mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-27 02:54:56 +00:00
power_clamp_functionality
This commit is contained in:
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
@ -65,4 +67,27 @@ class PageChangedEvent extends SmartPowerEvent {
|
|||||||
class PageArrowPressedEvent extends SmartPowerEvent {
|
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});
|
||||||
|
}
|
||||||
|
|||||||
@ -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});
|
||||||
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -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),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -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',
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user