mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
Integrated realtime data.
This commit is contained in:
@ -6,10 +6,12 @@ import 'package:syncrow_web/pages/analytics/modules/analytics/widgets/analytics_
|
|||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_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/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';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.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/fake_energy_consumption_by_phases_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/fake_energy_consumption_per_device_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/energy_consumption_per_device/fake_energy_consumption_per_device_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/power_clamp_info/remote_power_clamp_info_service.dart';
|
||||||
|
import 'package:syncrow_web/pages/analytics/services/realtime_device_service/firebase_realtime_device_service.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/fake_total_energy_consumption_service.dart';
|
import 'package:syncrow_web/pages/analytics/services/total_energy_consumption/fake_total_energy_consumption_service.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
@ -46,6 +48,11 @@ class AnalyticsPage extends StatelessWidget {
|
|||||||
RemotePowerClampInfoService(HTTPService()),
|
RemotePowerClampInfoService(HTTPService()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
BlocProvider(
|
||||||
|
create: (context) => RealtimeDeviceChangesBloc(
|
||||||
|
FirebaseRealtimeDeviceService(),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: const AnalyticsPageForm(),
|
child: const AnalyticsPageForm(),
|
||||||
);
|
);
|
||||||
|
@ -43,5 +43,13 @@ class PowerClampInfoBloc extends Bloc<PowerClampInfoEvent, PowerClampInfoState>
|
|||||||
void _onUpdatePowerClampStatusEvent(
|
void _onUpdatePowerClampStatusEvent(
|
||||||
UpdatePowerClampStatusEvent event,
|
UpdatePowerClampStatusEvent event,
|
||||||
Emitter<PowerClampInfoState> emit,
|
Emitter<PowerClampInfoState> emit,
|
||||||
) async {}
|
) async {
|
||||||
|
final currentModel = state.powerClampModel;
|
||||||
|
if (currentModel == null) return;
|
||||||
|
|
||||||
|
final updatedStatus = PowerStatus.fromStatusList(event.statusList);
|
||||||
|
final updatedModel = currentModel.copyWith(statusPower: updatedStatus);
|
||||||
|
|
||||||
|
emit(state.copyWith(powerClampModel: updatedModel));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,12 @@ class RealtimeDeviceChangesBloc
|
|||||||
onData: (data) {
|
onData: (data) {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
deviceStatusList: [...currentState.deviceStatusList, data],
|
deviceStatusList: [
|
||||||
|
...currentState.deviceStatusList.where((device) =>
|
||||||
|
!data.any((newDevice) => newDevice.code == device.code)),
|
||||||
|
...data,
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_by_phases/energy_consumption_by_phases_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/energy_consumption_per_device/energy_consumption_per_device_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/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';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/blocs/total_energy_consumption/total_energy_consumption_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/energy_consumption_per_device_chart_box.dart';
|
||||||
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart';
|
import 'package:syncrow_web/pages/analytics/modules/energy_management/widgets/power_clamp_energy_data_widget.dart';
|
||||||
@ -28,6 +29,12 @@ class _AnalyticsEnergyManagementViewState
|
|||||||
_loadTotalEnergyConsumption();
|
_loadTotalEnergyConsumption();
|
||||||
_loadEnergyConsumptionPerDevice();
|
_loadEnergyConsumptionPerDevice();
|
||||||
_loadPowerClampInfo();
|
_loadPowerClampInfo();
|
||||||
|
|
||||||
|
context.read<RealtimeDeviceChangesBloc>().add(
|
||||||
|
const RealtimeDeviceChangesStarted(
|
||||||
|
'cb71d6ad-6e29-4eaa-ae3e-1a0d1c5f60fa',
|
||||||
|
),
|
||||||
|
);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,11 @@ class PowerClampEnergyDataWidget extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocListener<RealtimeDeviceChangesBloc, RealtimeDeviceChangesState>(
|
return BlocListener<RealtimeDeviceChangesBloc, RealtimeDeviceChangesState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
context.read<PowerClampInfoBloc>().add(
|
if (state.status != RealtimeDeviceChangesStatus.loaded) {
|
||||||
UpdatePowerClampStatusEvent(state.deviceStatusList),
|
context.read<PowerClampInfoBloc>().add(
|
||||||
);
|
UpdatePowerClampStatusEvent(state.deviceStatusList),
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: BlocBuilder<PowerClampInfoBloc, PowerClampInfoState>(
|
child: BlocBuilder<PowerClampInfoBloc, PowerClampInfoState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
@ -4,7 +4,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sta
|
|||||||
|
|
||||||
class FirebaseRealtimeDeviceService implements RealtimeDeviceService {
|
class FirebaseRealtimeDeviceService implements RealtimeDeviceService {
|
||||||
@override
|
@override
|
||||||
Stream<Status> subscribe(String deviceId) {
|
Stream<List<Status>> subscribe(String deviceId) {
|
||||||
try {
|
try {
|
||||||
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
final ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
|
||||||
|
|
||||||
@ -15,11 +15,17 @@ class FirebaseRealtimeDeviceService implements RealtimeDeviceService {
|
|||||||
throw Exception('Invalid data received from Firebase');
|
throw Exception('Invalid data received from Firebase');
|
||||||
}
|
}
|
||||||
|
|
||||||
final statusMap = data['status'] as Map<dynamic, dynamic>;
|
final statusMap = data['status'] as List<dynamic>;
|
||||||
return Status(
|
return statusMap.map((dynamic status) {
|
||||||
code: statusMap['code'] as String? ?? '',
|
if (status is! Map<dynamic, dynamic>) {
|
||||||
value: statusMap['value'] as String? ?? '',
|
throw Exception('Invalid status format');
|
||||||
);
|
}
|
||||||
|
|
||||||
|
return Status(
|
||||||
|
code: status['code']?.toString() ?? '',
|
||||||
|
value: num.tryParse(status['value']?.toString() ?? '0') ,
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception('Error subscribing to device status: $e');
|
throw Exception('Error subscribing to device status: $e');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
abstract interface class RealtimeDeviceService {
|
abstract interface class RealtimeDeviceService {
|
||||||
Stream<Status> subscribe(String deviceId);
|
Stream<List<Status>> subscribe(String deviceId);
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
// PowerClampModel class to represent the response
|
// PowerClampModel class to represent the response
|
||||||
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||||
|
|
||||||
class PowerClampModel {
|
class PowerClampModel {
|
||||||
String productUuid;
|
String productUuid;
|
||||||
String productType;
|
String productType;
|
||||||
@ -46,11 +48,27 @@ class PowerStatus {
|
|||||||
|
|
||||||
factory PowerStatus.fromJson(Map<String, dynamic> json) {
|
factory PowerStatus.fromJson(Map<String, dynamic> json) {
|
||||||
return PowerStatus(
|
return PowerStatus(
|
||||||
phaseA: Phase.fromJson(json['phaseA']as List<dynamic>? ?? []),
|
phaseA: Phase.fromJson(json['phaseA'] as List<dynamic>? ?? []),
|
||||||
phaseB: Phase.fromJson(json['phaseB']as List<dynamic>? ?? []),
|
phaseB: Phase.fromJson(json['phaseB'] as List<dynamic>? ?? []),
|
||||||
phaseC: Phase.fromJson(json['phaseC']as List<dynamic>? ?? []),
|
phaseC: Phase.fromJson(json['phaseC'] as List<dynamic>? ?? []),
|
||||||
general: Phase.fromJson(json['general']as List<dynamic>? ?? []
|
general: Phase.fromJson(json['general'] as List<dynamic>? ?? []),
|
||||||
));
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory PowerStatus.fromStatusList(List<Status> statuses) {
|
||||||
|
List<DataPoint> extractPhase(String prefix) {
|
||||||
|
return statuses
|
||||||
|
.where((s) => s.code.endsWith(prefix))
|
||||||
|
.map((s) => DataPoint(code: s.code, value: s.value))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PowerStatus(
|
||||||
|
phaseA: Phase(dataPoints: extractPhase('A')),
|
||||||
|
phaseB: Phase(dataPoints: extractPhase('B')),
|
||||||
|
phaseC: Phase(dataPoints: extractPhase('C')),
|
||||||
|
general: Phase(dataPoints: extractPhase('')),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user