diff options
-rw-r--r-- | lib/core/constants/vss_path.dart | 8 | ||||
-rw-r--r-- | lib/data/data_providers/vehicle_notifier.dart | 42 | ||||
-rw-r--r-- | lib/data/models/vehicle.dart | 41 | ||||
-rw-r--r-- | lib/presentation/screens/hvac/hvac_content.dart | 12 | ||||
-rw-r--r-- | lib/presentation/screens/hvac/widgets/temperature_control.dart | 96 |
5 files changed, 167 insertions, 32 deletions
diff --git a/lib/core/constants/vss_path.dart b/lib/core/constants/vss_path.dart index 92c036f..236287f 100644 --- a/lib/core/constants/vss_path.dart +++ b/lib/core/constants/vss_path.dart @@ -33,6 +33,10 @@ class VSSPath { 'Vehicle.Cabin.HVAC.IsRecirculationActive'; static const String vehicleFanSpeed = 'Vehicle.Cabin.HVAC.Station.Row1.Driver.FanSpeed'; + static const String vehicleDriverTemperature = + 'Vehicle.Cabin.HVAC.Station.Row1.Driver.Temperature'; + static const String vehiclePassengerTemperature = + 'Vehicle.Cabin.HVAC.Station.Row1.Passenger.Temperature'; List<String> getSignalsList() { return const [ @@ -53,7 +57,9 @@ class VSSPath { vehicleIsFrontDefrosterActive, vehicleIsRearDefrosterActive, vehicleIsRecirculationActive, - vehicleFanSpeed + vehicleFanSpeed, + vehicleDriverTemperature, + vehiclePassengerTemperature, ]; } } diff --git a/lib/data/data_providers/vehicle_notifier.dart b/lib/data/data_providers/vehicle_notifier.dart index fb69595..b9a543c 100644 --- a/lib/data/data_providers/vehicle_notifier.dart +++ b/lib/data/data_providers/vehicle_notifier.dart @@ -136,7 +136,17 @@ class VehicleNotifier extends StateNotifier<Vehicle> { state = state.copyWith(fanSpeed: update.entry.value.uint32); } break; - + case VSSPath.vehicleDriverTemperature: + if (update.entry.value.hasInt32()) { + state = state.copyWith(driverTemperature: update.entry.value.int32); + } + break; + case VSSPath.vehiclePassengerTemperature: + if (update.entry.value.hasInt32()) { + state = + state.copyWith(passengerTemperature: update.entry.value.int32); + } + break; // default: // debugPrint("ERROR: Unexpected path ${update.entry.path}"); // break; @@ -302,7 +312,6 @@ class VehicleNotifier extends StateNotifier<Vehicle> { }, onError: (stacktrace, errorDescriptor) { debugPrint(stacktrace.toString()); state = const Vehicle.initialForDebug(); - }); } catch (e) { debugPrint(e.toString()); @@ -340,6 +349,35 @@ class VehicleNotifier extends StateNotifier<Vehicle> { } } + void setTemperature({required Side side, required int value}) { + var helper = ValClientHelper(channel: channel, stub: stub); + try { + switch (side) { + case Side.left: + helper.setInt32( + VSSPath.vehicleDriverTemperature, + value, + false, + ); + state = state.copyWith(driverTemperature: value); + break; + case Side.right: + helper.setInt32( + VSSPath.vehiclePassengerTemperature, + value, + false, + ); + state = state.copyWith(passengerTemperature: value); + break; + default: + debugPrint("ERROR: Unexpected side value $side}"); + break; + } + } catch (e) { + debugPrint(e.toString()); + } + } + void updateFanSpeed(int newValue) { state = state.copyWith(fanSpeed: newValue); } diff --git a/lib/data/models/vehicle.dart b/lib/data/models/vehicle.dart index adc6fc2..16752d3 100644 --- a/lib/data/models/vehicle.dart +++ b/lib/data/models/vehicle.dart @@ -22,6 +22,8 @@ class Vehicle { final bool isRearDefrosterActive; final bool isRecirculationActive; final int fanSpeed; + final int driverTemperature; + final int passengerTemperature; const Vehicle( this.speed, @@ -41,7 +43,10 @@ class Vehicle { this.isFrontDefrosterActive, this.isRearDefrosterActive, this.isRecirculationActive, - this.fanSpeed); + this.fanSpeed, + this.driverTemperature, + this.passengerTemperature, + ); const Vehicle.initial() : speed = 0, @@ -61,7 +66,9 @@ class Vehicle { isFrontDefrosterActive = false, isRearDefrosterActive = false, isRecirculationActive = false, - fanSpeed = 0; + fanSpeed = 0, + driverTemperature = 26, + passengerTemperature = 26; const Vehicle.initialForDebug() : speed = 60, @@ -81,7 +88,9 @@ class Vehicle { isFrontDefrosterActive = false, isRearDefrosterActive = false, isRecirculationActive = false, - fanSpeed = 0; + fanSpeed = 0, + driverTemperature = 26, + passengerTemperature = 26; Vehicle copyWith( {double? speed, @@ -101,7 +110,10 @@ class Vehicle { bool? isFrontDefrosterActive, bool? isRearDefrosterActive, bool? isRecirculationActive, - int? fanSpeed}) { + int? fanSpeed, + int? driverTemperature, + int? passengerTemperature, + }) { return Vehicle( speed ?? this.speed, insideTemperature ?? this.insideTemperature, @@ -120,7 +132,10 @@ class Vehicle { isFrontDefrosterActive ?? this.isFrontDefrosterActive, isRearDefrosterActive ?? this.isRearDefrosterActive, isRecirculationActive ?? this.isRecirculationActive, - fanSpeed ?? this.fanSpeed); + fanSpeed ?? this.fanSpeed, + driverTemperature ?? this.driverTemperature, + passengerTemperature ?? this.passengerTemperature, + ); } Map<String, dynamic> toMap() { @@ -142,7 +157,9 @@ class Vehicle { 'isFrontDefrosterActive': isFrontDefrosterActive, 'isRearDefrosterActive': isRearDefrosterActive, 'isRecirculationActive': isRecirculationActive, - 'fanSpeed': fanSpeed + 'fanSpeed': fanSpeed, + 'driverTemperature': driverTemperature, + 'passengerTemperature': passengerTemperature, }; } @@ -166,6 +183,8 @@ class Vehicle { map['isRearDefrosterActive'] ?? false, map['isRecirculationActive'] ?? false, map['fanSpeed'] ?? 0, + map['driverTemperature'] ?? 0, + map['passengerTemperature'] ?? 0, ); } @@ -176,7 +195,7 @@ class Vehicle { @override String toString() { - return 'Vehicle(speed: $speed, insideTemperature: $insideTemperature, outsideTemperature: $outsideTemperature, range: $range, fuelLevel: $fuelLevel, mediaVolume: $mediaVolume, isChildLockActiveLeft: $isChildLockActiveLeft, isChildLockActiveRight: $isChildLockActiveRight, engineSpeed: $engineSpeed, frontLeftTire: $frontLeftTire, frontRightTire: $frontRightTire, rearLeftTire: $rearLeftTire, rearRightTire: $rearRightTire, isAirConditioningActive: $isAirConditioningActive, isFrontDefrosterActive: $isFrontDefrosterActive, isRearDefrosterActive: $isRearDefrosterActive, isRecirculationActive: $isRecirculationActive,fanSpeed:$fanSpeed)'; + return 'Vehicle(speed: $speed, insideTemperature: $insideTemperature, outsideTemperature: $outsideTemperature, range: $range, fuelLevel: $fuelLevel, mediaVolume: $mediaVolume, isChildLockActiveLeft: $isChildLockActiveLeft, isChildLockActiveRight: $isChildLockActiveRight, engineSpeed: $engineSpeed, frontLeftTire: $frontLeftTire, frontRightTire: $frontRightTire, rearLeftTire: $rearLeftTire, rearRightTire: $rearRightTire, isAirConditioningActive: $isAirConditioningActive, isFrontDefrosterActive: $isFrontDefrosterActive, isRearDefrosterActive: $isRearDefrosterActive, isRecirculationActive: $isRecirculationActive,fanSpeed:$fanSpeed,driverTemperature:$driverTemperature, passengerTemperature:$passengerTemperature)'; } @override @@ -201,7 +220,9 @@ class Vehicle { other.isFrontDefrosterActive == isFrontDefrosterActive && other.isRearDefrosterActive == isRearDefrosterActive && other.isRecirculationActive == isRecirculationActive && - other.fanSpeed == fanSpeed; + other.fanSpeed == fanSpeed && + other.driverTemperature == driverTemperature && + other.passengerTemperature == passengerTemperature; } @override @@ -223,7 +244,9 @@ class Vehicle { isFrontDefrosterActive.hashCode ^ isRearDefrosterActive.hashCode ^ isRecirculationActive.hashCode ^ - fanSpeed.hashCode; + fanSpeed.hashCode ^ + driverTemperature.hashCode ^ + passengerTemperature.hashCode; } // } // / class VehicleNotifier extends StateNotifier<Vehicle> { diff --git a/lib/presentation/screens/hvac/hvac_content.dart b/lib/presentation/screens/hvac/hvac_content.dart index f79ec14..73fd439 100644 --- a/lib/presentation/screens/hvac/hvac_content.dart +++ b/lib/presentation/screens/hvac/hvac_content.dart @@ -58,6 +58,8 @@ class HVACState extends ConsumerState<HVAC> { isRearDefrostSelected = vehicle.isRearDefrosterActive; isRecirculationSelected = vehicle.isRecirculationActive; Size size = MediaQuery.sizeOf(context); + temperatureLeft = vehicle.driverTemperature; + temperatureRight = vehicle.passengerTemperature; return Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -153,8 +155,14 @@ class HVACState extends ConsumerState<HVAC> { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - TemperatureControl(temperature: temperatureLeft), - TemperatureControl(temperature: temperatureRight) + TemperatureControl( + temperature: temperatureLeft, + side: Side.left, + ), + TemperatureControl( + temperature: temperatureRight, + side: Side.right, + ) ], ), const SizedBox( diff --git a/lib/presentation/screens/hvac/widgets/temperature_control.dart b/lib/presentation/screens/hvac/widgets/temperature_control.dart index df83840..77d6dbc 100644 --- a/lib/presentation/screens/hvac/widgets/temperature_control.dart +++ b/lib/presentation/screens/hvac/widgets/temperature_control.dart @@ -1,14 +1,21 @@ +import 'dart:async'; + import 'package:flutter_ics_homescreen/export.dart'; -class TemperatureControl extends StatefulWidget { - const TemperatureControl({super.key, required this.temperature}); +enum Side { left, right } + +class TemperatureControl extends ConsumerStatefulWidget { + const TemperatureControl( + {super.key, required this.temperature, required this.side}); final int temperature; + final Side side; @override - State<TemperatureControl> createState() => _TemperatureControlState(); + TemperatureControlState createState() => TemperatureControlState(); } -class _TemperatureControlState extends State<TemperatureControl> { +class TemperatureControlState extends ConsumerState<TemperatureControl> { + late Timer tempButtonTimer; int temperature = 0; bool isUpButtonHighlighted = false; bool isDownButtonHighlighted = false; @@ -21,19 +28,40 @@ class _TemperatureControlState extends State<TemperatureControl> { }); } - onPressed({required String type}) { + onPressed({required String type, required Side side}) { setState(() { if (type == "add") { temperature = temperature + 1; } else if (type == "subtract") { temperature = temperature - 1; } + // limit the temperature to 60-100F + if (temperature <= 15) { + temperature = 15; + } else if (temperature >= 38) { + temperature = 38; + } + if (widget.side == Side.left) { + ref + .read(vehicleProvider.notifier) + .setTemperature(side: Side.left, value: temperature); + } else { + ref + .read(vehicleProvider.notifier) + .setTemperature(side: Side.right, value: temperature); + } }); } @override Widget build(BuildContext context) { - double iconSize = 32; + //final temperature = ref.watch(vehicleProvider.select((vehicle) => vehicle)); + // final outsideTemperature = ref + // .watch(vehicleProvider.select((vehicle) => vehicle.outsideTemperature)); + final tempUnit = + ref.watch(unitStateProvider.select((unit) => unit.temperatureUnit)); + + //double iconSize = 32; double height = MediaQuery.sizeOf(context).height * 0.0417; double width = MediaQuery.sizeOf(context).width * 0.2112; @@ -41,15 +69,29 @@ class _TemperatureControlState extends State<TemperatureControl> { children: [ Material( color: Colors.transparent, - child: InkWell( - onHighlightChanged: (value) { - setState(() { - isUpButtonHighlighted = value; + child: GestureDetector( + onTapDown: (value) { + isUpButtonHighlighted = !isUpButtonHighlighted; + onPressed(type: "add", side: widget.side); + }, + onTapUp: (detail) { + isUpButtonHighlighted = !isUpButtonHighlighted; + setState(() {}); + }, + onLongPress: () { + tempButtonTimer = + Timer.periodic(const Duration(milliseconds: 500), (timer) { + onPressed(type: "add", side: widget.side); }); }, - onTap: () { - onPressed(type: "add"); + onLongPressEnd: (details) { + setState(() { + isUpButtonHighlighted = !isUpButtonHighlighted; + + tempButtonTimer.cancel(); + }); }, + child: SizedBox( height: height, width: width, @@ -120,21 +162,39 @@ class _TemperatureControlState extends State<TemperatureControl> { Padding( padding: const EdgeInsets.symmetric(vertical: 10), child: Text( - "$temperature°C", + tempUnit == TemperatureUnit.celsius + ? '$temperature°C' + : '${((temperature * 9 / 5) + 32).toStringAsFixed(0)}°F', //converting from celsius. Step F unit = 2 style: GoogleFonts.brunoAce(fontSize: 44, height: 1.25), ), ), Material( color: Colors.transparent, - child: InkWell( - onHighlightChanged: (value) { + child: GestureDetector( + onTapDown: (value) { + isDownButtonHighlighted = !isDownButtonHighlighted; + onPressed(type: "subtract", side: widget.side); + }, + onTapUp: (detail) { + setState(() { - isDownButtonHighlighted = value; + isDownButtonHighlighted = !isDownButtonHighlighted; }); }, - onTap: () { - onPressed(type: "subtract"); + onLongPress: () { + tempButtonTimer = + Timer.periodic(const Duration(milliseconds: 500), (timer) { + onPressed(type: "subtract", side: widget.side); + }); }, + onLongPressEnd: (details) { + setState(() { + isDownButtonHighlighted = !isDownButtonHighlighted; + + tempButtonTimer.cancel(); + }); + }, + child: SizedBox( height: height, width: width, |