mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-23 09:07:54 +00:00
power_clamp
This commit is contained in:
@@ -17,7 +17,7 @@ class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
|
|||||||
required this.PCId,
|
required this.PCId,
|
||||||
}) : super(const PowerClampState()) {
|
}) : super(const PowerClampState()) {
|
||||||
on<PowerClampInitial>(_fetchPowerClampInfo);
|
on<PowerClampInitial>(_fetchPowerClampInfo);
|
||||||
on<ReportLogsInitial>(fetchLogsForLastMonth);
|
// on<ReportLogsInitial>(fetchLogsForLastMonth);
|
||||||
on<FetchEnergyData>(_mapReportToEnergyData);
|
on<FetchEnergyData>(_mapReportToEnergyData);
|
||||||
on<SelectDateEvent>(selectTimeOfLinePassword);
|
on<SelectDateEvent>(selectTimeOfLinePassword);
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,6 @@ class PowerClampBloc extends Bloc<PowerClampEvent, PowerClampState> {
|
|||||||
var response = await DevicesAPI.getPowerClampStatus(PCId);
|
var response = await DevicesAPI.getPowerClampStatus(PCId);
|
||||||
PowerClampModel deviceStatus = PowerClampModel.fromJson(response);
|
PowerClampModel deviceStatus = PowerClampModel.fromJson(response);
|
||||||
emit(UpdateState(powerClampModel: deviceStatus));
|
emit(UpdateState(powerClampModel: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(PowerClampFailedState(errorMessage: e.toString()));
|
emit(PowerClampFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dar
|
|||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
import 'package:syncrow_app/generated/assets.dart';
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
import 'power_chart.dart';
|
import 'power_chart.dart';
|
||||||
|
|
||||||
class PowerClampCard extends StatelessWidget {
|
class PowerClampCard extends StatelessWidget {
|
||||||
@@ -22,6 +21,7 @@ class PowerClampCard extends StatelessWidget {
|
|||||||
final String? totalFactor;
|
final String? totalFactor;
|
||||||
final Widget? dateSwitcher;
|
final Widget? dateSwitcher;
|
||||||
final String? formattedDate;
|
final String? formattedDate;
|
||||||
|
final String? energyConsumption;
|
||||||
final Function()? selectDateEvent;
|
final Function()? selectDateEvent;
|
||||||
final List<EnergyData>? chartData;
|
final List<EnergyData>? chartData;
|
||||||
final BuildContext? context;
|
final BuildContext? context;
|
||||||
@@ -43,6 +43,8 @@ class PowerClampCard extends StatelessWidget {
|
|||||||
this.selectDateEvent,
|
this.selectDateEvent,
|
||||||
this.chartData,
|
this.chartData,
|
||||||
this.context,
|
this.context,
|
||||||
|
this. energyConsumption,
|
||||||
|
//nConsumption
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -68,7 +70,7 @@ class PowerClampCard extends StatelessWidget {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
BodyLarge(
|
BodyLarge(
|
||||||
text: totalVoltage!,
|
text: energyConsumption!,
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -6,13 +6,9 @@ import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_s
|
|||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
|
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
|
||||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_info_card.dart';
|
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_card.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
|
||||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
|
||||||
import 'package:syncrow_app/generated/assets.dart';
|
|
||||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
class PowerClampPage extends StatefulWidget {
|
class PowerClampPage extends StatefulWidget {
|
||||||
@@ -21,29 +17,32 @@ class PowerClampPage extends StatefulWidget {
|
|||||||
const PowerClampPage({super.key, this.device});
|
const PowerClampPage({super.key, this.device});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PowerClampPageState createState() => _PowerClampPageState();
|
State<PowerClampPage> createState() => _PowerClampPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PowerClampPageState extends State<PowerClampPage> {
|
class _PowerClampPageState extends State<PowerClampPage> {
|
||||||
final PageController _pageController = PageController();
|
final PageController _pageController = PageController();
|
||||||
int _currentPage = 0;
|
int _currentPage = 0;
|
||||||
final int _pageCount = 4;
|
static const int _pageCount = 4;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
// Add listener to update _currentPage when the page is changed
|
_pageController.addListener(_handlePageChange);
|
||||||
_pageController.addListener(() {
|
}
|
||||||
int nextPage = _pageController.page?.round() ?? 0;
|
|
||||||
if (_currentPage != nextPage) {
|
void _handlePageChange() {
|
||||||
setState(() {
|
int nextPage = _pageController.page?.round() ?? 0;
|
||||||
_currentPage = nextPage;
|
if (_currentPage != nextPage) {
|
||||||
});
|
setState(() {
|
||||||
}
|
_currentPage = nextPage;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_pageController.removeListener(_handlePageChange);
|
||||||
_pageController.dispose();
|
_pageController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@@ -57,57 +56,8 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
|||||||
..add(const PowerClampInitial()),
|
..add(const PowerClampInitial()),
|
||||||
child: BlocBuilder<PowerClampBloc, PowerClampState>(
|
child: BlocBuilder<PowerClampBloc, PowerClampState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final _blocProvider = BlocProvider.of<PowerClampBloc>(context);
|
final blocProvider = context.read<PowerClampBloc>();
|
||||||
PowerClampModel model = PowerClampModel(
|
PowerClampModel model = _initialPowerClampModel();
|
||||||
productType: '',
|
|
||||||
productUuid: '',
|
|
||||||
status: PowerStatus(
|
|
||||||
phaseA: Phase(
|
|
||||||
dataPoints: [
|
|
||||||
DataPoint(
|
|
||||||
code: '',
|
|
||||||
customName: '',
|
|
||||||
dpId: 0,
|
|
||||||
time: 0,
|
|
||||||
type: '',
|
|
||||||
value: 0),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
phaseB: Phase(
|
|
||||||
dataPoints: [
|
|
||||||
DataPoint(
|
|
||||||
code: '',
|
|
||||||
customName: '',
|
|
||||||
dpId: 0,
|
|
||||||
time: 0,
|
|
||||||
type: '',
|
|
||||||
value: 0),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
phaseC: Phase(
|
|
||||||
dataPoints: [
|
|
||||||
DataPoint(
|
|
||||||
code: '',
|
|
||||||
customName: '',
|
|
||||||
dpId: 0,
|
|
||||||
time: 0,
|
|
||||||
type: '',
|
|
||||||
value: 0),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
general: Phase(
|
|
||||||
dataPoints: [
|
|
||||||
DataPoint(
|
|
||||||
code: '',
|
|
||||||
customName: '',
|
|
||||||
dpId: 0,
|
|
||||||
time: 0,
|
|
||||||
type: '',
|
|
||||||
value: 0),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
List<EnergyData> chartData = [];
|
List<EnergyData> chartData = [];
|
||||||
|
|
||||||
if (state is UpdateState) {
|
if (state is UpdateState) {
|
||||||
@@ -115,386 +65,151 @@ class _PowerClampPageState extends State<PowerClampPage> {
|
|||||||
} else if (state is EnergyDataState) {
|
} else if (state is EnergyDataState) {
|
||||||
chartData = state.energyData;
|
chartData = state.energyData;
|
||||||
}
|
}
|
||||||
return state is PowerClampLoadingState
|
|
||||||
? const Center(
|
if (state is PowerClampLoadingState) {
|
||||||
child: DefaultContainer(
|
return const Center(
|
||||||
width: 50,
|
child: DefaultContainer(
|
||||||
height: 50,
|
width: 50,
|
||||||
child: CircularProgressIndicator()),
|
height: 50,
|
||||||
)
|
child: CircularProgressIndicator(),
|
||||||
: Column(
|
),
|
||||||
children: [
|
);
|
||||||
Flexible(
|
}
|
||||||
child: RefreshIndicator(
|
|
||||||
onRefresh: () async {
|
return Column(
|
||||||
_blocProvider.add(const PowerClampInitial());
|
children: [
|
||||||
},
|
Flexible(
|
||||||
child:
|
child: RefreshIndicator(
|
||||||
PageView(controller: _pageController, children: [
|
onRefresh: () async {
|
||||||
powerClampCard(
|
blocProvider.add(const PowerClampInitial());
|
||||||
title: 'Total Energy \nConsumption',
|
},
|
||||||
isGeneral: true,
|
child: PageView(
|
||||||
dateSwitcher: _blocProvider.dateSwitcher(),
|
controller: _pageController,
|
||||||
formattedDate: _blocProvider.formattedDate,
|
children:
|
||||||
selectDateEvent: () {
|
_buildPowerClampCards(model, chartData, blocProvider),
|
||||||
_blocProvider
|
),
|
||||||
.add(SelectDateEvent(context: context));
|
),
|
||||||
},
|
),
|
||||||
totalFrequencyGeneral: model
|
_buildPageIndicator(),
|
||||||
.status.general.dataPoints.isNotEmpty
|
],
|
||||||
? model.status.general.dataPoints[0].value
|
);
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalActiveGeneral:
|
|
||||||
model.status.general.dataPoints.length > 3
|
|
||||||
? model
|
|
||||||
.status.general.dataPoints[3].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalCurrentGeneral:
|
|
||||||
model.status.general.dataPoints.length > 2
|
|
||||||
? model
|
|
||||||
.status.general.dataPoints[2].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalVoltage:
|
|
||||||
model.status.general.dataPoints.length > 1
|
|
||||||
? model
|
|
||||||
.status.general.dataPoints[1].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
chartData: chartData,
|
|
||||||
context: context),
|
|
||||||
powerClampCard(
|
|
||||||
title: 'Phase A Energy \nConsumption',
|
|
||||||
dateSwitcher: _blocProvider.dateSwitcher(),
|
|
||||||
formattedDate: _blocProvider.formattedDate,
|
|
||||||
selectDateEvent: () {
|
|
||||||
_blocProvider.add(SelectDateEvent(context: context));
|
|
||||||
},
|
|
||||||
totalFactor: model
|
|
||||||
.status.phaseA.dataPoints.isNotEmpty
|
|
||||||
? model.status.phaseA.dataPoints[0].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalActive:
|
|
||||||
model.status.phaseA.dataPoints.length > 3
|
|
||||||
? model
|
|
||||||
.status.phaseA.dataPoints[3].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalCurrent:
|
|
||||||
model.status.phaseA.dataPoints.length > 1
|
|
||||||
? model
|
|
||||||
.status.phaseA.dataPoints[1].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalVoltage:
|
|
||||||
model.status.phaseA.dataPoints.length > 0
|
|
||||||
? model
|
|
||||||
.status.phaseA.dataPoints[0].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
chartData: chartData,
|
|
||||||
context: context),
|
|
||||||
powerClampCard(
|
|
||||||
title: 'Phase B Energy \nConsumption',
|
|
||||||
dateSwitcher: _blocProvider.dateSwitcher(),
|
|
||||||
formattedDate: _blocProvider.formattedDate,
|
|
||||||
selectDateEvent: () {
|
|
||||||
_blocProvider
|
|
||||||
.add(SelectDateEvent(context: context));
|
|
||||||
},
|
|
||||||
totalFactor: model
|
|
||||||
.status.phaseB.dataPoints.isNotEmpty
|
|
||||||
? model.status.phaseB.dataPoints[0].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalActive:
|
|
||||||
model.status.phaseB.dataPoints.length > 3
|
|
||||||
? model
|
|
||||||
.status.phaseB.dataPoints[3].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalCurrent:
|
|
||||||
model.status.phaseB.dataPoints.length > 2
|
|
||||||
? model
|
|
||||||
.status.phaseB.dataPoints[2].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalVoltage:
|
|
||||||
model.status.phaseB.dataPoints.length > 1
|
|
||||||
? model
|
|
||||||
.status.phaseB.dataPoints[1].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
chartData: chartData,
|
|
||||||
context: context),
|
|
||||||
powerClampCard(
|
|
||||||
title: 'Phase C Energy \nConsumption',
|
|
||||||
dateSwitcher: _blocProvider.dateSwitcher(),
|
|
||||||
formattedDate: _blocProvider.formattedDate,
|
|
||||||
selectDateEvent: () {
|
|
||||||
_blocProvider
|
|
||||||
.add(SelectDateEvent(context: context));
|
|
||||||
},
|
|
||||||
totalFactor: model
|
|
||||||
.status.phaseC.dataPoints.isNotEmpty
|
|
||||||
? model.status.phaseC.dataPoints[0].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalActive:
|
|
||||||
model.status.phaseC.dataPoints.length > 3
|
|
||||||
? model
|
|
||||||
.status.phaseC.dataPoints[3].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalCurrent:
|
|
||||||
model.status.phaseC.dataPoints.length > 2
|
|
||||||
? model
|
|
||||||
.status.phaseC.dataPoints[2].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
totalVoltage:
|
|
||||||
model.status.phaseC.dataPoints.length > 1
|
|
||||||
? model
|
|
||||||
.status.phaseC.dataPoints[1].value
|
|
||||||
.toString()
|
|
||||||
: 'N/A',
|
|
||||||
chartData: chartData,
|
|
||||||
context: context),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10.0),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: List.generate(_pageCount, (index) {
|
|
||||||
return AnimatedContainer(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
margin:
|
|
||||||
const EdgeInsets.symmetric(horizontal: 4.0),
|
|
||||||
height: 10.0,
|
|
||||||
width: _currentPage == index
|
|
||||||
? 20.0
|
|
||||||
: 10.0, // Change width for current page
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: _currentPage == index
|
|
||||||
? Colors
|
|
||||||
.grey // Use a different color for the active indicator
|
|
||||||
: ColorsManager.greyColor,
|
|
||||||
borderRadius: BorderRadius.circular(5.0),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultContainer powerClampCard(
|
PowerClampModel _initialPowerClampModel() {
|
||||||
{bool? isGeneral,
|
return PowerClampModel(
|
||||||
String? title,
|
productType: '',
|
||||||
String? totalCurrent,
|
productUuid: '',
|
||||||
String? totalActiveGeneral,
|
status: PowerStatus(
|
||||||
String? totalCurrentGeneral,
|
phaseA: Phase(dataPoints: _emptyDataPoints()),
|
||||||
String? totalFrequencyGeneral,
|
phaseB: Phase(dataPoints: _emptyDataPoints()),
|
||||||
String? totalVoltage,
|
phaseC: Phase(dataPoints: _emptyDataPoints()),
|
||||||
String? totalActive,
|
general: Phase(dataPoints: _emptyDataPoints()),
|
||||||
String? totalFrequency,
|
),
|
||||||
String? totalFactor,
|
);
|
||||||
Widget? dateSwitcher,
|
}
|
||||||
String? formattedDate,
|
|
||||||
Function()? selectDateEvent,
|
List<DataPoint> _emptyDataPoints() {
|
||||||
List<EnergyData>? chartData,
|
return [
|
||||||
BuildContext? context}) {
|
DataPoint(
|
||||||
return DefaultContainer(
|
code: '',
|
||||||
child: Padding(
|
customName: '',
|
||||||
padding:
|
dpId: 0,
|
||||||
const EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
|
time: 0,
|
||||||
child: Column(
|
type: '',
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
value: 0,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
),
|
||||||
children: [
|
];
|
||||||
Text('Energy usage'),
|
}
|
||||||
Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
List<Widget> _buildPowerClampCards(PowerClampModel model,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
List<EnergyData> chartData, PowerClampBloc blocProvider) {
|
||||||
children: [
|
return [
|
||||||
BodyLarge(
|
_buildPowerClampCard(
|
||||||
text: title!,
|
title: 'Total Energy \nConsumption',
|
||||||
// 'Total Energy \nConsumption',
|
phase: model.status.general,
|
||||||
fontSize: 20,
|
isGeneral: true,
|
||||||
fontWeight: FontWeight.w700,
|
chartData: chartData,
|
||||||
),
|
blocProvider: blocProvider,
|
||||||
Row(
|
),
|
||||||
children: [
|
_buildPowerClampCard(
|
||||||
BodyLarge(
|
title: 'Phase A Energy \nConsumption',
|
||||||
text: totalVoltage!,
|
phase: model.status.phaseA,
|
||||||
fontSize: 20,
|
chartData: chartData,
|
||||||
fontWeight: FontWeight.w700,
|
blocProvider: blocProvider,
|
||||||
),
|
),
|
||||||
BodySmall(text: 'kWh')
|
_buildPowerClampCard(
|
||||||
],
|
title: 'Phase B Energy \nConsumption',
|
||||||
),
|
phase: model.status.phaseB,
|
||||||
],
|
chartData: chartData,
|
||||||
),
|
blocProvider: blocProvider,
|
||||||
const SizedBox(
|
),
|
||||||
height: 20,
|
_buildPowerClampCard(
|
||||||
),
|
title: 'Phase C Energy \nConsumption',
|
||||||
isGeneral == true
|
phase: model.status.phaseC,
|
||||||
? Row(
|
chartData: chartData,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
blocProvider: blocProvider,
|
||||||
children: [
|
),
|
||||||
PowerClampInfoCard(
|
];
|
||||||
iconPath: Assets.powerActiveIcon,
|
}
|
||||||
title: 'Active',
|
|
||||||
value: '$totalActiveGeneral',
|
Widget _buildPowerClampCard({
|
||||||
unit: ' w',
|
required String title,
|
||||||
),
|
required Phase phase,
|
||||||
PowerClampInfoCard(
|
bool isGeneral = false,
|
||||||
iconPath: Assets.voltMeterIcon,
|
required List<EnergyData> chartData,
|
||||||
title: 'Current',
|
required PowerClampBloc blocProvider,
|
||||||
value: '$totalCurrentGeneral',
|
}) {
|
||||||
unit: ' A',
|
return PowerClampCard(
|
||||||
),
|
energyConsumption: _getValueOrNA(phase.dataPoints, isGeneral ? 0 : 5),
|
||||||
PowerClampInfoCard(
|
title: title,
|
||||||
iconPath: Assets.frequencyIcon,
|
isGeneral: isGeneral,
|
||||||
title: 'Frequency',
|
dateSwitcher: blocProvider.dateSwitcher(),
|
||||||
value: '$totalFrequencyGeneral',
|
formattedDate: blocProvider.formattedDate,
|
||||||
unit: ' Hz',
|
selectDateEvent: () {
|
||||||
),
|
blocProvider.add(SelectDateEvent(context: context));
|
||||||
],
|
},
|
||||||
)
|
totalActiveGeneral: isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
|
||||||
: Column(
|
totalCurrentGeneral:
|
||||||
children: [
|
isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||||
Row(
|
totalFrequencyGeneral:
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
isGeneral ? _getValueOrNA(phase.dataPoints, 4) : null,
|
||||||
children: [
|
totalFactor: !isGeneral ? _getValueOrNA(phase.dataPoints, 3) : null,
|
||||||
PowerClampInfoCard(
|
totalActive: !isGeneral ? _getValueOrNA(phase.dataPoints, 2) : null,
|
||||||
iconPath: Assets.voltageIcon,
|
totalCurrent: !isGeneral ? _getValueOrNA(phase.dataPoints, 1) : null,
|
||||||
title: 'Voltage',
|
totalVoltage: !isGeneral ? _getValueOrNA(phase.dataPoints, 0) : null,
|
||||||
value: totalVoltage,
|
chartData: chartData,
|
||||||
unit: ' V',
|
context: context,
|
||||||
),
|
);
|
||||||
PowerClampInfoCard(
|
}
|
||||||
iconPath: Assets.voltMeterIcon,
|
|
||||||
title: 'Current',
|
String _getValueOrNA(List<DataPoint> dataPoints, int index) {
|
||||||
value: '$totalCurrent',
|
return dataPoints.length > index
|
||||||
unit: ' A',
|
? dataPoints[index].value.toString()
|
||||||
),
|
: 'N/A';
|
||||||
],
|
}
|
||||||
),
|
|
||||||
Row(
|
Widget _buildPageIndicator() {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
return Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(vertical: 10.0),
|
||||||
PowerClampInfoCard(
|
child: Row(
|
||||||
iconPath: Assets.powerActiveIcon,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
title: 'Active Power',
|
children: List.generate(_pageCount, (index) {
|
||||||
value: '$totalActive',
|
return AnimatedContainer(
|
||||||
unit: ' w',
|
duration: const Duration(milliseconds: 300),
|
||||||
),
|
margin: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
PowerClampInfoCard(
|
height: 10.0,
|
||||||
iconPath: Assets.speedoMeter,
|
width: _currentPage == index ? 10.0 : 10.0,
|
||||||
title: 'Power Factor',
|
decoration: BoxDecoration(
|
||||||
value: '$totalFactor',
|
color:
|
||||||
unit: '',
|
_currentPage == index ? Colors.grey : ColorsManager.greyColor,
|
||||||
),
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
],
|
),
|
||||||
)
|
);
|
||||||
],
|
}),
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
const Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
BodyMedium(
|
|
||||||
text: 'Total consumption',
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'10/08/2024',
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 8, fontWeight: FontWeight.w400),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
BodyMedium(
|
|
||||||
text: '1000.00 ',
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w700),
|
|
||||||
BodyMedium(
|
|
||||||
text: 'kWh',
|
|
||||||
fontSize: 8,
|
|
||||||
fontWeight: FontWeight.w700),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 290,
|
|
||||||
child: EnergyConsumptionPage(
|
|
||||||
chartData: chartData!.isNotEmpty
|
|
||||||
? chartData
|
|
||||||
: [
|
|
||||||
EnergyData('12:00 AM', 4.0),
|
|
||||||
EnergyData('01:00 AM', 3.5),
|
|
||||||
EnergyData('02:00 AM', 3.8),
|
|
||||||
EnergyData('03:00 AM', 3.2),
|
|
||||||
EnergyData('04: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:
|
|
||||||
chartData.fold(0, (sum, data) => sum + data.consumption),
|
|
||||||
date: '10/08/2024',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 5,
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
DefaultContainer(
|
|
||||||
padding: EdgeInsets.all(0),
|
|
||||||
color: ColorsManager.grayBox,
|
|
||||||
child: SizedBox(
|
|
||||||
child: dateSwitcher,
|
|
||||||
)),
|
|
||||||
InkWell(
|
|
||||||
onTap: selectDateEvent,
|
|
||||||
child: DefaultContainer(
|
|
||||||
color: ColorsManager.grayBox,
|
|
||||||
child: SizedBox(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(5),
|
|
||||||
child: Text(formattedDate!),
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,312 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_bloc.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_event.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/bloc/power_clamp_bloc/power_clamp_state.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/power_clamp_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_chart.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_card.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||||
|
|
||||||
|
class PowerClampTestPage extends StatefulWidget {
|
||||||
|
late final DeviceModel? device;
|
||||||
|
|
||||||
|
PowerClampTestPage({super.key, this.device});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_PowerClampTestPageState createState() => _PowerClampTestPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PowerClampTestPageState extends State<PowerClampTestPage> {
|
||||||
|
final PageController _pageController = PageController();
|
||||||
|
int _currentPage = 0;
|
||||||
|
final int _pageCount = 4;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_pageController.addListener(() {
|
||||||
|
int nextPage = _pageController.page?.round() ?? 0;
|
||||||
|
if (_currentPage != nextPage) {
|
||||||
|
setState(() {
|
||||||
|
_currentPage = nextPage;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_pageController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultScaffold(
|
||||||
|
title: 'Power Clamp',
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) => PowerClampBloc(PCId: widget.device?.uuid ?? '')
|
||||||
|
..add(const PowerClampInitial()),
|
||||||
|
child: BlocBuilder<PowerClampBloc, PowerClampState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final _blocProvider = BlocProvider.of<PowerClampBloc>(context);
|
||||||
|
PowerClampModel model = PowerClampModel(
|
||||||
|
productType: '',
|
||||||
|
productUuid: '',
|
||||||
|
status: PowerStatus(
|
||||||
|
phaseA: Phase(
|
||||||
|
dataPoints: [
|
||||||
|
DataPoint(
|
||||||
|
code: '',
|
||||||
|
customName: '',
|
||||||
|
dpId: 0,
|
||||||
|
time: 0,
|
||||||
|
type: '',
|
||||||
|
value: 0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
phaseB: Phase(
|
||||||
|
dataPoints: [
|
||||||
|
DataPoint(
|
||||||
|
code: '',
|
||||||
|
customName: '',
|
||||||
|
dpId: 0,
|
||||||
|
time: 0,
|
||||||
|
type: '',
|
||||||
|
value: 0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
phaseC: Phase(
|
||||||
|
dataPoints: [
|
||||||
|
DataPoint(
|
||||||
|
code: '',
|
||||||
|
customName: '',
|
||||||
|
dpId: 0,
|
||||||
|
time: 0,
|
||||||
|
type: '',
|
||||||
|
value: 0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
general: Phase(
|
||||||
|
dataPoints: [
|
||||||
|
DataPoint(
|
||||||
|
code: '',
|
||||||
|
customName: '',
|
||||||
|
dpId: 0,
|
||||||
|
time: 0,
|
||||||
|
type: '',
|
||||||
|
value: 0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
List<EnergyData> chartData = [];
|
||||||
|
|
||||||
|
if (state is UpdateState) {
|
||||||
|
model = state.powerClampModel;
|
||||||
|
} else if (state is EnergyDataState) {
|
||||||
|
chartData = state.energyData;
|
||||||
|
}
|
||||||
|
return state is PowerClampLoadingState
|
||||||
|
? const Center(
|
||||||
|
child: DefaultContainer(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
child: CircularProgressIndicator()),
|
||||||
|
)
|
||||||
|
: Column(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
_blocProvider.add(const PowerClampInitial());
|
||||||
|
},
|
||||||
|
child: PageView(
|
||||||
|
controller: _pageController,
|
||||||
|
children: [
|
||||||
|
PowerClampCard(
|
||||||
|
energyConsumption:
|
||||||
|
model.status.general.dataPoints.length > 0
|
||||||
|
? model.status.general.dataPoints[0].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
title: 'Total Energy \nConsumption',
|
||||||
|
isGeneral: true,
|
||||||
|
dateSwitcher: _blocProvider.dateSwitcher(),
|
||||||
|
formattedDate: _blocProvider.formattedDate,
|
||||||
|
selectDateEvent: () {
|
||||||
|
_blocProvider.add(
|
||||||
|
SelectDateEvent(context: context));
|
||||||
|
},
|
||||||
|
totalFrequencyGeneral:
|
||||||
|
model.status.general.dataPoints.length > 4
|
||||||
|
? model.status.general.dataPoints[4].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalActiveGeneral:
|
||||||
|
model.status.general.dataPoints.length > 2
|
||||||
|
? model.status.general.dataPoints[2].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalCurrentGeneral:
|
||||||
|
model.status.general.dataPoints.length > 1
|
||||||
|
? model.status.general.dataPoints[1].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalVoltage:
|
||||||
|
model.status.general.dataPoints.length > 0
|
||||||
|
? model.status.general.dataPoints[0].value.toString()
|
||||||
|
: 'N/A',
|
||||||
|
chartData: chartData,
|
||||||
|
context: context),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PowerClampCard(
|
||||||
|
energyConsumption:
|
||||||
|
model.status.phaseA.dataPoints.length > 5
|
||||||
|
? model.status.phaseA.dataPoints[5].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
title: 'Phase A Energy \nConsumption',
|
||||||
|
dateSwitcher: _blocProvider.dateSwitcher(),
|
||||||
|
formattedDate: _blocProvider.formattedDate,
|
||||||
|
selectDateEvent: () {
|
||||||
|
_blocProvider.add(
|
||||||
|
SelectDateEvent(context: context));
|
||||||
|
},
|
||||||
|
totalFactor: model.status.phaseA.dataPoints.length > 3
|
||||||
|
? model.status.phaseA.dataPoints[3].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalActive: model.status.phaseA.dataPoints.length > 2
|
||||||
|
? model.status.phaseA.dataPoints[2].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalCurrent:
|
||||||
|
model.status.phaseA.dataPoints.length > 1
|
||||||
|
? model.status.phaseA.dataPoints[1]
|
||||||
|
.value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalVoltage:
|
||||||
|
model.status.phaseA.dataPoints.length > 0
|
||||||
|
? model.status.phaseA.dataPoints[0]
|
||||||
|
.value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
chartData: chartData,
|
||||||
|
context: context),
|
||||||
|
|
||||||
|
|
||||||
|
PowerClampCard(
|
||||||
|
energyConsumption:
|
||||||
|
model.status.phaseB.dataPoints.length > 5
|
||||||
|
? model.status.phaseB.dataPoints[5].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
title: 'Phase B Energy \nConsumption',
|
||||||
|
dateSwitcher: _blocProvider.dateSwitcher(),
|
||||||
|
formattedDate: _blocProvider.formattedDate,
|
||||||
|
selectDateEvent: () {
|
||||||
|
_blocProvider.add(
|
||||||
|
SelectDateEvent(context: context));
|
||||||
|
},
|
||||||
|
totalFactor: model.status.phaseA.dataPoints.length > 3
|
||||||
|
? model.status.phaseB.dataPoints[3].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalActive: model.status.phaseB.dataPoints.length > 2
|
||||||
|
? model.status.phaseB.dataPoints[2].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalCurrent:
|
||||||
|
model.status.phaseB.dataPoints.length > 1
|
||||||
|
? model.status.phaseB.dataPoints[1]
|
||||||
|
.value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalVoltage:
|
||||||
|
model.status.phaseB.dataPoints.length > 0
|
||||||
|
? model.status.phaseB.dataPoints[0]
|
||||||
|
.value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
chartData: chartData,
|
||||||
|
context: context),
|
||||||
|
|
||||||
|
|
||||||
|
PowerClampCard(
|
||||||
|
energyConsumption:
|
||||||
|
model.status.phaseC.dataPoints.length > 5
|
||||||
|
? model.status.phaseC.dataPoints[5].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
title: 'Phase A Energy \nConsumption',
|
||||||
|
dateSwitcher: _blocProvider.dateSwitcher(),
|
||||||
|
formattedDate: _blocProvider.formattedDate,
|
||||||
|
selectDateEvent: () {
|
||||||
|
_blocProvider.add(
|
||||||
|
SelectDateEvent(context: context));
|
||||||
|
},
|
||||||
|
totalFactor: model.status.phaseC.dataPoints.length > 3
|
||||||
|
? model.status.phaseC.dataPoints[3].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalActive: model.status.phaseC.dataPoints.length > 2
|
||||||
|
? model.status.phaseC.dataPoints[2].value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalCurrent:
|
||||||
|
model.status.phaseC.dataPoints.length > 1
|
||||||
|
? model.status.phaseC.dataPoints[1]
|
||||||
|
.value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
totalVoltage:
|
||||||
|
model.status.phaseC.dataPoints.length > 0
|
||||||
|
? model.status.phaseC.dataPoints[0]
|
||||||
|
.value
|
||||||
|
.toString()
|
||||||
|
: 'N/A',
|
||||||
|
chartData: chartData,
|
||||||
|
context: context),
|
||||||
|
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: List.generate(_pageCount, (index) {
|
||||||
|
return AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
margin:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
|
height: 10.0,
|
||||||
|
width: _currentPage == index
|
||||||
|
? 10.0
|
||||||
|
: 10.0, // Change width for current page
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _currentPage == index
|
||||||
|
? Colors
|
||||||
|
.grey // Use a different color for the active indicator
|
||||||
|
: ColorsManager.greyColor,
|
||||||
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user