diff --git a/lib/BlindMasterScreens/individualControl/peripheral_screen.dart b/lib/BlindMasterScreens/individualControl/peripheral_screen.dart index 5cec62d..989fbbd 100644 --- a/lib/BlindMasterScreens/individualControl/peripheral_screen.dart +++ b/lib/BlindMasterScreens/individualControl/peripheral_screen.dart @@ -32,6 +32,8 @@ class _PeripheralScreenState extends State { double _blindPosition = 5.0; DateTime? lastSet; String lastSetMessage = ""; + int? batterySoc; + bool _movementPending = false; final _peripheralRenameController = TextEditingController(); @@ -130,6 +132,7 @@ class _PeripheralScreenState extends State { if (!mounted) return; final type = data['type'] as String? ?? ''; final soc = data['soc'] as int? ?? 0; + setState(() => batterySoc = soc); final (String message, Color color) = switch (type) { 'overvoltage' => ('Battery fault detected. Please check your charger.', Colors.red), 'critical_low' => ('Battery critically low ($soc%). Device shutting down.', Colors.red), @@ -169,6 +172,7 @@ class _PeripheralScreenState extends State { if (!mounted) return; setState(() { _blindPosition = (data['pos'] as int).toDouble(); + _movementPending = false; }); } } @@ -341,6 +345,20 @@ class _PeripheralScreenState extends State { } } + Future getDeviceBatterySoc() async { + try { + final payload = {'deviceId': widget.deviceId}; + final response = await secureGet('device_name', queryParameters: payload); + if (response == null) throw Exception("auth error"); + if (response.statusCode != 200) throw Exception("Server Error"); + final body = json.decode(response.body); + if (!mounted) return; + setState(() => batterySoc = body['battery_soc'] as int?); + } catch (e) { + // Battery SOC is non-critical; swallow silently + } + } + Future checkDeviceConnection() async { try { final payload = { @@ -413,6 +431,7 @@ class _PeripheralScreenState extends State { getName(); checkDeviceConnection(); fetchState(); + getDeviceBatterySoc(); } void rename() { @@ -548,37 +567,50 @@ class _PeripheralScreenState extends State { ), backgroundColor: Theme.of(context).primaryColorLight, foregroundColor: Colors.white, - bottom: !deviceConnected ? PreferredSize( - preferredSize: const Size.fromHeight(48.0), - child: Container( - width: double.infinity, - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - color: Colors.orange.shade700, - child: Row( - children: [ - const Icon( - Icons.wifi_off, - color: Colors.white, - size: 20, - ), - const SizedBox(width: 12), - const Expanded( - child: Text( - 'Device Disconnected', - style: TextStyle( - color: Colors.white, - fontSize: 14, - fontWeight: FontWeight.w500, - ), + actions: [ + if (batterySoc != null) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + children: [ + Icon( + batterySoc! <= 10 ? Icons.battery_alert + : batterySoc! <= 20 ? Icons.battery_1_bar + : batterySoc! <= 40 ? Icons.battery_2_bar + : batterySoc! <= 60 ? Icons.battery_3_bar + : batterySoc! <= 80 ? Icons.battery_5_bar + : Icons.battery_full, + color: batterySoc! <= 10 ? Colors.red : Colors.white, ), - ), - ], + const SizedBox(width: 4), + Text('$batterySoc%', style: const TextStyle(color: Colors.white)), + ], + ), ), - ), - ) : null, + ], ), - body: loaded + body: Column( + children: [ + if (_movementPending) + Container( + width: double.infinity, + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), + color: Colors.orange.shade700, + child: Row( + children: [ + const Icon(Icons.access_time, color: Colors.white, size: 20), + const SizedBox(width: 12), + const Expanded( + child: Text( + 'Movement pending... Will take up to 1 minute', + style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500), + ), + ), + ], + ), + ), + Expanded(child: loaded ? (calibrating ? RefreshIndicator( onRefresh: initAll, @@ -666,8 +698,9 @@ class _PeripheralScreenState extends State { onPositionChanged: (value) { setState(() { _blindPosition = value; - updateBlindPosition(); + _movementPending = true; }); + updateBlindPosition(); }, ), Container( @@ -718,7 +751,9 @@ class _PeripheralScreenState extends State { ) ) ))) - : BlindmasterProgressIndicator(), + : BlindmasterProgressIndicator()), + ], + ), floatingActionButton: Container( padding: EdgeInsets.all(25), child: Row(