mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-10-26 03:27:54 +00:00
static power clamp
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class EnergyConsumptionPage extends StatefulWidget {
|
||||
final List<dynamic> chartData;
|
||||
final double totalConsumption;
|
||||
final String date;
|
||||
|
||||
EnergyConsumptionPage({
|
||||
required this.chartData,
|
||||
required this.totalConsumption,
|
||||
required this.date,
|
||||
});
|
||||
|
||||
@override
|
||||
_EnergyConsumptionPageState createState() => _EnergyConsumptionPageState();
|
||||
}
|
||||
|
||||
class _EnergyConsumptionPageState extends State<EnergyConsumptionPage> {
|
||||
late List<dynamic> _chartData;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// Use the provided data
|
||||
_chartData = widget.chartData;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 19),
|
||||
child: LineChart(
|
||||
LineChartData(
|
||||
lineTouchData: LineTouchData(
|
||||
handleBuiltInTouches: true,
|
||||
touchSpotThreshold: 2,
|
||||
getTouchLineEnd: (barData, spotIndex) {
|
||||
return 10.0;
|
||||
},
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
getTooltipColor: (touchTooltipItem) => Colors.white,
|
||||
tooltipRoundedRadius: 10.0,
|
||||
tooltipPadding: const EdgeInsets.all(8.0),
|
||||
tooltipBorder: BorderSide(color: Colors.grey, width: 1),
|
||||
getTooltipItems: (List<LineBarSpot> touchedSpots) {
|
||||
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,
|
||||
getTitlesWidget: (value, meta) {
|
||||
int index = value.toInt();
|
||||
if (index >= 0 && index < _chartData.length) {
|
||||
return Text(_chartData[index].time,
|
||||
style: TextStyle(fontSize: 10));
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
),
|
||||
),
|
||||
rightTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: false,
|
||||
reservedSize: 40,
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Text(value.toStringAsFixed(1) + ' kWh',
|
||||
style: TextStyle(fontSize: 10));
|
||||
},
|
||||
),
|
||||
),
|
||||
topTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
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.blue.withOpacity(0.2),
|
||||
dashArray: [10, 10],
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.withOpacity(0.2),
|
||||
dashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
drawHorizontalLine: false,
|
||||
),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
|
||||
curveSmoothness: 0.5,
|
||||
preventCurveOverShooting: true,
|
||||
aboveBarData: BarAreaData(),
|
||||
spots: _chartData
|
||||
.asMap()
|
||||
.entries
|
||||
.map((entry) => FlSpot(
|
||||
entry.key.toDouble(), entry.value.consumption))
|
||||
.toList(),
|
||||
isCurved: true,
|
||||
color: ColorsManager.chart.withOpacity(0.6),
|
||||
show: true,
|
||||
shadow: Shadow(color: Colors.black12),
|
||||
belowBarData: BarAreaData(
|
||||
show: true,
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
ColorsManager.chart.withOpacity(0.5),
|
||||
Colors.blue.withOpacity(0.1),
|
||||
],
|
||||
begin: Alignment.center,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
dotData: FlDotData(
|
||||
show: false,
|
||||
),
|
||||
isStrokeCapRound: true,
|
||||
barWidth: 6,
|
||||
|
||||
),
|
||||
],
|
||||
borderData: FlBorderData(
|
||||
show: false,
|
||||
border: Border.all(
|
||||
color: Color(0xff023DFE).withOpacity(0.7),
|
||||
width: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EnergyData {
|
||||
EnergyData(this.time, this.consumption);
|
||||
final String time;
|
||||
final double consumption;
|
||||
}
|
||||
//
|
||||
@@ -0,0 +1,235 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/door_sensor_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_info_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/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';
|
||||
|
||||
class PowerClampPage extends StatefulWidget {
|
||||
final DeviceModel? device;
|
||||
|
||||
const PowerClampPage({super.key, this.device});
|
||||
|
||||
@override
|
||||
_PowerClampPageState createState() => _PowerClampPageState();
|
||||
}
|
||||
|
||||
class _PowerClampPageState extends State<PowerClampPage> {
|
||||
final PageController _pageController = PageController();
|
||||
int _currentPage = 0;
|
||||
final int _pageCount = 5;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultScaffold(
|
||||
title: 'Power Clamp',
|
||||
child: BlocProvider(
|
||||
create: (context) => DoorSensorBloc(DSId: widget.device?.uuid ?? '')
|
||||
..add(const DoorSensorInitial()),
|
||||
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||
builder: (context, state) {
|
||||
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
||||
DoorSensorModel model =
|
||||
DoorSensorModel(batteryPercentage: 0, doorContactState: false);
|
||||
if (state is LoadingNewSate) {
|
||||
model = state.doorSensor;
|
||||
} else if (state is UpdateState) {
|
||||
model = state.doorSensor;
|
||||
}
|
||||
return state is DoorSensorLoadingState
|
||||
? const Center(
|
||||
child: DefaultContainer(
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: CircularProgressIndicator()),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
doorSensorBloc.add(const DoorSensorInitial());
|
||||
},
|
||||
child: PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: (int page) {
|
||||
setState(() {
|
||||
_currentPage = page;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
return DefaultContainer(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 10, right: 10, top: 25, bottom: 20),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Energy usage'),
|
||||
Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyLarge(
|
||||
text: 'Total Energy \nConsumption',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
BodyLarge(
|
||||
text: '8623.20 ',
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
BodySmall(text: 'kWh')
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.powerActiveIcon,
|
||||
title: 'Active',
|
||||
value: '700',
|
||||
unit: ' w',
|
||||
),
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.voltMeterIcon,
|
||||
title: 'Current',
|
||||
value: '3.06',
|
||||
unit: ' A',
|
||||
),
|
||||
PowerClampInfoCard(
|
||||
iconPath: Assets.frequencyIcon,
|
||||
title: 'Frequency',
|
||||
value: '50',
|
||||
unit: ' Hz',
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
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: 310,
|
||||
child: EnergyConsumptionPage(
|
||||
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: 100.0,
|
||||
date: '10/08/2024',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: _pageCount,
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
decoration: BoxDecoration(
|
||||
color: _currentPage == index
|
||||
? Colors.grey
|
||||
: ColorsManager.greyColor,
|
||||
borderRadius: BorderRadius.circular(5.0),
|
||||
),
|
||||
child: Center(
|
||||
child: _currentPage == index
|
||||
? Text(
|
||||
'',
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
class PowerClampInfoCard extends StatelessWidget {
|
||||
final String iconPath;
|
||||
final String title;
|
||||
final String value;
|
||||
final String unit;
|
||||
|
||||
const PowerClampInfoCard({
|
||||
Key? key,
|
||||
required this.iconPath,
|
||||
required this.title,
|
||||
required this.value,
|
||||
required this.unit,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: DefaultContainer(
|
||||
height: 60,
|
||||
color: ColorsManager.grayBox,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: SvgPicture.asset(
|
||||
iconPath,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
BodyMedium(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 8,
|
||||
text: title,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
BodyMedium(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 15,
|
||||
text: value,
|
||||
),
|
||||
BodyMedium(
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 8,
|
||||
text: unit,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.d
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/one_touch/one_touch_screen.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/power_clamp/power_clamp_page.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/three_touch/three_touch_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_Interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/two_touch/two_touch_Interface.dart';
|
||||
@@ -163,12 +164,20 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
WaterHeaterPage(device: device)));
|
||||
case DeviceType.DS:
|
||||
// case DeviceType.DS:
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// PageRouteBuilder(
|
||||
// pageBuilder: (context, animation1, animation2) =>
|
||||
// DoorSensorScreen(device: device)));
|
||||
|
||||
|
||||
case DeviceType.DS:
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation1, animation2) =>
|
||||
DoorSensorScreen(device: device)));
|
||||
PowerClampPage(device: device)));
|
||||
|
||||
case DeviceType.OneTouch:
|
||||
Navigator.push(
|
||||
|
||||
Reference in New Issue
Block a user