From 4744009cb65c887a80346a898733c032813877d7 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Fri, 27 Jun 2025 17:11:17 +0300 Subject: [PATCH 1/5] Update TotalEnergyConsumptionChart to adjust Y-axis limits and intervals for better data representation --- .../widgets/total_energy_consumption_chart.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart index 85b95c29..bba1fa14 100644 --- a/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart +++ b/lib/pages/analytics/modules/energy_management/widgets/total_energy_consumption_chart.dart @@ -14,14 +14,17 @@ class TotalEnergyConsumptionChart extends StatelessWidget { return Expanded( child: LineChart( LineChartData( + maxY: chartData.isEmpty + ? null + : chartData.map((e) => e.value).reduce((a, b) => a > b ? a : b) + 250, clipData: const FlClipData.vertical(), titlesData: EnergyManagementChartsHelper.titlesData( context, - leftTitlesInterval: 250, + leftTitlesInterval: 500, ), gridData: EnergyManagementChartsHelper.gridData().copyWith( checkToShowHorizontalLine: (value) => true, - horizontalInterval: 250, + horizontalInterval: 500, ), borderData: EnergyManagementChartsHelper.borderData(), lineTouchData: EnergyManagementChartsHelper.lineTouchData(), @@ -29,7 +32,6 @@ class TotalEnergyConsumptionChart extends StatelessWidget { ), duration: Duration.zero, curve: Curves.easeIn, - ), ); } From 13e9a808ab70e0fe745d25ac9eadfb72cfcf5845 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Fri, 27 Jun 2025 22:09:00 +0300 Subject: [PATCH 2/5] uses UTC dates as an attempt to fix heatmap's rendering bug. --- lib/pages/analytics/models/occupancy_heat_map_model.dart | 4 ++-- .../modules/occupancy/widgets/occupancy_heat_map.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pages/analytics/models/occupancy_heat_map_model.dart b/lib/pages/analytics/models/occupancy_heat_map_model.dart index e4b7d730..4c7a37d4 100644 --- a/lib/pages/analytics/models/occupancy_heat_map_model.dart +++ b/lib/pages/analytics/models/occupancy_heat_map_model.dart @@ -21,11 +21,11 @@ class OccupancyHeatMapModel extends Equatable { return OccupancyHeatMapModel( uuid: json['uuid'] as String? ?? '', - eventDate: DateTime( + eventDate: DateTime.utc( int.parse(year ?? '2025'), int.parse(month ?? '1'), int.parse(day ?? '1'), - ).toUtc(), + ), countTotalPresenceDetected: num.parse( json['count_total_presence_detected']?.toString() ?? '0', ).toInt(), diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart index 0809a990..05c5bb71 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart @@ -20,14 +20,14 @@ class OccupancyHeatMap extends StatelessWidget { : 0; DateTime _getStartingDate() { - final jan1 = DateTime(DateTime.now().year, 1, 1).toUtc(); + final jan1 = DateTime.utc(DateTime.now().year, 1, 1); final startOfWeek = jan1.subtract(Duration(days: jan1.weekday - 1)); return startOfWeek; } List _generatePaintItems(DateTime startDate) { return List.generate(_totalWeeks * 7, (index) { - final date = startDate.toUtc().add(Duration(days: index)); + final date = startDate.add(Duration(days: index)); final value = heatMapData[date] ?? 0; return OccupancyPaintItem(index: index, value: value, date: date); }); From c4fd90b3bca1aa3ca390b1330c606c3e3c32fee1 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sat, 28 Jun 2025 13:16:06 +0300 Subject: [PATCH 3/5] testing heatmap fixes. --- .../modules/occupancy/widgets/occupancy_heat_map.dart | 9 +++++++-- .../occupancy/widgets/occupancy_heat_map_box.dart | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart index 05415421..482f0029 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map.dart @@ -9,8 +9,13 @@ import 'package:syncrow_web/pages/analytics/modules/occupancy/widgets/occupancy_ import 'package:syncrow_web/utils/color_manager.dart'; class OccupancyHeatMap extends StatelessWidget { - const OccupancyHeatMap({required this.heatMapData, super.key}); + const OccupancyHeatMap({ + required this.heatMapData, + required this.selectedDate, + super.key, + }); final Map heatMapData; + final DateTime selectedDate; static const _cellSize = 16.0; static const _totalWeeks = 53; @@ -20,7 +25,7 @@ class OccupancyHeatMap extends StatelessWidget { : 0; DateTime _getStartingDate() { - final jan1 = DateTime(DateTime.now().year, 1, 1); + final jan1 = DateTime.utc(selectedDate.year, 1, 1); final startOfWeek = jan1.subtract(Duration(days: jan1.weekday - 1)); return startOfWeek; } diff --git a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart index c3b537e0..a5f56aa4 100644 --- a/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart +++ b/lib/pages/analytics/modules/occupancy/widgets/occupancy_heat_map_box.dart @@ -70,6 +70,8 @@ class OccupancyHeatMapBox extends StatelessWidget { const SizedBox(height: 20), Expanded( child: OccupancyHeatMap( + selectedDate: + context.watch().state.yearlyDate, heatMapData: state.heatMapData.asMap().map( (_, value) => MapEntry( value.eventDate, From b97183fb61baef13f4018c6202ede44814f0f8ce Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Sat, 28 Jun 2025 15:47:42 +0400 Subject: [PATCH 4/5] SP-1801 --- .../device_managment/ac/bloc/ac_bloc.dart | 57 ++++++------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/lib/pages/device_managment/ac/bloc/ac_bloc.dart b/lib/pages/device_managment/ac/bloc/ac_bloc.dart index 38d11a46..2ac26b41 100644 --- a/lib/pages/device_managment/ac/bloc/ac_bloc.dart +++ b/lib/pages/device_managment/ac/bloc/ac_bloc.dart @@ -45,8 +45,7 @@ class AcBloc extends Bloc { ) async { emit(AcsLoadingState()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = AcStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.countdown1 != 0) { final totalMinutes = deviceStatus.countdown1 * 6; @@ -74,22 +73,18 @@ class AcBloc extends Bloc { void _listenToChanges(String deviceId) { try { final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - _deviceStatusSubscription = - ref.onValue.listen((DatabaseEvent event) async { + _deviceStatusSubscription = ref.onValue.listen((DatabaseEvent event) async { if (event.snapshot.value == null) return; - Map usersMap = - event.snapshot.value as Map; + final usersMap = event.snapshot.value! as Map; - List statusList = []; + final statusList = []; usersMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); + statusList.add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = - AcStatusModel.fromJson(usersMap['productUuid'], statusList); + deviceStatus = AcStatusModel.fromJson(usersMap['productUuid'], statusList); print('Device status updated: ${deviceStatus.acSwitch}'); if (!isClosed) { @@ -111,21 +106,14 @@ class AcBloc extends Bloc { AcControlEvent event, Emitter emit, ) async { - emit(AcsLoadingState()); - try { - final success = await controlDeviceService.controlDevice( + _updateDeviceFunctionFromCode(event.code, event.value); + emit(ACStatusLoaded(status: deviceStatus)); + await controlDeviceService.controlDevice( deviceUuid: event.deviceId, status: Status(code: event.code, value: event.value), ); - _updateDeviceFunctionFromCode(event.code, event.value); - emit(ACStatusLoaded(status: deviceStatus)); - if (!success) { - emit(const AcsFailedState(error: 'Failed to control device')); - } - } catch (e) { - emit(AcsFailedState(error: e.toString())); - } + } catch (e) {} } FutureOr _onFetchAcBatchStatus( @@ -134,10 +122,8 @@ class AcBloc extends Bloc { ) async { emit(AcsLoadingState()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesIds); - deviceStatus = - AcStatusModel.fromJson(event.devicesIds.first, status.status); + final status = await DevicesManagementApi().getBatchStatus(event.devicesIds); + deviceStatus = AcStatusModel.fromJson(event.devicesIds.first, status.status); emit(ACStatusLoaded(status: deviceStatus)); } catch (e) { emit(AcsFailedState(error: e.toString())); @@ -148,23 +134,16 @@ class AcBloc extends Bloc { AcBatchControlEvent event, Emitter emit, ) async { - emit(AcsLoadingState()); _updateDeviceFunctionFromCode(event.code, event.value); emit(ACStatusLoaded(status: deviceStatus)); try { - final success = await batchControlDevicesService.batchControlDevices( + await batchControlDevicesService.batchControlDevices( uuids: event.devicesIds, code: event.code, value: event.value, ); - - if (!success) { - emit(const AcsFailedState(error: 'Failed to control devices')); - } - } catch (e) { - emit(AcsFailedState(error: e.toString())); - } + } catch (e) {} } Future _onFactoryReset( @@ -197,8 +176,8 @@ class AcBloc extends Bloc { void _handleIncreaseTime(IncreaseTimeEvent event, Emitter emit) { if (state is! ACStatusLoaded) return; final currentState = state as ACStatusLoaded; - int newHours = scheduledHours; - int newMinutes = scheduledMinutes + 30; + var newHours = scheduledHours; + var newMinutes = scheduledMinutes + 30; newHours += newMinutes ~/ 60; newMinutes = newMinutes % 60; if (newHours > 23) { @@ -220,7 +199,7 @@ class AcBloc extends Bloc { ) { if (state is! ACStatusLoaded) return; final currentState = state as ACStatusLoaded; - int totalMinutes = (scheduledHours * 60) + scheduledMinutes; + var totalMinutes = (scheduledHours * 60) + scheduledMinutes; totalMinutes = (totalMinutes - 30).clamp(0, 1440); scheduledHours = totalMinutes ~/ 60; scheduledMinutes = totalMinutes % 60; @@ -293,7 +272,7 @@ class AcBloc extends Bloc { void _startCountdownTimer(Emitter emit) { _countdownTimer?.cancel(); - int totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60); + var totalSeconds = (scheduledHours * 3600) + (scheduledMinutes * 60); _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (totalSeconds > 0) { From b96f65d2c2b0cc577996e94101eb5a57212063c4 Mon Sep 17 00:00:00 2001 From: Rafeek-Khoudare Date: Sun, 29 Jun 2025 10:42:18 +0300 Subject: [PATCH 5/5] fix the open close states when curtain module --- .../curtain_module/view/curtain_module_items.dart | 2 +- .../schedule_widgets/schedual_view.dart | 15 ++++++++++----- .../schedule_widgets/schedule_table.dart | 14 ++++++++++++-- .../helper/add_schedule_dialog_helper.dart | 14 +++++++++++--- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib/pages/device_managment/curtain_module/view/curtain_module_items.dart b/lib/pages/device_managment/curtain_module/view/curtain_module_items.dart index 48b5ab2a..82c812ce 100644 --- a/lib/pages/device_managment/curtain_module/view/curtain_module_items.dart +++ b/lib/pages/device_managment/curtain_module/view/curtain_module_items.dart @@ -64,7 +64,7 @@ class CurtainModuleItems extends StatelessWidget with HelperResponsiveLayout { deviceUuid: deviceId, category: 'CUR_2', code: 'control', - value: 'open', + ), )); }, diff --git a/lib/pages/device_managment/schedule_device/schedule_widgets/schedual_view.dart b/lib/pages/device_managment/schedule_device/schedule_widgets/schedual_view.dart index 3b7bc138..c511b8bd 100644 --- a/lib/pages/device_managment/schedule_device/schedule_widgets/schedual_view.dart +++ b/lib/pages/device_managment/schedule_device/schedule_widgets/schedual_view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/schedule_device/bloc/schedule_bloc.dart'; import 'package:syncrow_web/pages/device_managment/schedule_device/schedule_widgets/count_down_button.dart'; import 'package:syncrow_web/pages/device_managment/schedule_device/schedule_widgets/count_down_inching_view.dart'; @@ -9,6 +10,7 @@ import 'package:syncrow_web/pages/device_managment/schedule_device/schedule_widg import 'package:syncrow_web/pages/device_managment/schedule_device/schedule_widgets/schedule_mode_buttons.dart'; import 'package:syncrow_web/pages/device_managment/schedule_device/schedule_widgets/schedule_mode_selector.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; class BuildScheduleView extends StatelessWidget { @@ -17,12 +19,10 @@ class BuildScheduleView extends StatelessWidget { required this.deviceUuid, required this.category, this.code, - this.value, }); final String deviceUuid; final String category; final String? code; - final String? value; @override Widget build(BuildContext context) { @@ -64,15 +64,20 @@ class BuildScheduleView extends StatelessWidget { final entry = await ScheduleDialogHelper .showAddScheduleDialog( context, - schedule: null, + schedule: ScheduleEntry( + category: category, + time: '', + function: Status( + code: code.toString(), value: null), + days: [], + ), isEdit: false, code: code, - value: value, ); if (entry != null) { context.read().add( ScheduleAddEvent( - category: entry.category, + category: category, code: entry.function.code, time: entry.time, functionOn: entry.function.value, diff --git a/lib/pages/device_managment/schedule_device/schedule_widgets/schedule_table.dart b/lib/pages/device_managment/schedule_device/schedule_widgets/schedule_table.dart index 98ae0515..b23e48df 100644 --- a/lib/pages/device_managment/schedule_device/schedule_widgets/schedule_table.dart +++ b/lib/pages/device_managment/schedule_device/schedule_widgets/schedule_table.dart @@ -162,11 +162,18 @@ class _ScheduleTableView extends StatelessWidget { child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { + bool temp; + if (schedule.category == 'CUR_2') { + temp = schedule.function.value == 'open' ? true : false; + } else { + temp = schedule.function.value as bool; + } context.read().add( ScheduleUpdateEntryEvent( category: schedule.category, scheduleId: schedule.scheduleId, - functionOn: schedule.function.value, + functionOn: temp, + // schedule.function.value, enable: !schedule.enable, ), ); @@ -188,7 +195,10 @@ class _ScheduleTableView extends StatelessWidget { child: Text(_getSelectedDays( ScheduleModel.parseSelectedDays(schedule.days)))), Center(child: Text(formatIsoStringToTime(schedule.time, context))), - Center(child: Text(schedule.function.value ? 'On' : 'Off')), + schedule.category == 'CUR_2' + ? Center( + child: Text(schedule.function.value == true ? 'open' : 'close')) + : Center(child: Text(schedule.function.value ? 'On' : 'Off')), Center( child: Wrap( runAlignment: WrapAlignment.center, diff --git a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart index b8059402..51087704 100644 --- a/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart +++ b/lib/pages/device_managment/water_heater/helper/add_schedule_dialog_helper.dart @@ -18,7 +18,6 @@ class ScheduleDialogHelper { ScheduleEntry? schedule, bool isEdit = false, String? code, - String? value, }) { final initialTime = schedule != null ? _convertStringToTimeOfDay(schedule.time) @@ -117,12 +116,21 @@ class ScheduleDialogHelper { width: 100, child: ElevatedButton( onPressed: () { + dynamic temp; + if (schedule?.category == 'CUR_2') { + temp = functionOn! ? 'open' : 'close'; + } else { + temp = functionOn; + } + print(temp); final entry = ScheduleEntry( category: schedule?.category ?? 'switch_1', time: _formatTimeOfDayToISO(selectedTime), function: Status( - code: code ?? 'switch_1', - value: value ?? functionOn), + code: code ?? 'switch_1', + value: temp, + // functionOn, + ), days: _convertSelectedDaysToStrings(selectedDays), scheduleId: schedule?.scheduleId, );