Responsive banner saying to wait for up to minute, as well as battery status.

This commit is contained in:
2026-03-21 00:00:35 -05:00
parent 80a2884077
commit 9d291652ac

View File

@@ -32,6 +32,8 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
double _blindPosition = 5.0;
DateTime? lastSet;
String lastSetMessage = "";
int? batterySoc;
bool _movementPending = false;
final _peripheralRenameController = TextEditingController();
@@ -130,6 +132,7 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
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<PeripheralScreen> {
if (!mounted) return;
setState(() {
_blindPosition = (data['pos'] as int).toDouble();
_movementPending = false;
});
}
}
@@ -341,6 +345,20 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
}
}
Future<void> 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<void> checkDeviceConnection() async {
try {
final payload = {
@@ -413,6 +431,7 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
getName();
checkDeviceConnection();
fetchState();
getDeviceBatterySoc();
}
void rename() {
@@ -548,37 +567,50 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
),
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<PeripheralScreen> {
onPositionChanged: (value) {
setState(() {
_blindPosition = value;
updateBlindPosition();
_movementPending = true;
});
updateBlindPosition();
},
),
Container(
@@ -718,7 +751,9 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
)
)
)))
: BlindmasterProgressIndicator(),
: BlindmasterProgressIndicator()),
],
),
floatingActionButton: Container(
padding: EdgeInsets.all(25),
child: Row(