Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send notification when low OMI battery #1792

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions app/lib/backend/http/api/hardware.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'dart:convert';
import 'dart:ffi';

import 'package:flutter/material.dart';
import 'package:friend_private/backend/http/shared.dart';
import 'package:friend_private/env/env.dart';

Future<void> saveFcmTokenServer(
{required String token, required String timeZone}) async {
var response = await makeApiCall(
url: '${Env.apiBaseUrl}v1/firmware/battery-alert',
headers: {'Content-Type': 'application/json'},
method: 'POST',
body: jsonEncode({'fcm_token': token, 'time_zone': timeZone}),
);

debugPrint('saveToken: ${response?.body}');
if (response?.statusCode == 200) {
debugPrint("Token saved successfully");
} else {
debugPrint("Failed to save token");
}
}

64 changes: 49 additions & 15 deletions app/lib/providers/device_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import 'package:friend_private/services/services.dart';
import 'package:friend_private/utils/analytics/mixpanel.dart';
import 'package:instabug_flutter/instabug_flutter.dart';

class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption {
class DeviceProvider extends ChangeNotifier
implements IDeviceServiceSubsciption {


CaptureProvider? captureProvider;

bool isConnecting = false;
Expand All @@ -22,6 +25,7 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
int batteryLevel = -1;
Timer? _reconnectionTimer;
int connectionCheckSeconds = 4;
bool lowBatteryNotified = false;

Timer? _disconnectNotificationTimer;

Expand All @@ -44,10 +48,13 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption

Future getDeviceInfo() async {
if (connectedDevice != null) {
if (pairedDevice?.firmwareRevision != null && pairedDevice?.firmwareRevision != 'Unknown') {
if (pairedDevice?.firmwareRevision != null &&
pairedDevice?.firmwareRevision != 'Unknown') {
return;
}
var connection = await ServiceManager.instance().device.ensureConnection(connectedDevice!.id);
var connection = await ServiceManager.instance()
.device
.ensureConnection(connectedDevice!.id);
pairedDevice = await connectedDevice!.getDeviceInfo(connection);
SharedPreferencesUtil().btDevice = pairedDevice!;
} else {
Expand All @@ -66,16 +73,19 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
void Function(int)? onBatteryLevelChange,
}) async {
{
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
var connection =
await ServiceManager.instance().device.ensureConnection(deviceId);
if (connection == null) {
return Future.value(null);
}
return connection.getBleBatteryLevelListener(onBatteryLevelChange: onBatteryLevelChange);
return connection.getBleBatteryLevelListener(
onBatteryLevelChange: onBatteryLevelChange);
}
}

Future<List<int>> _getStorageList(String deviceId) async {
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
var connection =
await ServiceManager.instance().device.ensureConnection(deviceId);
if (connection == null) {
return [];
}
Expand All @@ -87,7 +97,8 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
if (deviceId.isEmpty) {
return null;
}
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
var connection =
await ServiceManager.instance().device.ensureConnection(deviceId);
return connection?.device;
}

Expand All @@ -98,6 +109,21 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
connectedDevice!.id,
onBatteryLevelChange: (int value) {
batteryLevel = value;

if (batteryLevel < 20) {
if (!lowBatteryNotified) {
NotificationService.instance.createNotification(
title: 'Charge your OMI necklace🪫!',
body: 'Your OMI necklace is running low on battery. Please charge it to avoid any interruptions.',
);
lowBatteryNotified = true;
}
} else {
// Reset flag when battery charges above 20%
lowBatteryNotified = false;
}

notifyListeners();
},
);
notifyListeners();
Expand All @@ -106,7 +132,8 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
Future periodicConnect(String printer) async {
debugPrint("period connect");
_reconnectionTimer?.cancel();
_reconnectionTimer = Timer.periodic(Duration(seconds: connectionCheckSeconds), (t) async {
_reconnectionTimer =
Timer.periodic(Duration(seconds: connectionCheckSeconds), (t) async {
debugPrint("period connect...");
print(printer);
print('seconds: $connectionCheckSeconds');
Expand All @@ -115,7 +142,8 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
if (SharedPreferencesUtil().btDevice.id.isEmpty) {
return;
}
print("isConnected: $isConnected, isConnecting: $isConnecting, connectedDevice: $connectedDevice");
print(
"isConnected: $isConnected, isConnecting: $isConnecting, connectedDevice: $connectedDevice");
if ((!isConnected && connectedDevice == null)) {
if (isConnecting) {
return;
Expand All @@ -127,7 +155,8 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
});
}

Future<BtDevice?> _scanAndConnectDevice({bool autoConnect = true, bool timeout = false}) async {
Future<BtDevice?> _scanAndConnectDevice(
{bool autoConnect = true, bool timeout = false}) async {
var device = await _getConnectedDevice();
if (device != null) {
return device;
Expand All @@ -136,7 +165,9 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
int timeoutCounter = 0;
while (true) {
if (timeout && timeoutCounter >= 10) return null;
await ServiceManager.instance().device.discover(desirableDeviceId: SharedPreferencesUtil().btDevice.id);
await ServiceManager.instance()
.device
.discover(desirableDeviceId: SharedPreferencesUtil().btDevice.id);
if (connectedDevice != null) {
return connectedDevice;
}
Expand Down Expand Up @@ -270,11 +301,14 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption
}

@override
void onDeviceConnectionStateChanged(String deviceId, DeviceConnectionState state) async {
debugPrint("provider > device connection state changed...${deviceId}...${state}...${connectedDevice?.id}");
void onDeviceConnectionStateChanged(
String deviceId, DeviceConnectionState state) async {
debugPrint(
"provider > device connection state changed...${deviceId}...${state}...${connectedDevice?.id}");
switch (state) {
case DeviceConnectionState.connected:
var connection = await ServiceManager.instance().device.ensureConnection(deviceId);
var connection =
await ServiceManager.instance().device.ensureConnection(deviceId);
if (connection == null) {
return;
}
Expand All @@ -294,4 +328,4 @@ class DeviceProvider extends ChangeNotifier implements IDeviceServiceSubsciption

@override
void onStatusChanged(DeviceServiceStatus status) {}
}
}
9 changes: 9 additions & 0 deletions backend/routers/firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import httpx
from fastapi import APIRouter, HTTPException

from utils.notifications import send_notification
from database.notifications import get_token_only

router = APIRouter()


Expand Down Expand Up @@ -69,6 +72,7 @@ async def get_latest_version(device: int):
}



def extract_key_value_pairs(markdown_content):
key_value_pattern = re.compile(r'<!-- KEY_VALUE_START\s*(.*?)\s*KEY_VALUE_END -->', re.DOTALL)
key_value_match = key_value_pattern.search(markdown_content)
Expand All @@ -88,3 +92,8 @@ def extract_key_value_pairs(markdown_content):
key_value_map[key] = value

return key_value_map