RileyLinkService -> kt

This commit is contained in:
Milos Kozak 2021-12-13 00:56:20 +01:00
parent bfb556bb20
commit 0307796ecf
3 changed files with 203 additions and 283 deletions

View file

@ -28,8 +28,7 @@ import javax.inject.Singleton
* RileyLinkMedtronicService is intended to stay running when the gui-app is closed. * RileyLinkMedtronicService is intended to stay running when the gui-app is closed.
*/ */
@Singleton @Singleton
class RileyLinkMedtronicService // This empty constructor must be kept, otherwise dagger injection might break! class RileyLinkMedtronicService : RileyLinkService() {
@Inject constructor() : RileyLinkService() {
@Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin @Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin
@Inject lateinit var medtronicUtil: MedtronicUtil @Inject lateinit var medtronicUtil: MedtronicUtil
@ -40,7 +39,7 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
private val mBinder: IBinder = LocalBinder() private val mBinder: IBinder = LocalBinder()
private var serialChanged = false private var serialChanged = false
lateinit var frequencies: Array<String> private lateinit var frequencies: Array<String>
private var rileyLinkAddress: String? = null private var rileyLinkAddress: String? = null
private var rileyLinkAddressChanged = false private var rileyLinkAddressChanged = false
private var encodingType: RileyLinkEncodingType? = null private var encodingType: RileyLinkEncodingType? = null
@ -61,16 +60,17 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
return mBinder return mBinder
} }
override fun getEncoding(): RileyLinkEncodingType { override val encoding: RileyLinkEncodingType
return RileyLinkEncodingType.FourByteSixByteLocal get() = RileyLinkEncodingType.FourByteSixByteLocal
}
/** /**
* If you have customized RileyLinkServiceData you need to override this * If you have customized RileyLinkServiceData you need to override this
*/ */
override fun initRileyLinkServiceData() { override fun initRileyLinkServiceData() {
frequencies = arrayOf(rh.gs(R.string.key_medtronic_pump_frequency_us_ca), frequencies = arrayOf(
rh.gs(R.string.key_medtronic_pump_frequency_worldwide)) rh.gs(R.string.key_medtronic_pump_frequency_us_ca),
rh.gs(R.string.key_medtronic_pump_frequency_worldwide)
)
// frequencies[0] = rh.gs(R.string.key_medtronic_pump_frequency_us_ca) // frequencies[0] = rh.gs(R.string.key_medtronic_pump_frequency_us_ca)
// frequencies[1] = rh.gs(R.string.key_medtronic_pump_frequency_worldwide) // frequencies[1] = rh.gs(R.string.key_medtronic_pump_frequency_worldwide)
rileyLinkServiceData.targetDevice = RileyLinkTargetDevice.MedtronicPump rileyLinkServiceData.targetDevice = RileyLinkTargetDevice.MedtronicPump
@ -83,15 +83,14 @@ class RileyLinkMedtronicService // This empty constructor must be kept, otherwi
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed") aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed")
} }
override fun getDeviceCommunicationManager(): MedtronicCommunicationManager { override val deviceCommunicationManager
return medtronicCommunicationManager get() = medtronicCommunicationManager
}
override fun setPumpDeviceState(pumpDeviceState: PumpDeviceState) { override fun setPumpDeviceState(pumpDeviceState: PumpDeviceState) {
medtronicPumpStatus.pumpDeviceState = pumpDeviceState medtronicPumpStatus.pumpDeviceState = pumpDeviceState
} }
fun setPumpIDString(pumpID: String) { private fun setPumpIDString(pumpID: String) {
if (pumpID.length != 6) { if (pumpID.length != 6) {
aapsLogger.error("setPumpIDString: invalid pump id string: $pumpID") aapsLogger.error("setPumpIDString: invalid pump id string: $pumpID")
return return

View file

@ -1,271 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import java.util.Locale;
import javax.inject.Inject;
import dagger.android.DaggerService;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.interfaces.ActivePlugin;
import info.nightscout.shared.logging.AAPSLogger;
import info.nightscout.shared.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.shared.sharedPreferences.SP;
/**
* Created by andy on 5/6/18.
* Split from original file and renamed.
*/
public abstract class RileyLinkService extends DaggerService {
@Inject protected AAPSLogger aapsLogger;
@Inject protected SP sp;
@Inject protected Context context;
@Inject protected RxBus rxBus;
@Inject protected RileyLinkUtil rileyLinkUtil;
@Inject protected HasAndroidInjector injector;
@Inject protected ResourceHelper rh;
@Inject protected RileyLinkServiceData rileyLinkServiceData;
@Inject protected ActivePlugin activePlugin;
@Inject protected RileyLinkBLE rileyLinkBLE; // android-bluetooth management
@Inject protected RFSpy rfspy; // interface for RL xxx Mhz radio.
protected BluetoothAdapter bluetoothAdapter;
protected RileyLinkBroadcastReceiver mBroadcastReceiver;
protected RileyLinkBluetoothStateReceiver bluetoothStateReceiver;
@Override
public void onCreate() {
super.onCreate();
rileyLinkUtil.setEncoding(getEncoding());
initRileyLinkServiceData();
mBroadcastReceiver = new RileyLinkBroadcastReceiver(this);
mBroadcastReceiver.registerBroadcasts(this);
bluetoothStateReceiver = new RileyLinkBluetoothStateReceiver();
bluetoothStateReceiver.registerBroadcasts(this);
}
/**
* Get Encoding for RileyLink communication
*/
public abstract RileyLinkEncodingType getEncoding();
/**
* If you have customized RileyLinkServiceData you need to override this
*/
public abstract void initRileyLinkServiceData();
@Override
public boolean onUnbind(Intent intent) {
//aapsLogger.warn(LTag.PUMPBTCOMM, "onUnbind");
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
//aapsLogger.warn(LTag.PUMPBTCOMM, "onRebind");
super.onRebind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
//LOG.error("I die! I die!");
// xyz rfspy.stopReader();
rileyLinkBLE.disconnect(); // dispose of Gatt (disconnect and close)
if (mBroadcastReceiver != null) {
mBroadcastReceiver.unregisterBroadcasts(this);
}
if (bluetoothStateReceiver != null) {
bluetoothStateReceiver.unregisterBroadcasts(this);
}
}
public abstract RileyLinkCommunicationManager getDeviceCommunicationManager();
public RileyLinkServiceState getRileyLinkServiceState() {
return rileyLinkServiceData == null ? null : rileyLinkServiceData.rileyLinkServiceState;
}
// Here is where the wake-lock begins:
// We've received a service startCommand, we grab the lock.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return (START_STICKY);
}
public boolean bluetoothInit() {
aapsLogger.debug(LTag.PUMPBTCOMM, "bluetoothInit: attempting to get an adapter");
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothInitializing);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
aapsLogger.error("Unable to obtain a BluetoothAdapter.");
rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.NoBluetoothAdapter);
} else {
if (!bluetoothAdapter.isEnabled()) {
aapsLogger.error("Bluetooth is not enabled.");
rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled);
} else {
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady);
return true;
}
}
return false;
}
// returns true if our Rileylink configuration changed
public boolean reconfigureRileyLink(String deviceAddress) {
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkInitializing);
if (rileyLinkBLE.isConnected()) {
if (deviceAddress.equals(rileyLinkServiceData.rileyLinkAddress)) {
aapsLogger.info(LTag.PUMPBTCOMM, "No change to RL address. Not reconnecting.");
return false;
} else {
aapsLogger.warn(LTag.PUMPBTCOMM, "Disconnecting from old RL (" + rileyLinkServiceData.rileyLinkAddress
+ "), reconnecting to new: " + deviceAddress);
rileyLinkBLE.disconnect();
// prolly need to shut down listening thread too?
// SP.putString(MedtronicConst.Prefs.RileyLinkAddress, deviceAddress);
rileyLinkServiceData.rileyLinkAddress = deviceAddress;
rileyLinkBLE.findRileyLink(rileyLinkServiceData.rileyLinkAddress);
return true;
}
} else {
aapsLogger.debug(LTag.PUMPBTCOMM, "Using RL " + deviceAddress);
if (rileyLinkServiceData.getRileyLinkServiceState() == RileyLinkServiceState.NotStarted) {
if (!bluetoothInit()) {
aapsLogger.error("RileyLink can't get activated, Bluetooth is not functioning correctly. " +
(getError() != null ? getError().name() : "Unknown error (null)"));
return false;
}
}
rileyLinkBLE.findRileyLink(deviceAddress);
return true;
}
}
// FIXME: This needs to be run in a session so that is interruptable, has a separate thread, etc.
public void doTuneUpDevice() {
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.TuneUpDevice);
setPumpDeviceState(PumpDeviceState.Sleeping);
double lastGoodFrequency = 0.0d;
if (rileyLinkServiceData.lastGoodFrequency == null) {
lastGoodFrequency = sp.getDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, 0.0d);
} else {
lastGoodFrequency = rileyLinkServiceData.lastGoodFrequency;
}
double newFrequency;
newFrequency = getDeviceCommunicationManager().tuneForDevice();
if ((newFrequency != 0.0) && (newFrequency != lastGoodFrequency)) {
aapsLogger.info(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "Saving new pump frequency of %.3f MHz", newFrequency));
sp.putDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, newFrequency);
rileyLinkServiceData.lastGoodFrequency = newFrequency;
rileyLinkServiceData.tuneUpDone = true;
rileyLinkServiceData.lastTuneUpTime = System.currentTimeMillis();
}
if (newFrequency == 0.0d) {
// error tuning pump, pump not present ??
rileyLinkServiceData.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.TuneUpOfDeviceFailed);
} else {
getDeviceCommunicationManager().clearNotConnectedCount();
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady);
}
}
public abstract void setPumpDeviceState(PumpDeviceState pumpDeviceState);
public void disconnectRileyLink() {
if (rileyLinkBLE.isConnected()) {
rileyLinkBLE.disconnect();
rileyLinkServiceData.rileyLinkAddress = null;
rileyLinkServiceData.rileyLinkName = null;
}
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady);
}
@NonNull public RileyLinkBLE getRileyLinkBLE() {
return rileyLinkBLE;
}
/**
* Get Target Device for Service
*/
public RileyLinkTargetDevice getRileyLinkTargetDevice() {
return this.rileyLinkServiceData.targetDevice;
}
public void changeRileyLinkEncoding(RileyLinkEncodingType encodingType) {
if (rfspy != null) {
rfspy.setRileyLinkEncoding(encodingType);
}
}
public RileyLinkError getError() {
if (rileyLinkServiceData != null)
return rileyLinkServiceData.rileyLinkError;
else
return null;
}
public boolean verifyConfiguration() {
return verifyConfiguration(false);
}
public abstract boolean verifyConfiguration(boolean forceRileyLinkAddressRenewal);
}

View file

@ -0,0 +1,192 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import dagger.android.DaggerService
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RFSpy
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import java.util.*
import javax.inject.Inject
/**
* Created by andy on 5/6/18.
* Split from original file and renamed.
*/
abstract class RileyLinkService : DaggerService() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var context: Context
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rileyLinkUtil: RileyLinkUtil
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var rileyLinkServiceData: RileyLinkServiceData
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var rileyLinkBLE: RileyLinkBLE // android-bluetooth management
@Inject lateinit var rfspy: RFSpy // interface for RL xxx Mhz radio.
private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
protected var mBroadcastReceiver: RileyLinkBroadcastReceiver? = null
private var bluetoothStateReceiver: RileyLinkBluetoothStateReceiver? = null
override fun onCreate() {
super.onCreate()
rileyLinkUtil.encoding = encoding
initRileyLinkServiceData()
mBroadcastReceiver = RileyLinkBroadcastReceiver(this)
mBroadcastReceiver?.registerBroadcasts(this)
bluetoothStateReceiver = RileyLinkBluetoothStateReceiver()
bluetoothStateReceiver?.registerBroadcasts(this)
}
/**
* Get Encoding for RileyLink communication
*/
abstract val encoding: RileyLinkEncodingType
/**
* If you have customized RileyLinkServiceData you need to override this
*/
abstract fun initRileyLinkServiceData()
override fun onUnbind(intent: Intent): Boolean {
//aapsLogger.warn(LTag.PUMPBTCOMM, "onUnbind");
return super.onUnbind(intent)
}
override fun onRebind(intent: Intent) {
//aapsLogger.warn(LTag.PUMPBTCOMM, "onRebind");
super.onRebind(intent)
}
override fun onDestroy() {
super.onDestroy()
rileyLinkBLE.disconnect() // dispose of Gatt (disconnect and close)
mBroadcastReceiver?.unregisterBroadcasts(this)
bluetoothStateReceiver?.unregisterBroadcasts(this)
}
abstract val deviceCommunicationManager: RileyLinkCommunicationManager<*>
val rileyLinkServiceState: RileyLinkServiceState?
get() = rileyLinkServiceData.rileyLinkServiceState
// Here is where the wake-lock begins:
// We've received a service startCommand, we grab the lock.
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int = START_STICKY
fun bluetoothInit(): Boolean {
aapsLogger.debug(LTag.PUMPBTCOMM, "bluetoothInit: attempting to get an adapter")
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothInitializing)
if (bluetoothAdapter == null) {
aapsLogger.error("Unable to obtain a BluetoothAdapter.")
rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.NoBluetoothAdapter)
} else {
if (bluetoothAdapter?.isEnabled != true) {
aapsLogger.error("Bluetooth is not enabled.")
rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled)
} else {
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady)
return true
}
}
return false
}
// returns true if our Rileylink configuration changed
fun reconfigureRileyLink(deviceAddress: String): Boolean {
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkInitializing)
return if (rileyLinkBLE.isConnected) {
if (deviceAddress == rileyLinkServiceData.rileyLinkAddress) {
aapsLogger.info(LTag.PUMPBTCOMM, "No change to RL address. Not reconnecting.")
false
} else {
aapsLogger.warn(LTag.PUMPBTCOMM, "Disconnecting from old RL (${rileyLinkServiceData.rileyLinkAddress}), reconnecting to new: $deviceAddress")
rileyLinkBLE.disconnect()
// need to shut down listening thread too?
// SP.putString(MedtronicConst.Prefs.RileyLinkAddress, deviceAddress);
rileyLinkServiceData.rileyLinkAddress = deviceAddress
rileyLinkBLE.findRileyLink(deviceAddress)
true
}
} else {
aapsLogger.debug(LTag.PUMPBTCOMM, "Using RL $deviceAddress")
if (rileyLinkServiceData.getRileyLinkServiceState() == RileyLinkServiceState.NotStarted) {
if (!bluetoothInit()) {
aapsLogger.error("RileyLink can't get activated, Bluetooth is not functioning correctly. ${error?.name ?: "Unknown error (null)"}")
return false
}
}
rileyLinkBLE.findRileyLink(deviceAddress)
true
}
}
// FIXME: This needs to be run in a session so that is interruptible, has a separate thread, etc.
fun doTuneUpDevice() {
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.TuneUpDevice)
setPumpDeviceState(PumpDeviceState.Sleeping)
val lastGoodFrequency = rileyLinkServiceData.lastGoodFrequency ?: sp.getDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, 0.0)
val newFrequency = deviceCommunicationManager.tuneForDevice()
if (newFrequency != 0.0 && newFrequency != lastGoodFrequency) {
aapsLogger.info(LTag.PUMPBTCOMM, String.format(Locale.ENGLISH, "Saving new pump frequency of %.3f MHz", newFrequency))
sp.putDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, newFrequency)
rileyLinkServiceData.lastGoodFrequency = newFrequency
rileyLinkServiceData.tuneUpDone = true
rileyLinkServiceData.lastTuneUpTime = System.currentTimeMillis()
}
if (newFrequency == 0.0) {
// error tuning pump, pump not present ??
rileyLinkServiceData.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.TuneUpOfDeviceFailed)
} else {
deviceCommunicationManager.clearNotConnectedCount()
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady)
}
}
abstract fun setPumpDeviceState(pumpDeviceState: PumpDeviceState)
fun disconnectRileyLink() {
if (rileyLinkBLE.isConnected) {
rileyLinkBLE.disconnect()
rileyLinkServiceData.rileyLinkAddress = null
rileyLinkServiceData.rileyLinkName = null
}
rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady)
}
/**
* Get Target Device for Service
*/
val rileyLinkTargetDevice: RileyLinkTargetDevice
get() = rileyLinkServiceData.targetDevice
fun changeRileyLinkEncoding(encodingType: RileyLinkEncodingType?) {
rfspy.setRileyLinkEncoding(encodingType)
}
val error: RileyLinkError?
get() = rileyLinkServiceData.rileyLinkError
fun verifyConfiguration(): Boolean {
return verifyConfiguration(false)
}
abstract fun verifyConfiguration(forceRileyLinkAddressRenewal: Boolean): Boolean
}