From c07b53107e474318446653e4efae455085d6e9d6 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Thu, 15 May 2025 10:51:09 +0300 Subject: [PATCH] SP-1506-FE-chart per phase api integration. --- .../models/phases_energy_consumption.dart | 65 +++++++++++++++---- .../analytics/views/analytics_page.dart | 4 +- ...gy_consumption_by_phases_chart_helper.dart | 20 ------ .../fetch_energy_management_data_helper.dart | 27 ++++++-- .../energy_consumption_by_phases_chart.dart | 39 +++++++---- .../power_clamp_energy_data_widget.dart | 8 +++ ...et_energy_consumption_by_phases_param.dart | 16 ++--- ..._energy_consumption_by_phases_service.dart | 29 --------- ..._energy_consumption_by_phases_service.dart | 5 +- 9 files changed, 120 insertions(+), 93 deletions(-) delete mode 100644 lib/pages/analytics/modules/energy_management/helpers/energy_consumption_by_phases_chart_helper.dart delete mode 100644 lib/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart diff --git a/lib/pages/analytics/models/phases_energy_consumption.dart b/lib/pages/analytics/models/phases_energy_consumption.dart index f986c3ad..a826bac0 100644 --- a/lib/pages/analytics/models/phases_energy_consumption.dart +++ b/lib/pages/analytics/models/phases_energy_consumption.dart @@ -1,27 +1,66 @@ import 'package:equatable/equatable.dart'; class PhasesEnergyConsumption extends Equatable { - final int month; - final double phaseA; - final double phaseB; - final double phaseC; + final String uuid; + final DateTime createdAt; + final DateTime updatedAt; + final String deviceUuid; + final DateTime date; + final double energyConsumedKw; + final double energyConsumedA; + final double energyConsumedB; + final double energyConsumedC; const PhasesEnergyConsumption({ - required this.month, - required this.phaseA, - required this.phaseB, - required this.phaseC, + required this.uuid, + required this.createdAt, + required this.updatedAt, + required this.deviceUuid, + required this.date, + required this.energyConsumedKw, + required this.energyConsumedA, + required this.energyConsumedB, + required this.energyConsumedC, }); @override - List get props => [month, phaseA, phaseB, phaseC]; + List get props => [ + uuid, + createdAt, + updatedAt, + deviceUuid, + date, + energyConsumedKw, + energyConsumedA, + energyConsumedB, + energyConsumedC, + ]; factory PhasesEnergyConsumption.fromJson(Map json) { return PhasesEnergyConsumption( - month: json['month'] as int, - phaseA: (json['phaseA'] as num).toDouble(), - phaseB: (json['phaseB'] as num).toDouble(), - phaseC: (json['phaseC'] as num).toDouble(), + uuid: json['uuid'] as String, + createdAt: DateTime.parse(json['createdAt'] as String), + updatedAt: DateTime.parse(json['updatedAt'] as String), + deviceUuid: json['deviceUuid'] as String, + date: DateTime.parse(json['date'] as String), + energyConsumedKw: double.parse(json['energyConsumedKw']), + energyConsumedA: double.parse(json['energyConsumedA']), + energyConsumedB: double.parse(json['energyConsumedB']), + energyConsumedC: double.parse(json['energyConsumedC']), ); } + + Map toJson() { + return { + 'uuid': uuid, + 'createdAt': createdAt.toIso8601String(), + 'updatedAt': updatedAt.toIso8601String(), + 'deviceUuid': deviceUuid, + 'date': date.toIso8601String().split('T')[0], + 'energyConsumedKw': energyConsumedKw.toString(), + 'energyConsumedA': energyConsumedA.toString(), + 'energyConsumedB': energyConsumedB.toString(), + 'energyConsumedC': energyConsumedC.toString(), + }; + } } diff --git a/lib/pages/analytics/modules/analytics/views/analytics_page.dart b/lib/pages/analytics/modules/analytics/views/analytics_page.dart index 883672a2..72cc7d51 100644 --- a/lib/pages/analytics/modules/analytics/views/analytics_page.dart +++ b/lib/pages/analytics/modules/analytics/views/analytics_page.dart @@ -15,7 +15,7 @@ import 'package:syncrow_web/pages/analytics/modules/occupancy/blocs/occupancy_he import 'package:syncrow_web/pages/analytics/services/analytics_devices/analytics_devices_service_delagate.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_energy_management_analytics_devices_service.dart'; import 'package:syncrow_web/pages/analytics/services/analytics_devices/remote_occupancy_analytics_devices_service.dart'; -import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart'; +import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart'; import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/remote_energy_consumption_per_device_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupacy/fake_occupacy_service.dart'; import 'package:syncrow_web/pages/analytics/services/occupancy_heat_map/remote_occupancy_heat_map_service.dart'; @@ -57,7 +57,7 @@ class _AnalyticsPageState extends State { ), BlocProvider( create: (context) => EnergyConsumptionByPhasesBloc( - FakeEnergyConsumptionByPhasesService(), + RemoteEnergyConsumptionByPhasesService(_httpService), ), ), BlocProvider( diff --git a/lib/pages/analytics/modules/energy_management/helpers/energy_consumption_by_phases_chart_helper.dart b/lib/pages/analytics/modules/energy_management/helpers/energy_consumption_by_phases_chart_helper.dart deleted file mode 100644 index e79fe48d..00000000 --- a/lib/pages/analytics/modules/energy_management/helpers/energy_consumption_by_phases_chart_helper.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart'; - -abstract final class EnergyConsumptionByPhasesChartHelper { - const EnergyConsumptionByPhasesChartHelper._(); - - static const fakeData = [ - PhasesEnergyConsumption(month: 1, phaseA: 200, phaseB: 300, phaseC: 400), - PhasesEnergyConsumption(month: 2, phaseA: 300, phaseB: 400, phaseC: 500), - PhasesEnergyConsumption(month: 3, phaseA: 400, phaseB: 500, phaseC: 600), - PhasesEnergyConsumption(month: 4, phaseA: 100, phaseB: 100, phaseC: 100), - PhasesEnergyConsumption(month: 5, phaseA: 300, phaseB: 400, phaseC: 500), - PhasesEnergyConsumption(month: 6, phaseA: 300, phaseB: 100, phaseC: 400), - PhasesEnergyConsumption(month: 7, phaseA: 300, phaseB: 100, phaseC: 400), - PhasesEnergyConsumption(month: 8, phaseA: 500, phaseB: 100, phaseC: 100), - PhasesEnergyConsumption(month: 9, phaseA: 500, phaseB: 100, phaseC: 200), - PhasesEnergyConsumption(month: 10, phaseA: 100, phaseB: 50, phaseC: 50), - PhasesEnergyConsumption(month: 11, phaseA: 600, phaseB: 750, phaseC: 130), - PhasesEnergyConsumption(month: 12, phaseA: 100, phaseB: 80, phaseC: 100), - ]; -} diff --git a/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart b/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart index 96fbb224..29da8c61 100644 --- a/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart +++ b/lib/pages/analytics/modules/energy_management/helpers/fetch_energy_management_data_helper.dart @@ -34,14 +34,26 @@ abstract final class FetchEnergyManagementDataHelper { final datePickerState = context.read().state; final selectedDate0 = selectedDate ?? datePickerState.monthlyDate; - loadAnalyticsDevices(context, communityUuid: communityId, spaceUuid: spaceId); + loadAnalyticsDevices( + context, + communityUuid: communityId, + spaceUuid: spaceId, + selectedDate: selectedDate0, + ); loadTotalEnergyConsumption( context, selectedDate: selectedDate0, communityId: communityId, spaceId: spaceId, ); - loadEnergyConsumptionByPhases(context, selectedDate: selectedDate); + final selectedDevice = getSelectedDevice(context); + if (selectedDevice case final AnalyticsDevice device) { + loadEnergyConsumptionByPhases( + context, + powerClampUuid: device.uuid, + selectedDate: selectedDate0, + ); + } loadEnergyConsumptionPerDevice( context, communityId: communityId, @@ -54,11 +66,12 @@ abstract final class FetchEnergyManagementDataHelper { static void loadEnergyConsumptionByPhases( BuildContext context, { + required String powerClampUuid, DateTime? selectedDate, }) { final param = GetEnergyConsumptionByPhasesParam( - startDate: selectedDate, - spaceId: '', + date: selectedDate, + powerClampUuid: powerClampUuid, ); context.read().add( LoadEnergyConsumptionByPhasesEvent(param: param), @@ -121,6 +134,7 @@ abstract final class FetchEnergyManagementDataHelper { BuildContext context, { required String communityUuid, required String spaceUuid, + required DateTime selectedDate, }) { context.read().add( LoadAnalyticsDevicesEvent( @@ -128,6 +142,11 @@ abstract final class FetchEnergyManagementDataHelper { context.read().add( LoadPowerClampInfoEvent(device.uuid), ); + loadEnergyConsumptionByPhases( + context, + powerClampUuid: device.uuid, + selectedDate: selectedDate, + ); context.read().add( RealtimeDeviceChangesStarted(device.uuid), ); diff --git a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart index c94755bb..883e8556 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/energy_consumption_by_phases_chart.dart @@ -1,6 +1,6 @@ import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; -import 'package:syncrow_web/pages/analytics/helpers/get_month_name_from_int.dart'; +import 'package:intl/intl.dart'; import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/helpers/energy_management_charts_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -31,21 +31,25 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { barRods: [ BarChartRodData( color: ColorsManager.vividBlue.withValues(alpha: 0.1), - toY: data.phaseA + data.phaseB + data.phaseC, + toY: data.energyConsumedA + + data.energyConsumedB + + data.energyConsumedC, rodStackItems: [ BarChartRodStackItem( 0, - data.phaseA, + data.energyConsumedA, ColorsManager.vividBlue.withValues(alpha: 0.8), ), BarChartRodStackItem( - data.phaseA, - data.phaseA + data.phaseB, + data.energyConsumedA, + data.energyConsumedA + data.energyConsumedB, ColorsManager.vividBlue.withValues(alpha: 0.4), ), BarChartRodStackItem( - data.phaseA + data.phaseB, - data.phaseA + data.phaseB + data.phaseC, + data.energyConsumedA + data.energyConsumedB, + data.energyConsumedA + + data.energyConsumedB + + data.energyConsumedC, ColorsManager.vividBlue.withValues(alpha: 0.15), ), ], @@ -91,18 +95,27 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { }) { final data = energyData; - final month = data[group.x.toInt()].month.getMonthName; - final phaseA = data[group.x.toInt()].phaseA; - final phaseB = data[group.x.toInt()].phaseB; - final phaseC = data[group.x.toInt()].phaseC; + final date = DateFormat('dd/MM/yyyy').format(data[group.x.toInt()].date); + final phaseA = data[group.x.toInt()].energyConsumedA; + final phaseB = data[group.x.toInt()].energyConsumedB; + final phaseC = data[group.x.toInt()].energyConsumedC; + final total = data[group.x.toInt()].energyConsumedKw; return BarTooltipItem( - '$month\n', + '$date\n', context.textTheme.bodyMedium!.copyWith( color: ColorsManager.blackColor, fontSize: 14, ), + textAlign: TextAlign.start, children: [ + TextSpan( + text: 'Total: $total\n', + style: context.textTheme.bodySmall?.copyWith( + color: ColorsManager.blackColor, + fontSize: 12, + ), + ), TextSpan( text: 'Phase A: $phaseA\n', style: context.textTheme.bodySmall?.copyWith( @@ -144,7 +157,7 @@ class EnergyConsumptionByPhasesChart extends StatelessWidget { sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, _) { - final month = energyData[value.toInt()].month.getMonthName; + final month = DateFormat('dd/MM').format(energyData[value.toInt()].date); return FittedBox( alignment: AlignmentDirectional.bottomCenter, fit: BoxFit.scaleDown, diff --git a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart index 95f343c2..8a53d037 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/analytics/models/power_clamp_energy_status.dart'; +import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_date_picker_bloc/analytics_date_picker_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/analytics/blocs/analytics_devices/analytics_devices_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/power_clamp_info/power_clamp_info_bloc.dart'; import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/realtime_device_changes/realtime_device_changes_bloc.dart'; @@ -11,6 +12,7 @@ import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/po import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_phases_data_widget.dart'; import 'package:syncrow_web/pages/analytics/widgets/analytics_error_widget.dart'; import 'package:syncrow_web/pages/device_managment/power_clamp/models/power_clamp_model.dart'; +import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; @@ -132,6 +134,12 @@ class PowerClampEnergyDataWidget extends StatelessWidget { alignment: AlignmentDirectional.centerEnd, child: AnalyticsDeviceDropdown( onChanged: (value) { + FetchEnergyManagementDataHelper.loadEnergyConsumptionByPhases( + context, + powerClampUuid: value.uuid, + selectedDate: + context.read().state.monthlyDate, + ); FetchEnergyManagementDataHelper.loadRealtimeDeviceChanges( context, deviceUuid: value.uuid, diff --git a/lib/pages/analytics/params/get_energy_consumption_by_phases_param.dart b/lib/pages/analytics/params/get_energy_consumption_by_phases_param.dart index 169e2753..243e156e 100644 --- a/lib/pages/analytics/params/get_energy_consumption_by_phases_param.dart +++ b/lib/pages/analytics/params/get_energy_consumption_by_phases_param.dart @@ -1,24 +1,20 @@ import 'package:equatable/equatable.dart'; class GetEnergyConsumptionByPhasesParam extends Equatable { - final DateTime? startDate; - final DateTime? endDate; - final String? spaceId; + final String powerClampUuid; + final DateTime? date; const GetEnergyConsumptionByPhasesParam({ - this.startDate, - this.endDate, - this.spaceId, + required this.powerClampUuid, + this.date, }); Map toJson() { return { - 'startDate': startDate?.toIso8601String(), - 'endDate': endDate?.toIso8601String(), - 'spaceId': spaceId, + 'monthDate': '${date?.year}-${date?.month.toString().padLeft(2, '0')}', }; } @override - List get props => [startDate, endDate, spaceId]; + List get props => [powerClampUuid, date]; } diff --git a/lib/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart b/lib/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart deleted file mode 100644 index f6ce67c9..00000000 --- a/lib/pages/analytics/services/energy_consumption_by_phases/fake_energy_consumption_by_phases_service.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:syncrow_web/pages/analytics/models/phases_energy_consumption.dart'; -import 'package:syncrow_web/pages/analytics/params/get_energy_consumption_by_phases_param.dart'; -import 'package:syncrow_web/pages/analytics/services/energy_consumption_by_phases/energy_consumption_by_phases_service.dart'; - -class FakeEnergyConsumptionByPhasesService - implements EnergyConsumptionByPhasesService { - @override - Future> load( - GetEnergyConsumptionByPhasesParam param, - ) { - return Future.delayed( - const Duration(milliseconds: 500), - () => const [ - PhasesEnergyConsumption(month: 1, phaseA: 200, phaseB: 300, phaseC: 400), - PhasesEnergyConsumption(month: 2, phaseA: 300, phaseB: 400, phaseC: 500), - PhasesEnergyConsumption(month: 3, phaseA: 400, phaseB: 500, phaseC: 600), - PhasesEnergyConsumption(month: 4, phaseA: 100, phaseB: 100, phaseC: 100), - PhasesEnergyConsumption(month: 5, phaseA: 300, phaseB: 400, phaseC: 500), - PhasesEnergyConsumption(month: 6, phaseA: 300, phaseB: 100, phaseC: 400), - PhasesEnergyConsumption(month: 7, phaseA: 300, phaseB: 100, phaseC: 400), - PhasesEnergyConsumption(month: 8, phaseA: 500, phaseB: 100, phaseC: 100), - PhasesEnergyConsumption(month: 9, phaseA: 500, phaseB: 100, phaseC: 200), - PhasesEnergyConsumption(month: 10, phaseA: 100, phaseB: 50, phaseC: 50), - PhasesEnergyConsumption(month: 11, phaseA: 600, phaseB: 750, phaseC: 130), - PhasesEnergyConsumption(month: 12, phaseA: 100, phaseB: 100, phaseC: 100), - ], - ); - } -} diff --git a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart index f0ac31ed..28df5eed 100644 --- a/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart +++ b/lib/pages/analytics/services/energy_consumption_by_phases/remote_energy_consumption_by_phases_service.dart @@ -15,8 +15,9 @@ final class RemoteEnergyConsumptionByPhasesService ) async { try { final response = await _httpService.get( - path: 'endpoint', + path: '/power-clamp/${param.powerClampUuid}/historical', showServerMessage: true, + queryParameters: param.toJson(), expectedResponseModel: (data) { final json = data as Map? ?? {}; final mappedData = json['data'] as List? ?? []; @@ -28,7 +29,7 @@ final class RemoteEnergyConsumptionByPhasesService ); return response; } catch (e) { - throw Exception('Failed to load energy consumption per device: $e'); + throw Exception('Failed to load energy consumption per phase: $e'); } } }