power_clamp_chart_functionality

This commit is contained in:
mohammad
2024-10-23 16:38:40 +03:00
parent 91ba2bad78
commit 600ed7992d
9 changed files with 1095 additions and 485 deletions

View File

@ -171,6 +171,9 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
code: 'switch_1',
);
recordGroups = response;
emit(UpdateState(garageSensor: deviceStatus));
} on DioException catch (e) {
final errorData = e.response!.data;

View File

@ -1,6 +1,5 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
@ -18,12 +17,11 @@ class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
}) : super(const PowerClampState()) {
on<PowerClampInitial>(_fetchPowerClampInfo);
// on<ReportLogsInitial>(fetchLogsForLastMonth);
on<FetchEnergyData>(_mapReportToEnergyData);
on<SelectDateEvent>(selectTimeOfLinePassword);
// on<FetchEnergyData>(_mapReportToEnergyData);
on<SelectDateEvent>(checkDayMonthYearSelected);
on<FilterRecordsByDateEvent>(_filterRecordsByDate);
}
//SelectDateEvent
DateTime? dateTime = DateTime.now();
String formattedDate = DateFormat('yyyy/MM/dd').format(DateTime.now());
bool lowBattery = false;
bool closingReminder = false;
@ -59,26 +57,6 @@ class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
),
),
);
// void _fetchStatus(
// PowerClampInitial event, Emitter<PowerClampState> emit) async {
// emit(PowerClampLoadingState());
// try {
// var response = await DevicesAPI.getDeviceStatus(PCId);
// List<StatusModel> statusModelList = [];
// for (var status in response['status']) {
// statusModelList.add(StatusModel.fromJson(status));
// }
// deviceStatus = PowerClampModel.fromJson(
// statusModelList,
// );
// emit(UpdateState(powerClampModel: deviceStatus));
// Future.delayed(const Duration(milliseconds: 500));
// // _listenToChanges();
// } catch (e) {
// emit(PowerClampFailedState(errorMessage: e.toString()));
// return;
// }
// }
void _fetchPowerClampInfo(
PowerClampInitial event, Emitter<PowerClampState> emit) async {
@ -93,42 +71,564 @@ class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
}
}
//List<StatusModel> statusModelList = [];
// for (var status in response['status']) {
// statusModelList.add(StatusModel.fromJson(status));
// }
// deviceStatus = PowerClampModel.fromJson(
// statusModelList,
// );
DeviceReport recordGroups =
DeviceReport(startTime: '0', endTime: '0', data: []);
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<PowerClampState> emit) async {
DateTime now = DateTime.now();
EventDevice recordGroupsDateTime =
EventDevice(code: '', eventTime: DateTime.now(), value: '');
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
List<EventDevice> record = [
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2024-10-23 11:14:13'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-10-23 11:14:13'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-23 11:14:13'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-11 11:15:43'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-11 11:15:35'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-12 11:15:29'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-13 11:15:25'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-14 11:15:21'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-15 11:15:17'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-16 11:15:07'),
value: '2286'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-17 11:14:47'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-18 11:14:40'),
value: '2284'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-19 11:14:23'),
value: '2285'),
EventDevice(
code: 'VoltageA',
eventTime: DateTime.parse('2023-02-20 11:14:13'),
value: '2284'),
];
List<EventDevice> filteredRecords = [];
int startTime = lastMonth.millisecondsSinceEpoch;
int endTime = now.millisecondsSinceEpoch;
try {
emit(PowerClampLoadingState());
var response = await DevicesAPI.getReportLogs(
startTime: startTime.toString(),
endTime: endTime.toString(),
deviceUuid: PCId,
code: event.code!,
int currentIndex = 0;
final List<String> views = ['Day', 'Month', 'Year'];
Widget dateSwitcher() {
void switchView(int direction) {
currentIndex = (currentIndex + direction + views.length) % views.length;
}
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.arrow_left),
onPressed: () {
setState(() {
switchView(-1);
});
},
),
Text(
views[currentIndex],
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
),
IconButton(
icon: const Icon(Icons.arrow_right),
onPressed: () {
setState(() {
switchView(1);
});
},
),
],
);
recordGroups = response;
emit(UpdateState(powerClampModel: deviceStatus));
add(FetchEnergyData()); // Trigger mapping to EnergyData
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
},
);
}
void checkDayMonthYearSelected(
SelectDateEvent event, Emitter<PowerClampState> emit) async {
emit(PowerClampLoadingState());
if (currentIndex == 0) {
await dayMonthYearPicker(context: event.context).then(
(newDate) {
if (newDate != null) {
dateTime = newDate;
formattedDate = DateFormat('yyyy/MM/dd').format(dateTime!);
add(FilterRecordsByDateEvent(
selectedDate: dateTime!,
viewType: views[currentIndex],
));
}
},
);
} else if (currentIndex == 1) {
await selectMonthAndYear(event.context).then(
(newDate) {
if (newDate != null) {
dateTime = newDate;
formattedDate = DateFormat('yyyy-MM').format(dateTime!);
add(FilterRecordsByDateEvent(
selectedDate: dateTime!,
viewType: views[currentIndex],
));
}
},
);
} else if (currentIndex == 2) {
await selectYear(event.context).then(
(newDate) {
if (newDate != null) {
dateTime = newDate;
formattedDate = DateFormat('yyyy').format(dateTime!);
add(FilterRecordsByDateEvent(
selectedDate: dateTime!,
viewType: views[currentIndex],
));
}
},
);
}
emit(DateSelectedState());
}
Future<DateTime?> selectMonthAndYear(BuildContext context) async {
int selectedYear = DateTime.now().year;
int selectedMonth = DateTime.now().month;
FixedExtentScrollController yearController =
FixedExtentScrollController(initialItem: selectedYear - 1905);
FixedExtentScrollController monthController =
FixedExtentScrollController(initialItem: selectedMonth - 1);
return await showModalBottomSheet<DateTime>(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: 300,
child: Column(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Select Month and Year',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
const Divider(),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
Expanded(
child: ListWheelScrollView.useDelegate(
controller: yearController,
overAndUnderCenterOpacity: 0.2,
itemExtent: 50,
onSelectedItemChanged: (index) {
selectedYear = 1905 + index;
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
(1905 + index).toString(),
style: const TextStyle(fontSize: 18),
),
);
},
childCount: 200,
),
),
),
Expanded(
flex: 2,
child: ListWheelScrollView.useDelegate(
controller: monthController,
overAndUnderCenterOpacity: 0.2,
itemExtent: 50,
onSelectedItemChanged: (index) {
selectedMonth = index + 1;
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
DateFormat.MMMM()
.format(DateTime(0, index + 1)),
style: const TextStyle(fontSize: 18),
),
);
},
childCount: 12,
),
),
),
const Spacer(),
],
),
),
const Divider(),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('OK'),
onPressed: () {
final selectedDateTime =
DateTime(selectedYear, selectedMonth);
Navigator.of(context).pop(selectedDateTime);
},
),
],
),
),
],
),
);
},
);
}
Future<DateTime?> selectYear(BuildContext context) async {
int selectedYear = DateTime.now().year;
FixedExtentScrollController yearController =
FixedExtentScrollController(initialItem: selectedYear - 1905);
return await showModalBottomSheet<DateTime>(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: 300,
child: Column(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Select Year',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
const Divider(),
Expanded(
child: ListWheelScrollView.useDelegate(
controller: yearController,
overAndUnderCenterOpacity: 0.2,
itemExtent: 50,
onSelectedItemChanged: (index) {
selectedYear = 1905 + index;
},
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Center(
child: Text(
(1905 + index).toString(),
style: const TextStyle(fontSize: 18),
),
);
},
childCount: 200,
),
),
),
const Divider(),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context)
.pop(); // Pops without value, returning null
},
),
TextButton(
child: const Text('OK'),
onPressed: () {
final selectedDateTime = DateTime(selectedYear);
Navigator.of(context).pop(
selectedDateTime); // Pops with the selected date
},
),
],
),
),
],
),
);
},
);
}
Future<DateTime?> dayMonthYearPicker({
required BuildContext context,
}) async {
DateTime selectedDate = DateTime.now(); // Default selected date
return await showModalBottomSheet<DateTime>(
context: context,
builder: (BuildContext context) {
return SizedBox(
height: 350, // Increased height to accommodate the buttons
child: Column(
children: [
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
initialDateTime: DateTime.now(),
minimumYear: 1900,
maximumYear: DateTime.now().year,
onDateTimeChanged: (DateTime newDateTime) {
selectedDate =
newDateTime; // Update the selected date when changed
},
),
),
const Divider(),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context)
.pop(); // Dismiss the modal without returning a value
},
),
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context)
.pop(selectedDate); // Return the selected date
},
),
],
),
),
],
),
);
},
);
}
List<EnergyData> energyDataList = [];
void _filterRecordsByDate(
FilterRecordsByDateEvent event, Emitter<PowerClampState> emit) {
emit(PowerClampLoadingState());
if (event.viewType == 'Year') {
filteredRecords = record
.where((record) => record.eventTime!.year == event.selectedDate.year)
.toList();
} else if (event.viewType == 'Month') {
filteredRecords = record
.where((record) =>
record.eventTime!.year == event.selectedDate.year &&
record.eventTime!.month == event.selectedDate.month)
.toList();
} else if (event.viewType == 'Day') {
filteredRecords = record
.where((record) =>
record.eventTime!.year == event.selectedDate.year &&
record.eventTime!.month == event.selectedDate.month &&
record.eventTime!.day == event.selectedDate.day)
.toList();
}
String getMonthShortName(int month) {
final date = DateTime(0, month);
return DateFormat.MMM().format(date);
}
energyDataList = filteredRecords.map((eventDevice) {
return EnergyData(
event.viewType == 'Year'
? getMonthShortName(
int.tryParse(DateFormat('MM').format(eventDevice.eventTime!))!)
: event.viewType == 'Month'
? DateFormat('yyyy/MM/dd').format(eventDevice.eventTime!)
: DateFormat('HH:mm:ss').format(eventDevice.eventTime!),
double.parse(eventDevice.value!),
);
}).toList();
Future.delayed(const Duration(milliseconds: 500));
emit(FilterRecordsState(filteredRecords: energyDataList));
}
}
// Event for filtering records by date
// _listenToChanges() {
// try {
// DatabaseReference ref =
@ -158,102 +658,135 @@ class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
// }
// New Function: Convert the device report data into EnergyData and emit it.
void _mapReportToEnergyData(
FetchEnergyData event, Emitter<PowerClampState> emit) {
try {
List<EnergyData> energyDataList = recordGroups.data
?.map((event) {
if (event.code == "VoltageA" && event.eventTime != null) {
// Convert eventTime to readable format
DateTime eventDateTime =
DateTime.fromMillisecondsSinceEpoch(event.eventTime!);
String formattedTime =
"${eventDateTime.hour}:${eventDateTime.minute.toString().padLeft(2, '0')} ${eventDateTime.hour >= 12 ? 'PM' : 'AM'}";
double value = double.tryParse(event.value ?? "0") ?? 0;
return EnergyData(
formattedTime, value / 1000); // Assume kWh format
}
return null;
})
.where((data) => data != null)
.cast<EnergyData>()
.toList() ??
[];
// void _mapReportToEnergyData(
// FetchEnergyData event, Emitter<PowerClampState> emit) {
// try {
// List<EnergyData> energyDataList = recordGroups.data
// ?.map((event) {
// if (event.code == "VoltageA" && event.eventTime != null) {
// // Convert eventTime to readable format
// DateTime eventDateTime =
// DateTime.fromMillisecondsSinceEpoch(event.eventTime!);
// String formattedTime =
// "${eventDateTime.hour}:${eventDateTime.minute.toString().padLeft(2, '0')} ${eventDateTime.hour >= 12 ? 'PM' : 'AM'}";
// double value = double.tryParse(event.value ?? "0") ?? 0;
// return EnergyData(
// formattedTime, value / 1000); // Assume kWh format
// }
// return null;
// })
// .where((data) => data != null)
// .cast<EnergyData>()
// .toList() ??
// [];
emit(EnergyDataState(energyData: energyDataList));
} catch (e) {
emit(PowerClampFailedState(errorMessage: e.toString()));
}
}
// emit(EnergyDataState(energyData: energyDataList));
// } catch (e) {
// emit(PowerClampFailedState(errorMessage: e.toString()));
// }
// }
Future<void> selectTimeOfLinePassword(
SelectDateEvent event, Emitter<PowerClampState> emit) async {
emit(ChangeTimeState());
final DateTime? picked = await showDatePicker(
context: event.context,
initialDate: DateTime.now(),
firstDate: DateTime(1905),
lastDate: DateTime(2101),
);
if (picked != null) {
final selectedDateTime = DateTime(
picked.year,
picked.month,
picked.day,
0,
0,
);
final selectedTimestamp = DateTime(
selectedDateTime.year,
selectedDateTime.month,
selectedDateTime.day,
selectedDateTime.hour,
selectedDateTime.minute,
).millisecondsSinceEpoch ~/
1000;
// Future<void> selectTimeOfLinePassword(
// SelectDateEvent event, Emitter<PowerClampState> emit) async {
// emit(ChangeTimeState());
// final DateTime? picked = await showDatePicker(
// initialDatePickerMode: DatePickerMode.year,
// context: event.context,
// initialDate: DateTime.now(),
// firstDate: DateTime(1905),
// lastDate: DateTime(2101),
// );
// if (picked != null) {
// final selectedDateTime = DateTime(
// picked.year,
// picked.month,
// picked.day,
// 0,
// 0,
// );
// final selectedTimestamp = DateTime(
// selectedDateTime.year,
// selectedDateTime.month,
// selectedDateTime.day,
// selectedDateTime.hour,
// selectedDateTime.minute,
// ).millisecondsSinceEpoch ~/
// 1000;
DateTime dateTime = selectedDateTime;
formattedDate = DateFormat('yyyy/MM/dd').format(dateTime);
emit(DateSelectedState());
}
}
// DateTime dateTime = selectedDateTime;
// formattedDate = DateFormat('yyyy/MM/dd').format(dateTime);
// emit(DateSelectedState());
// }
// }
int currentIndex = 0;
final List<String> views = ['Day', 'Month', 'Year'];
// void _fetchStatus(
// PowerClampInitial event, Emitter<PowerClampState> emit) async {
// emit(PowerClampLoadingState());
// try {
// var response = await DevicesAPI.getDeviceStatus(PCId);
// List<StatusModel> statusModelList = [];
// for (var status in response['status']) {
// statusModelList.add(StatusModel.fromJson(status));
// }
// deviceStatus = PowerClampModel.fromJson(
// statusModelList,
// );
// emit(UpdateState(powerClampModel: deviceStatus));
// Future.delayed(const Duration(milliseconds: 500));
// // _listenToChanges();
// } catch (e) {
// emit(PowerClampFailedState(errorMessage: e.toString()));
// return;
// }
// }
Widget dateSwitcher() {
void switchView(int direction) {
currentIndex = (currentIndex + direction + views.length) % views.length;
}
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.arrow_left),
onPressed: () {
setState(() {
switchView(-1);
});
},
),
Text(
views[currentIndex],
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
),
IconButton(
icon: const Icon(Icons.arrow_right),
onPressed: () {
setState(() {
switchView(1);
});
},
),
],
);
},
);
}
}
// Future<void> fetchLogsForLastMonth(
// ReportLogsInitial event, Emitter<PowerClampState> emit) async {
// DateTime now = DateTime.now();
// DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
// int startTime = lastMonth.millisecondsSinceEpoch;
// int endTime = now.millisecondsSinceEpoch;
// try {
// emit(PowerClampLoadingState());
// var response = await DevicesAPI.getReportLogs(
// startTime: startTime.toString(),
// endTime: endTime.toString(),
// deviceUuid: PCId,
// code: event.code!,
// );
// recordGroups = response;
// record = recordGroups.data!.map((event) {
// return EventDevice(
// code: event.code,
// eventTime: event.eventTime != null
// ? DateTime.fromMillisecondsSinceEpoch(event.eventTime!)
// : null,
// value: event.value,
// );
// }).toList();
// for (var event in record) {
// print(
// 'Code: ${event.code}, Event Time: ${DateFormat('yyyy-MM-dd hh:mm:ss a').format(event.eventTime!)}, Value: ${event.value}');
// }
// emit(UpdateState(powerClampModel: deviceStatus));
// } on DioException catch (e) {
// final errorData = e.response!.data;
// String errorMessage = errorData['message'];
// }
// }
// int transformTimestamp(int originalTime) {
// DateTime originalDateTime =
// DateTime.fromMillisecondsSinceEpoch(originalTime);
// DateTime transformedDateTime = originalDateTime.add(Duration(hours: 1));
// return transformedDateTime.millisecondsSinceEpoch;
// }
// void addDataToRecord(List<Map<String, dynamic>> rawData) {
// for (var dataPoint in rawData) {
// EventDevice event = EventDevice.fromJson(dataPoint);
// record.add(event);
// }
// }

View File

@ -107,3 +107,13 @@ class TickTimer extends PowerClampEvent {
class StopTimer extends PowerClampEvent {}
class OnClose extends PowerClampEvent {}
class FilterRecordsByDateEvent extends PowerClampEvent {
final DateTime selectedDate;
final String viewType; // 'Day', 'Month', 'Year'
FilterRecordsByDateEvent(
{required this.selectedDate, required this.viewType});
}

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
@ -12,7 +13,9 @@ class PowerClampState extends Equatable {
class PowerClampInitialState extends PowerClampState {}
class PowerClampLoadingState extends PowerClampState {}
class ChangeTimeState extends PowerClampState {}
class DateSelectedState extends PowerClampState {}
//DateSelectedState
@ -46,3 +49,10 @@ class EnergyDataState extends PowerClampState {
const EnergyDataState({required this.energyData});
}
// State for filtered records
class FilterRecordsState extends PowerClampState {
final List<EnergyData> filteredRecords;
FilterRecordsState({required this.filteredRecords});
}

View File

@ -27,6 +27,33 @@ class DeviceReport {
};
}
class EventDevice {
final String? code;
final DateTime? eventTime;
final String? value;
EventDevice({
this.code,
this.eventTime,
this.value,
});
EventDevice.fromJson(Map<String, dynamic> json)
: code = json['code'] as String?,
eventTime = json['eventTime'] ,
value = json['value'] as String?;
Map<String, dynamic> toJson() => {
'code': code,
'eventTime': eventTime,
'value': value,
};
}
class DeviceEvent {
final String? code;
final int? eventTime;

View File

@ -18,6 +18,7 @@ class PowerClampCard extends StatelessWidget {
final String? totalVoltage;
final String? totalActive;
final String? totalFrequency;
final String? dateTimeSelected;
final String? totalFactor;
final Widget? dateSwitcher;
final String? formattedDate;
@ -32,6 +33,7 @@ class PowerClampCard extends StatelessWidget {
this.title,
this.totalCurrent,
this.totalActiveGeneral,
this.dateTimeSelected,
this.totalCurrentGeneral,
this.totalFrequencyGeneral,
this.totalVoltage,
@ -80,7 +82,7 @@ class PowerClampCard extends StatelessWidget {
],
),
const SizedBox(
height: 20,
height: 10,
),
isGeneral == true
? Row(
@ -144,28 +146,25 @@ class PowerClampCard extends StatelessWidget {
)
],
),
const SizedBox(
height: 10,
),
const Row(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodyMedium(
const BodyMedium(
text: 'Total consumption',
fontSize: 12,
fontWeight: FontWeight.w700,
),
Text(
'10/08/2024',
style:
TextStyle(fontSize: 8, fontWeight: FontWeight.w400),
dateTimeSelected !,
style: const TextStyle(
fontSize: 8, fontWeight: FontWeight.w400),
),
],
),
Row(
const Row(
children: [
BodyMedium(
text: '1000.00 ',
@ -179,8 +178,8 @@ class PowerClampCard extends StatelessWidget {
),
],
),
SizedBox(
height: 290,
Expanded(
child: SizedBox(
child: EnergyConsumptionPage(
chartData: chartData!.isNotEmpty
? chartData!
@ -198,11 +197,12 @@ class PowerClampCard extends StatelessWidget {
EnergyData('10:00 AM', 3.9),
EnergyData('11:00 AM', 4.0),
],
totalConsumption:
chartData!.fold(0, (sum, data) => sum + data.consumption),
totalConsumption: chartData!
.fold(0, (sum, data) => sum + data.consumption),
date: '10/08/2024',
),
),
),
const SizedBox(
height: 5,
),

View File

@ -24,11 +24,12 @@ class _PowerClampPageState extends State<PowerClampPage> {
final PageController _pageController = PageController();
int _currentPage = 0;
static const int _pageCount = 4;
late PowerClampModel model;
@override
void initState() {
super.initState();
_pageController.addListener(_handlePageChange);
model = _initialPowerClampModel();
}
void _handlePageChange() {
@ -54,16 +55,18 @@ class _PowerClampPageState extends State<PowerClampPage> {
child: BlocProvider(
create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
..add(const PowerClampInitial()),
// ..add(const ReportLogsInitial(code: 'VoltageA')),
child: BlocBuilder<PowerClampBloc, PowerClampState>(
builder: (context, state) {
final blocProvider = context.read<PowerClampBloc>();
PowerClampModel model = _initialPowerClampModel();
List<EnergyData> chartData = [];
if (state is UpdateState) {
model = state.powerClampModel;
} else if (state is EnergyDataState) {
chartData = state.energyData;
} else if (state is FilterRecordsState) {
chartData = state.filteredRecords;
}
if (state is PowerClampLoadingState) {
@ -83,11 +86,33 @@ class _PowerClampPageState extends State<PowerClampPage> {
onRefresh: () async {
blocProvider.add(const PowerClampInitial());
},
child: PageView(
controller: _pageController,
children:
_buildPowerClampCards(model, chartData, blocProvider),
child: PageView(controller: _pageController, children: [
_buildPowerClampCard(
title: 'Total Energy \nConsumption',
phase: model.status.general,
isGeneral: true,
chartData: chartData,
blocProvider: blocProvider,
),
_buildPowerClampCard(
title: 'Phase A Energy \nConsumption',
phase: model.status.phaseA,
chartData: chartData,
blocProvider: blocProvider,
),
_buildPowerClampCard(
title: 'Phase B Energy \nConsumption',
phase: model.status.phaseB,
chartData: chartData,
blocProvider: blocProvider,
),
_buildPowerClampCard(
title: 'Phase C Energy \nConsumption',
phase: model.status.phaseC,
chartData: chartData,
blocProvider: blocProvider,
),
]),
),
),
_buildPageIndicator(),
@ -164,6 +189,7 @@ class _PowerClampPageState extends State<PowerClampPage> {
required PowerClampBloc blocProvider,
}) {
return PowerClampCard(
dateTimeSelected:blocProvider.formattedDate,
energyConsumption: _getValueOrNA(phase.dataPoints, isGeneral ? 0 : 5),
title: title,
isGeneral: isGeneral,

View File

@ -1,312 +1,312 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_event.dart';
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_card.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_bloc.dart';
// import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_event.dart';
// import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_state.dart';
// import 'package:syncrow_app/features/devices/model/device_model.dart';
// import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
// import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
// import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_card.dart';
// import 'package:syncrow_app/features/shared_widgets/default_container.dart';
// import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
// import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class PowerClampTestPage extends StatefulWidget {
late final DeviceModel? device;
// class PowerClampTestPage extends StatefulWidget {
// late final DeviceModel? device;
PowerClampTestPage({super.key, this.device});
// PowerClampTestPage({super.key, this.device});
@override
_PowerClampTestPageState createState() => _PowerClampTestPageState();
}
// @override
// _PowerClampTestPageState createState() => _PowerClampTestPageState();
// }
class _PowerClampTestPageState extends State<PowerClampTestPage> {
final PageController _pageController = PageController();
int _currentPage = 0;
final int _pageCount = 4;
@override
void initState() {
super.initState();
_pageController.addListener(() {
int nextPage = _pageController.page?.round() ?? 0;
if (_currentPage != nextPage) {
setState(() {
_currentPage = nextPage;
});
}
});
}
// class _PowerClampTestPageState extends State<PowerClampTestPage> {
// final PageController _pageController = PageController();
// int _currentPage = 0;
// final int _pageCount = 4;
// @override
// void initState() {
// super.initState();
// _pageController.addListener(() {
// int nextPage = _pageController.page?.round() ?? 0;
// if (_currentPage != nextPage) {
// setState(() {
// _currentPage = nextPage;
// });
// }
// });
// }
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
// @override
// void dispose() {
// _pageController.dispose();
// super.dispose();
// }
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Power Clamp',
child: BlocProvider(
create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
..add(const PowerClampInitial()),
child: BlocBuilder<PowerClampBloc, PowerClampState>(
builder: (context, state) {
final _blocProvider = BlocProvider.of<PowerClampBloc>(context);
PowerClampModel model = PowerClampModel(
productType: '',
productUuid: '',
status: PowerStatus(
phaseA: Phase(
dataPoints: [
DataPoint(
code: '',
customName: '',
dpId: 0,
time: 0,
type: '',
value: 0),
],
),
phaseB: Phase(
dataPoints: [
DataPoint(
code: '',
customName: '',
dpId: 0,
time: 0,
type: '',
value: 0),
],
),
phaseC: Phase(
dataPoints: [
DataPoint(
code: '',
customName: '',
dpId: 0,
time: 0,
type: '',
value: 0),
],
),
general: Phase(
dataPoints: [
DataPoint(
code: '',
customName: '',
dpId: 0,
time: 0,
type: '',
value: 0),
],
),
),
);
List<EnergyData> chartData = [];
// @override
// Widget build(BuildContext context) {
// return DefaultScaffold(
// title: 'Power Clamp',
// child: BlocProvider(
// create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
// ..add(const PowerClampInitial()),
// child: BlocBuilder<PowerClampBloc, PowerClampState>(
// builder: (context, state) {
// final _blocProvider = BlocProvider.of<PowerClampBloc>(context);
// PowerClampModel model = PowerClampModel(
// productType: '',
// productUuid: '',
// status: PowerStatus(
// phaseA: Phase(
// dataPoints: [
// DataPoint(
// code: '',
// customName: '',
// dpId: 0,
// time: 0,
// type: '',
// value: 0),
// ],
// ),
// phaseB: Phase(
// dataPoints: [
// DataPoint(
// code: '',
// customName: '',
// dpId: 0,
// time: 0,
// type: '',
// value: 0),
// ],
// ),
// phaseC: Phase(
// dataPoints: [
// DataPoint(
// code: '',
// customName: '',
// dpId: 0,
// time: 0,
// type: '',
// value: 0),
// ],
// ),
// general: Phase(
// dataPoints: [
// DataPoint(
// code: '',
// customName: '',
// dpId: 0,
// time: 0,
// type: '',
// value: 0),
// ],
// ),
// ),
// );
// List<EnergyData> chartData = [];
if (state is UpdateState) {
model = state.powerClampModel;
} else if (state is EnergyDataState) {
chartData = state.energyData;
}
return state is PowerClampLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: Column(
children: [
Flexible(
child: RefreshIndicator(
onRefresh: () async {
_blocProvider.add(const PowerClampInitial());
},
child: PageView(
controller: _pageController,
children: [
PowerClampCard(
energyConsumption:
model.status.general.dataPoints.length > 0
? model.status.general.dataPoints[0].value
.toString()
: 'N/A',
title: 'Total Energy \nConsumption',
isGeneral: true,
dateSwitcher: _blocProvider.dateSwitcher(),
formattedDate: _blocProvider.formattedDate,
selectDateEvent: () {
_blocProvider.add(
SelectDateEvent(context: context));
},
totalFrequencyGeneral:
model.status.general.dataPoints.length > 4
? model.status.general.dataPoints[4].value
.toString()
: 'N/A',
totalActiveGeneral:
model.status.general.dataPoints.length > 2
? model.status.general.dataPoints[2].value
.toString()
: 'N/A',
totalCurrentGeneral:
model.status.general.dataPoints.length > 1
? model.status.general.dataPoints[1].value
.toString()
: 'N/A',
totalVoltage:
model.status.general.dataPoints.length > 0
? model.status.general.dataPoints[0].value.toString()
: 'N/A',
chartData: chartData,
context: context),
// if (state is UpdateState) {
// model = state.powerClampModel;
// } else if (state is EnergyDataState) {
// chartData = state.energyData;
// }
// return state is PowerClampLoadingState
// ? const Center(
// child: DefaultContainer(
// width: 50,
// height: 50,
// child: CircularProgressIndicator()),
// )
// : Column(
// children: [
// Flexible(
// child: RefreshIndicator(
// onRefresh: () async {
// _blocProvider.add(const PowerClampInitial());
// },
// child: PageView(
// controller: _pageController,
// children: [
// PowerClampCard(
// energyConsumption:
// model.status.general.dataPoints.length > 0
// ? model.status.general.dataPoints[0].value
// .toString()
// : 'N/A',
// title: 'Total Energy \nConsumption',
// isGeneral: true,
// dateSwitcher: Container(),
// formattedDate: _blocProvider.formattedDate,
// selectDateEvent: () {
// _blocProvider.add(
// SelectDateEvent(context: context));
// },
// totalFrequencyGeneral:
// model.status.general.dataPoints.length > 4
// ? model.status.general.dataPoints[4].value
// .toString()
// : 'N/A',
// totalActiveGeneral:
// model.status.general.dataPoints.length > 2
// ? model.status.general.dataPoints[2].value
// .toString()
// : 'N/A',
// totalCurrentGeneral:
// model.status.general.dataPoints.length > 1
// ? model.status.general.dataPoints[1].value
// .toString()
// : 'N/A',
// totalVoltage:
// model.status.general.dataPoints.length > 0
// ? model.status.general.dataPoints[0].value.toString()
// : 'N/A',
// chartData: chartData,
// context: context),
PowerClampCard(
energyConsumption:
model.status.phaseA.dataPoints.length > 5
? model.status.phaseA.dataPoints[5].value
.toString()
: 'N/A',
title: 'Phase A Energy \nConsumption',
dateSwitcher: _blocProvider.dateSwitcher(),
formattedDate: _blocProvider.formattedDate,
selectDateEvent: () {
_blocProvider.add(
SelectDateEvent(context: context));
},
totalFactor: model.status.phaseA.dataPoints.length > 3
? model.status.phaseA.dataPoints[3].value
.toString()
: 'N/A',
totalActive: model.status.phaseA.dataPoints.length > 2
? model.status.phaseA.dataPoints[2].value
.toString()
: 'N/A',
totalCurrent:
model.status.phaseA.dataPoints.length > 1
? model.status.phaseA.dataPoints[1]
.value
.toString()
: 'N/A',
totalVoltage:
model.status.phaseA.dataPoints.length > 0
? model.status.phaseA.dataPoints[0]
.value
.toString()
: 'N/A',
chartData: chartData,
context: context),
// PowerClampCard(
// energyConsumption:
// model.status.phaseA.dataPoints.length > 5
// ? model.status.phaseA.dataPoints[5].value
// .toString()
// : 'N/A',
// title: 'Phase A Energy \nConsumption',
// dateSwitcher: _blocProvider.dateSwitcher(),
// formattedDate: _blocProvider.formattedDate,
// selectDateEvent: () {
// _blocProvider.add(
// SelectDateEvent(context: context));
// },
// totalFactor: model.status.phaseA.dataPoints.length > 3
// ? model.status.phaseA.dataPoints[3].value
// .toString()
// : 'N/A',
// totalActive: model.status.phaseA.dataPoints.length > 2
// ? model.status.phaseA.dataPoints[2].value
// .toString()
// : 'N/A',
// totalCurrent:
// model.status.phaseA.dataPoints.length > 1
// ? model.status.phaseA.dataPoints[1]
// .value
// .toString()
// : 'N/A',
// totalVoltage:
// model.status.phaseA.dataPoints.length > 0
// ? model.status.phaseA.dataPoints[0]
// .value
// .toString()
// : 'N/A',
// chartData: chartData,
// context: context),
PowerClampCard(
energyConsumption:
model.status.phaseB.dataPoints.length > 5
? model.status.phaseB.dataPoints[5].value
.toString()
: 'N/A',
title: 'Phase B Energy \nConsumption',
dateSwitcher: _blocProvider.dateSwitcher(),
formattedDate: _blocProvider.formattedDate,
selectDateEvent: () {
_blocProvider.add(
SelectDateEvent(context: context));
},
totalFactor: model.status.phaseA.dataPoints.length > 3
? model.status.phaseB.dataPoints[3].value
.toString()
: 'N/A',
totalActive: model.status.phaseB.dataPoints.length > 2
? model.status.phaseB.dataPoints[2].value
.toString()
: 'N/A',
totalCurrent:
model.status.phaseB.dataPoints.length > 1
? model.status.phaseB.dataPoints[1]
.value
.toString()
: 'N/A',
totalVoltage:
model.status.phaseB.dataPoints.length > 0
? model.status.phaseB.dataPoints[0]
.value
.toString()
: 'N/A',
chartData: chartData,
context: context),
// PowerClampCard(
// energyConsumption:
// model.status.phaseB.dataPoints.length > 5
// ? model.status.phaseB.dataPoints[5].value
// .toString()
// : 'N/A',
// title: 'Phase B Energy \nConsumption',
// dateSwitcher: _blocProvider.dateSwitcher(),
// formattedDate: _blocProvider.formattedDate,
// selectDateEvent: () {
// _blocProvider.add(
// SelectDateEvent(context: context));
// },
// totalFactor: model.status.phaseA.dataPoints.length > 3
// ? model.status.phaseB.dataPoints[3].value
// .toString()
// : 'N/A',
// totalActive: model.status.phaseB.dataPoints.length > 2
// ? model.status.phaseB.dataPoints[2].value
// .toString()
// : 'N/A',
// totalCurrent:
// model.status.phaseB.dataPoints.length > 1
// ? model.status.phaseB.dataPoints[1]
// .value
// .toString()
// : 'N/A',
// totalVoltage:
// model.status.phaseB.dataPoints.length > 0
// ? model.status.phaseB.dataPoints[0]
// .value
// .toString()
// : 'N/A',
// chartData: chartData,
// context: context),
PowerClampCard(
energyConsumption:
model.status.phaseC.dataPoints.length > 5
? model.status.phaseC.dataPoints[5].value
.toString()
: 'N/A',
title: 'Phase A Energy \nConsumption',
dateSwitcher: _blocProvider.dateSwitcher(),
formattedDate: _blocProvider.formattedDate,
selectDateEvent: () {
_blocProvider.add(
SelectDateEvent(context: context));
},
totalFactor: model.status.phaseC.dataPoints.length > 3
? model.status.phaseC.dataPoints[3].value
.toString()
: 'N/A',
totalActive: model.status.phaseC.dataPoints.length > 2
? model.status.phaseC.dataPoints[2].value
.toString()
: 'N/A',
totalCurrent:
model.status.phaseC.dataPoints.length > 1
? model.status.phaseC.dataPoints[1]
.value
.toString()
: 'N/A',
totalVoltage:
model.status.phaseC.dataPoints.length > 0
? model.status.phaseC.dataPoints[0]
.value
.toString()
: 'N/A',
chartData: chartData,
context: context),
// PowerClampCard(
// energyConsumption:
// model.status.phaseC.dataPoints.length > 5
// ? model.status.phaseC.dataPoints[5].value
// .toString()
// : 'N/A',
// title: 'Phase A Energy \nConsumption',
// dateSwitcher: _blocProvider.dateSwitcher(),
// formattedDate: _blocProvider.formattedDate,
// selectDateEvent: () {
// _blocProvider.add(
// SelectDateEvent(context: context));
// },
// totalFactor: model.status.phaseC.dataPoints.length > 3
// ? model.status.phaseC.dataPoints[3].value
// .toString()
// : 'N/A',
// totalActive: model.status.phaseC.dataPoints.length > 2
// ? model.status.phaseC.dataPoints[2].value
// .toString()
// : 'N/A',
// totalCurrent:
// model.status.phaseC.dataPoints.length > 1
// ? model.status.phaseC.dataPoints[1]
// .value
// .toString()
// : 'N/A',
// totalVoltage:
// model.status.phaseC.dataPoints.length > 0
// ? model.status.phaseC.dataPoints[0]
// .value
// .toString()
// : 'N/A',
// chartData: chartData,
// context: context),
]),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(_pageCount, (index) {
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
margin:
const EdgeInsets.symmetric(horizontal: 4.0),
height: 10.0,
width: _currentPage == index
? 10.0
: 10.0, // Change width for current page
decoration: BoxDecoration(
color: _currentPage == index
? Colors
.grey // Use a different color for the active indicator
: ColorsManager.greyColor,
borderRadius: BorderRadius.circular(5.0),
),
);
}),
),
),
],
);
},
),
),
);
}
}
// ]),
// ),
// ),
// Padding(
// padding: const EdgeInsets.symmetric(vertical: 10.0),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: List.generate(_pageCount, (index) {
// return AnimatedContainer(
// duration: const Duration(milliseconds: 300),
// margin:
// const EdgeInsets.symmetric(horizontal: 4.0),
// height: 10.0,
// width: _currentPage == index
// ? 10.0
// : 10.0, // Change width for current page
// decoration: BoxDecoration(
// color: _currentPage == index
// ? Colors
// .grey // Use a different color for the active indicator
// : ColorsManager.greyColor,
// borderRadius: BorderRadius.circular(5.0),
// ),
// );
// }),
// ),
// ),
// ],
// );
// },
// ),
// ),
// );
// }
// }

View File

@ -383,6 +383,7 @@ class DevicesAPI {
.replaceAll('{startTime}', startTime)
.replaceAll('{endTime}', endTime),
expectedResponseModel: (json) {
log('json=====$json');
return DeviceReport.fromJson(json);
},
);