power_clamp_functionality

This commit is contained in:
mohammad
2024-10-24 15:03:19 +03:00
parent e01ed33b17
commit 9b4e687e9a
6 changed files with 981 additions and 273 deletions

View File

@ -1,28 +1,218 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_event.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_event.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_state.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/bloc/smart_power_state.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/models/device_event.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/view/power_chart.dart';
import 'package:syncrow_web/services/devices_mang_api.dart'; import 'package:syncrow_web/services/devices_mang_api.dart';
class SmartPowerBloc extends Bloc<SmartPowerEvent, SmartPowerState> { class SmartPowerBloc extends Bloc<SmartPowerEvent, SmartPowerState> {
SmartPowerBloc({required this.deviceId}) : super(SmartPowerInitial()) { SmartPowerBloc({required this.deviceId}) : super(SmartPowerInitial()) {
on<SmartPowerFetchDeviceEvent>(_onFetchDeviceStatus); on<SmartPowerFetchDeviceEvent>(_onFetchDeviceStatus);
// on<SmartPowerControl>(_onControl); on<SmartPowerArrowPressedEvent>(_onArrowPressed);
on<SmartPowerFetchBatchEvent>(_onFetchBatchStatus); on<SmartPowerFetchBatchEvent>(_onFetchBatchStatus);
on<SmartPowerPageChangedEvent>(_onPageChanged);
on<SmartPowerBatchControl>(_onBatchControl); on<SmartPowerBatchControl>(_onBatchControl);
// on<WallLightFactoryReset>(_onFactoryReset); on<FilterRecordsByDateEvent>(_filterRecordsByDate);
on<SelectDateEvent>(checkDayMonthYearSelected);
// SelectDateEvent
} }
late PowerClampModel deviceStatus; late PowerClampModel deviceStatus;
final String deviceId; final String deviceId;
Timer? _timer; Timer? _timer;
List<Map<String, dynamic>> phaseData = []; List<Map<String, dynamic>> phaseData = [];
int currentPage = 0;
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'),
];
FutureOr<void> _onFetchDeviceStatus( FutureOr<void> _onFetchDeviceStatus(
SmartPowerFetchDeviceEvent event, Emitter<SmartPowerState> emit) async { SmartPowerFetchDeviceEvent event, Emitter<SmartPowerState> emit) async {
emit(SmartPowerLoading()); emit(SmartPowerLoading());
try { try {
var status = await DevicesManagementApi().getPowerClampInfo(event.deviceId); var status =
await DevicesManagementApi().getPowerClampInfo(event.deviceId);
deviceStatus = PowerClampModel.fromJson(status); deviceStatus = PowerClampModel.fromJson(status);
phaseData = [ phaseData = [
@ -48,21 +238,30 @@ class SmartPowerBloc extends Bloc<SmartPowerEvent, SmartPowerState> {
'powerFactor': '${deviceStatus.status.phaseC.dataPoints[3].value}', 'powerFactor': '${deviceStatus.status.phaseC.dataPoints[3].value}',
}, },
]; ];
emit(SmartPowerStatusLoaded(deviceStatus)); emit(SmartPowerStatusLoaded(deviceStatus, currentPage));
} catch (e) { } catch (e) {
emit(SmartPowerError(e.toString())); emit(SmartPowerError(e.toString()));
} }
} }
FutureOr<void> _onArrowPressed(
SmartPowerArrowPressedEvent event, Emitter<SmartPowerState> emit) {
currentPage = (currentPage + event.direction + 4) % 4;
emit(SmartPowerStatusLoaded(deviceStatus, currentPage));
}
FutureOr<void> _onPageChanged(
SmartPowerPageChangedEvent event, Emitter<SmartPowerState> emit) {
currentPage = event.page;
emit(SmartPowerStatusLoaded(deviceStatus, currentPage));
}
Future<void> _onFetchBatchStatus( Future<void> _onFetchBatchStatus(
SmartPowerFetchBatchEvent event, Emitter<SmartPowerState> emit) async { SmartPowerFetchBatchEvent event, Emitter<SmartPowerState> emit) async {
emit(SmartPowerLoading()); emit(SmartPowerLoading());
try { try {
await DevicesManagementApi().getBatchStatus(event.devicesIds);
await DevicesManagementApi().getBatchStatus(event.devicesIds); emit(SmartPowerStatusLoaded(deviceStatus, currentPage));
// deviceStatus =
// SmartPowerStatusModel.fromJson(event.devicesIds.first, status.status);
emit(SmartPowerStatusLoaded(deviceStatus));
} catch (e) { } catch (e) {
emit(SmartPowerError(e.toString())); emit(SmartPowerError(e.toString()));
} }
@ -76,30 +275,408 @@ class SmartPowerBloc extends Bloc<SmartPowerEvent, SmartPowerState> {
FutureOr<void> _onBatchControl( FutureOr<void> _onBatchControl(
SmartPowerBatchControl event, Emitter<SmartPowerState> emit) async { SmartPowerBatchControl event, Emitter<SmartPowerState> emit) async {
// final oldValue = _getValueByCode(event.code); emit(SmartPowerStatusLoaded(deviceStatus, currentPage));
// _updateLocalValue(event.code, event.value);
emit(SmartPowerStatusLoaded(deviceStatus));
FutureOr<void> _onFactoryReset(
WallLightFactoryReset event, Emitter<SmartPowerState> emit) async {
emit(SmartPowerLoading());
try {
final response = await DevicesManagementApi().factoryReset(
event.factoryReset,
event.deviceId,
);
if (!response) {
emit(SmartPowerError('Failed'));
} else {
emit(SmartPowerStatusLoaded(deviceStatus));
}
} catch (e) {
emit(SmartPowerError(e.toString()));
}
}
} }
List<EventDevice> filteredRecords = [];
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(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
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);
});
},
),
],
);
},
);
}
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 showDialog<DateTime>(
context: context,
builder: (BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.white,
height: 350,
width: 350,
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 showDialog<DateTime>(
context: context,
builder: (BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.white,
height: 350,
width: 350,
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 showDialog<DateTime>(
context: context,
builder: (BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.white,
height: 350,
width: 350,
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
},
),
],
),
),
],
),
),
],
);
},
);
}
DateTime? dateTime = DateTime.now();
String formattedDate = DateFormat('yyyy/MM/dd').format(DateTime.now());
void checkDayMonthYearSelected(
SelectDateEvent event, Emitter<SmartPowerState> emit) async {
// emit(SmartPowerLoading());
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());
}
List<EnergyData> energyDataList = [];
void _filterRecordsByDate(
FilterRecordsByDateEvent event, Emitter<SmartPowerState> emit) {
print('dddddddddddddddddddd');
// emit(SmartPowerLoading());
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(SmartPowerStatusLoaded(deviceStatus, currentPage));
emit(FilterRecordsState(filteredRecords: energyDataList));
}
} }

View File

@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart';
class SmartPowerEvent extends Equatable { class SmartPowerEvent extends Equatable {
@ -57,6 +58,7 @@ class WallLightFactoryReset extends SmartPowerEvent {
@override @override
List<Object> get props => [deviceId, factoryReset]; List<Object> get props => [deviceId, factoryReset];
} }
class PageChangedEvent extends SmartPowerEvent { class PageChangedEvent extends SmartPowerEvent {
final int newPage; final int newPage;
PageChangedEvent(this.newPage); PageChangedEvent(this.newPage);
@ -66,3 +68,26 @@ class PageArrowPressedEvent extends SmartPowerEvent {
final int direction; final int direction;
PageArrowPressedEvent(this.direction); PageArrowPressedEvent(this.direction);
} }
class SmartPowerArrowPressedEvent extends SmartPowerEvent {
final int direction;
SmartPowerArrowPressedEvent(this.direction);
}
class SmartPowerPageChangedEvent extends SmartPowerEvent {
final int page;
SmartPowerPageChangedEvent(this.page);
}
class SelectDateEvent extends SmartPowerEvent {
BuildContext context;
SelectDateEvent({required this.context});
}
class FilterRecordsByDateEvent extends SmartPowerEvent {
final DateTime selectedDate;
final String viewType; // 'Day', 'Month', 'Year'
FilterRecordsByDateEvent(
{required this.selectedDate, required this.viewType});
}

View File

@ -1,5 +1,6 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart';
import 'package:syncrow_web/pages/device_managment/power_clamp/view/power_chart.dart';
class SmartPowerState extends Equatable { class SmartPowerState extends Equatable {
@override @override
@ -9,16 +10,15 @@ class SmartPowerState extends Equatable {
class SmartPowerInitial extends SmartPowerState {} class SmartPowerInitial extends SmartPowerState {}
class SmartPowerLoading extends SmartPowerState {} class SmartPowerLoading extends SmartPowerState {}
class DateSelectedState extends SmartPowerState {}
class SmartPowerStatusLoaded extends SmartPowerState { class SmartPowerStatusLoaded extends SmartPowerState {
final PowerClampModel status; final PowerClampModel deviceStatus;
final int currentPage;
SmartPowerStatusLoaded(this.status); SmartPowerStatusLoaded(this.deviceStatus, this.currentPage);
@override
List<Object> get props => [status];
} }
class SmartPowerError extends SmartPowerState { class SmartPowerError extends SmartPowerState {
final String message; final String message;
@ -55,3 +55,8 @@ class SmartPowerBatchStatusLoaded extends SmartPowerState {
List<Object> get props => [status]; List<Object> get props => [status];
} }
class FilterRecordsState extends SmartPowerState {
final List<EnergyData> filteredRecords;
FilterRecordsState({required this.filteredRecords});
}

View File

@ -0,0 +1,23 @@
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,
};
}

View File

@ -6,11 +6,17 @@ class EnergyConsumptionPage extends StatefulWidget {
final List<dynamic> chartData; final List<dynamic> chartData;
final double totalConsumption; final double totalConsumption;
final String date; final String date;
final String formattedDate;
final Widget widget;
final Function()? onTap;
EnergyConsumptionPage({ EnergyConsumptionPage({
required this.chartData, required this.chartData,
required this.totalConsumption, required this.totalConsumption,
required this.date, required this.date,
required this.widget,
required this.onTap,
required this.formattedDate,
}); });
@override @override
@ -85,135 +91,186 @@ class _EnergyConsumptionPageState extends State<EnergyConsumptionPage> {
], ],
), ),
Expanded( Expanded(
child: Padding( child: Column(
padding: const EdgeInsets.only(top: 15), children: [
child: LineChart( Expanded(
LineChartData( child: Padding(
lineTouchData: LineTouchData( padding: const EdgeInsets.only(top: 15),
handleBuiltInTouches: true, child: LineChart(
touchSpotThreshold: 2, LineChartData(
getTouchLineEnd: (barData, spotIndex) { lineTouchData: LineTouchData(
return 10.0; handleBuiltInTouches: true,
}, touchSpotThreshold: 2,
touchTooltipData: LineTouchTooltipData( getTouchLineEnd: (barData, spotIndex) {
getTooltipColor: (touchTooltipItem) => Colors.white, return 10.0;
tooltipRoundedRadius: 10.0, },
tooltipPadding: const EdgeInsets.all(8.0), touchTooltipData: LineTouchTooltipData(
tooltipBorder: BorderSide(color: Colors.grey, width: 1), getTooltipColor: (touchTooltipItem) =>
getTooltipItems: (List<LineBarSpot> touchedSpots) { Colors.white,
return touchedSpots.map((spot) { tooltipRoundedRadius: 10.0,
return LineTooltipItem( tooltipPadding: const EdgeInsets.all(8.0),
'${spot.x},\n ${spot.y.toStringAsFixed(2)} kWh', tooltipBorder:
const TextStyle( BorderSide(color: Colors.grey, width: 1),
color: Colors.blue, getTooltipItems:
fontWeight: FontWeight.bold, (List<LineBarSpot> touchedSpots) {
fontSize: 12, return touchedSpots.map((spot) {
), return LineTooltipItem(
'${spot.x},\n ${spot.y.toStringAsFixed(2)} kWh',
const TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontSize: 12,
),
);
}).toList();
},
)),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
),
),
leftTitles: const AxisTitles(
sideTitles: SideTitles(
showTitles: false,
),
),
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
),
),
topTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
reservedSize: 70,
getTitlesWidget: (value, meta) {
int index = value.toInt();
if (index >= 0 && index < _chartData.length) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: RotatedBox(
quarterTurns: -1,
child: Text(_chartData[index].time,
style: TextStyle(fontSize: 10)),
),
);
}
return const SizedBox.shrink();
},
),
),
),
gridData: FlGridData(
show: true,
drawVerticalLine: true,
horizontalInterval: 1,
verticalInterval: 1,
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(0.2),
dashArray: [8, 8],
strokeWidth: 1,
); );
}).toList(); },
}, getDrawingHorizontalLine: (value) {
)), return FlLine(
titlesData: FlTitlesData( color: Colors.grey.withOpacity(0.2),
bottomTitles: AxisTitles( dashArray: [5, 5],
sideTitles: SideTitles( strokeWidth: 1,
showTitles: false,
),
),
leftTitles: const AxisTitles(
sideTitles: SideTitles(
showTitles: false,
),
),
rightTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
),
),
topTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
reservedSize: 70,
getTitlesWidget: (value, meta) {
int index = value.toInt();
if (index >= 0 && index < _chartData.length) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: RotatedBox(
quarterTurns: -1,
child: Text(_chartData[index].time,
style: TextStyle(fontSize: 10)),
),
); );
} },
return const SizedBox.shrink(); drawHorizontalLine: false,
}, ),
), lineBarsData: [
), LineChartBarData(
), preventCurveOvershootingThreshold: 0.1,
gridData: FlGridData( curveSmoothness: 0.5,
show: true, preventCurveOverShooting: true,
drawVerticalLine: true, aboveBarData: BarAreaData(),
horizontalInterval: 1, spots: _chartData
verticalInterval: 1, .asMap()
getDrawingVerticalLine: (value) { .entries
return FlLine( .map((entry) => FlSpot(entry.key.toDouble(),
color: Colors.grey.withOpacity(0.2), entry.value.consumption))
dashArray: [8, 8], .toList(),
strokeWidth: 1, isCurved: true,
); color: ColorsManager.primaryColor.withOpacity(0.6),
}, show: true,
getDrawingHorizontalLine: (value) { shadow: Shadow(color: Colors.black12),
return FlLine( belowBarData: BarAreaData(
color: Colors.grey.withOpacity(0.2), show: true,
dashArray: [5, 5], gradient: LinearGradient(
strokeWidth: 1, colors: [
); ColorsManager.primaryColor.withOpacity(0.5),
}, Colors.blue.withOpacity(0.1),
drawHorizontalLine: false, ],
), begin: Alignment.center,
lineBarsData: [ end: Alignment.bottomCenter,
LineChartBarData( ),
preventCurveOvershootingThreshold: 0.1, ),
curveSmoothness: 0.5, dotData: FlDotData(
preventCurveOverShooting: true, show: false,
aboveBarData: BarAreaData(), ),
spots: _chartData isStrokeCapRound: true,
.asMap() barWidth: 2,
.entries ),
.map((entry) => FlSpot( ],
entry.key.toDouble(), entry.value.consumption)) borderData: FlBorderData(
.toList(), show: false,
isCurved: true, border: Border.all(
color: ColorsManager.primaryColor.withOpacity(0.6), color: Color(0xff023DFE).withOpacity(0.7),
show: true, width: 10,
shadow: Shadow(color: Colors.black12), ),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: [
ColorsManager.primaryColor.withOpacity(0.5),
Colors.blue.withOpacity(0.1),
],
begin: Alignment.center,
end: Alignment.bottomCenter,
), ),
), ),
dotData: FlDotData(
show: false,
),
isStrokeCapRound: true,
barWidth: 2,
),
],
borderData: FlBorderData(
show: false,
border: Border.all(
color: Color(0xff023DFE).withOpacity(0.7),
width: 10,
), ),
), ),
), ),
), Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 2,
child: Container(
decoration: BoxDecoration(
color: ColorsManager.graysColor,
borderRadius: BorderRadius.circular(10),
),
child:
Expanded(child: Container(child: widget.widget)),
),
),
Spacer(),
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: ColorsManager.graysColor,
borderRadius: BorderRadius.circular(10),
),
child: InkWell(
onTap: widget.onTap,
child: Center(
child: Container(
child: SizedBox(
child: Padding(
padding: const EdgeInsets.all(5),
child: Text(widget.formattedDate),
),
)),
),
),
),
),
],
),
)
],
), ),
), ),
], ],

View File

@ -12,23 +12,17 @@ import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
//Smart Power Clamp //Smart Power Clamp
class SmartPowerDeviceControl extends StatefulWidget class SmartPowerDeviceControl extends StatelessWidget
with HelperResponsiveLayout { with HelperResponsiveLayout {
final String deviceId; final String deviceId;
const SmartPowerDeviceControl({super.key, required this.deviceId}); const SmartPowerDeviceControl({super.key, required this.deviceId});
@override
State<SmartPowerDeviceControl> createState() =>
_SmartPowerDeviceControlState();
}
class _SmartPowerDeviceControlState extends State<SmartPowerDeviceControl> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => SmartPowerBloc(deviceId: widget.deviceId) create: (context) => SmartPowerBloc(deviceId: deviceId)
..add(SmartPowerFetchDeviceEvent(widget.deviceId)), ..add(SmartPowerFetchDeviceEvent(deviceId)),
child: BlocBuilder<SmartPowerBloc, SmartPowerState>( child: BlocBuilder<SmartPowerBloc, SmartPowerState>(
builder: (context, state) { builder: (context, state) {
final _blocProvider = BlocProvider.of<SmartPowerBloc>(context); final _blocProvider = BlocProvider.of<SmartPowerBloc>(context);
@ -37,6 +31,7 @@ class _SmartPowerDeviceControlState extends State<SmartPowerDeviceControl> {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (state is SmartPowerStatusLoaded) { } else if (state is SmartPowerStatusLoaded) {
return _buildStatusControls( return _buildStatusControls(
currentPage: _blocProvider.currentPage,
context: context, context: context,
blocProvider: _blocProvider, blocProvider: _blocProvider,
); );
@ -51,24 +46,9 @@ class _SmartPowerDeviceControlState extends State<SmartPowerDeviceControl> {
Widget _buildStatusControls({ Widget _buildStatusControls({
required BuildContext context, required BuildContext context,
required SmartPowerBloc blocProvider, required SmartPowerBloc blocProvider,
required int currentPage,
}) { }) {
PageController _pageController = PageController(); PageController _pageController = PageController(initialPage: currentPage);
int _currentPage = 0;
void _onArrowPressed(int direction) {
setState(() {
_currentPage = (_currentPage + direction) % 3;
if (_currentPage < 0) {
_currentPage = 2;
}
_pageController.animateToPage(
_currentPage,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
});
}
return Container( return Container(
child: DeviceControlsContainer( child: DeviceControlsContainer(
child: Column( child: Column(
@ -84,45 +64,55 @@ class _SmartPowerDeviceControlState extends State<SmartPowerDeviceControl> {
), ),
], ],
), ),
Row( Padding(
mainAxisAlignment: MainAxisAlignment.spaceBetween, padding: const EdgeInsets.all(10.0),
children: [ child: Row(
PowerClampInfoCard( mainAxisAlignment: MainAxisAlignment.spaceBetween,
iconPath: Assets.powerActiveIcon, children: [
title: 'Active', PowerClampInfoCard(
value: blocProvider iconPath: Assets.powerActiveIcon,
.deviceStatus.status.general.dataPoints[2].value title: 'Active',
.toString(), value: blocProvider
unit: '', .deviceStatus.status.general.dataPoints[2].value
), .toString(),
PowerClampInfoCard( unit: '',
iconPath: Assets.voltMeterIcon, ),
title: 'Current', PowerClampInfoCard(
value: blocProvider iconPath: Assets.voltMeterIcon,
.deviceStatus.status.general.dataPoints[1].value title: 'Current',
.toString(), value: blocProvider
unit: ' A', .deviceStatus.status.general.dataPoints[1].value
), .toString(),
PowerClampInfoCard( unit: ' A',
iconPath: Assets.frequencyIcon, ),
title: 'Frequency', PowerClampInfoCard(
value: blocProvider iconPath: Assets.frequencyIcon,
.deviceStatus.status.general.dataPoints[4].value title: 'Frequency',
.toString(), value: blocProvider
unit: ' Hz', .deviceStatus.status.general.dataPoints[4].value
), .toString(),
], unit: ' Hz',
),
],
),
),
SizedBox(
height: 10,
), ),
PhaseWidget( PhaseWidget(
phaseData: blocProvider.phaseData, phaseData: blocProvider.phaseData,
), ),
Container( Container(
padding: EdgeInsets.all(10), padding: EdgeInsets.only(
top: 10,
left: 20,
right: 20,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: ColorsManager.whiteColors, color: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
), ),
height: 250, height: 325,
child: Column( child: Column(
children: [ children: [
Container( Container(
@ -130,94 +120,125 @@ class _SmartPowerDeviceControlState extends State<SmartPowerDeviceControl> {
color: ColorsManager.graysColor, color: ColorsManager.graysColor,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
), ),
height: 60, height: 50,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
IconButton( IconButton(
icon: Icon(Icons.arrow_left), icon: const Icon(Icons.arrow_left),
onPressed: () => _onArrowPressed(-1), onPressed: () {
blocProvider.add(SmartPowerArrowPressedEvent(-1));
_pageController.previousPage(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
), ),
Text( Text(
_currentPage == 0 currentPage == 0
? 'Total' ? 'Total'
: _currentPage == 0 : currentPage == 1
? 'Phase A' ? 'Phase A'
: _currentPage == 0 : currentPage == 2
? 'Phase B' ? 'Phase B'
: 'Phase C', : 'Phase C',
style: TextStyle(fontSize: 18), style: TextStyle(fontSize: 18),
), ),
IconButton( IconButton(
icon: Icon(Icons.arrow_right), icon: Icon(Icons.arrow_right),
onPressed: () => _onArrowPressed(1), onPressed: () {
blocProvider.add(SmartPowerArrowPressedEvent(1));
_pageController.nextPage(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
), ),
], ],
), ),
), ),
SizedBox(
height: 10,
),
Expanded( Expanded(
child: PageView( child: PageView(
controller: _pageController, controller: _pageController,
onPageChanged: (int page) { onPageChanged: (int page) {
setState(() { blocProvider.add(SmartPowerPageChangedEvent(page));
_currentPage = page;
});
}, },
children: [ children: [
EnergyConsumptionPage( EnergyConsumptionPage(
chartData: [ formattedDate: blocProvider.formattedDate,
EnergyData('12:00 AM', 4.0), onTap: () {
EnergyData('01:00 AM', 3.5), blocProvider.add(SelectDateEvent(context: context));
EnergyData('02:00 AM', 3.8), },
EnergyData('03:00 AM', 3.2), widget: blocProvider.dateSwitcher(),
EnergyData('04:00 AM', 4.0), chartData: blocProvider.energyDataList.isNotEmpty
EnergyData('05:00 AM', 3.4), ? blocProvider.energyDataList
EnergyData('06:00 AM', 3.2), : [
EnergyData('07:00 AM', 3.5), EnergyData('12:00 AM', 4.0),
EnergyData('08:00 AM', 3.8), EnergyData('01:00 AM', 3.5),
EnergyData('09:00 AM', 3.6), EnergyData('02:00 AM', 3.8),
EnergyData('10:00 AM', 3.9), EnergyData('03:00 AM', 3.2),
EnergyData('10:00 AM', 3.9), EnergyData('04:00 AM', 4.0),
EnergyData('11:00 AM', 4.0), EnergyData('05:00 AM', 3.4),
], EnergyData('06:00 AM', 3.2),
EnergyData('07:00 AM', 3.5),
EnergyData('08:00 AM', 3.8),
EnergyData('09:00 AM', 3.6),
EnergyData('10:00 AM', 3.9),
EnergyData('11:00 AM', 4.0),
],
totalConsumption: 10000, totalConsumption: 10000,
date: '10/08/2024', date: '10/08/2024',
), ),
EnergyConsumptionPage( EnergyConsumptionPage(
chartData: [ formattedDate: blocProvider.formattedDate,
EnergyData('12:00 AM', 4.0), onTap: () {
EnergyData('01:00 AM', 3.5), blocProvider.add(SelectDateEvent(context: context));
EnergyData('02:00 AM', 3.8), },
EnergyData('03:00 AM', 3.2), widget: blocProvider.dateSwitcher(),
EnergyData('04:00 AM', 4.0), chartData: blocProvider.energyDataList.isNotEmpty
EnergyData('05:00 AM', 3.4), ? blocProvider.energyDataList
EnergyData('06:00 AM', 3.2), : [
EnergyData('07:00 AM', 3.5), EnergyData('12:00 AM', 4.0),
EnergyData('08:00 AM', 3.8), EnergyData('01:00 AM', 3.5),
EnergyData('09:00 AM', 3.6), EnergyData('02:00 AM', 3.8),
EnergyData('10:00 AM', 3.9), EnergyData('03:00 AM', 3.2),
EnergyData('10:00 AM', 3.9), EnergyData('04:00 AM', 4.0),
EnergyData('11:00 AM', 4.0), EnergyData('05:00 AM', 3.4),
], EnergyData('06:00 AM', 3.2),
EnergyData('07:00 AM', 3.5),
EnergyData('08:00 AM', 3.8),
EnergyData('09:00 AM', 3.6),
EnergyData('10:00 AM', 3.9),
EnergyData('11:00 AM', 4.0),
],
totalConsumption: 10000, totalConsumption: 10000,
date: '10/08/2024', date: '10/08/2024',
), ),
EnergyConsumptionPage( EnergyConsumptionPage(
chartData: [ formattedDate: blocProvider.formattedDate,
EnergyData('12:00 AM', 4.0), onTap: () {
EnergyData('01:00 AM', 6.5), blocProvider.add(SelectDateEvent(context: context));
EnergyData('02:00 AM', 3.8), },
EnergyData('03:00 AM', 3.2), widget: blocProvider.dateSwitcher(),
EnergyData('04:00 AM', 6.0), chartData: blocProvider.energyDataList.isNotEmpty
EnergyData('05:00 AM', 3.4), ? blocProvider.energyDataList
EnergyData('06:00 AM', 5.2), : [
EnergyData('07:00 AM', 3.5), EnergyData('12:00 AM', 4.0),
EnergyData('08:00 AM', 3.8), EnergyData('01:00 AM', 6.5),
EnergyData('09:00 AM', 5.6), EnergyData('02:00 AM', 3.8),
EnergyData('10:00 AM', 6.9), EnergyData('03:00 AM', 3.2),
EnergyData('10:00 AM', 3.9), EnergyData('04:00 AM', 6.0),
EnergyData('11:00 AM', 6.0), EnergyData('05:00 AM', 3.4),
], EnergyData('06:00 AM', 5.2),
EnergyData('07:00 AM', 3.5),
EnergyData('08:00 AM', 3.8),
EnergyData('09:00 AM', 5.6),
EnergyData('10:00 AM', 6.9),
EnergyData('11:00 AM', 6.0),
],
totalConsumption: 10000, totalConsumption: 10000,
date: '10/08/2024', date: '10/08/2024',
), ),