RFSpyReader -> kt

This commit is contained in:
Milos Kozak 2022-07-01 11:36:28 +02:00
parent b00a9bac8e
commit 88072ea752
3 changed files with 102 additions and 140 deletions

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState
@ -54,8 +55,6 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil.Comp
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.TimeChangeType
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
@ -306,12 +305,8 @@ class MedtronicPumpPlugin @Inject constructor(
private val isPumpNotReachable: Boolean private val isPumpNotReachable: Boolean
get() { get() {
val rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState val rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState
if (rileyLinkServiceState == null) { if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady
aapsLogger.debug(LTag.PUMP, "RileyLink unreachable. RileyLinkServiceState is null.") && rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady
return false
}
if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady //
&& rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady //
&& rileyLinkServiceState != RileyLinkServiceState.TuneUpDevice && rileyLinkServiceState != RileyLinkServiceState.TuneUpDevice
) { ) {
aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.") aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.")
@ -998,11 +993,7 @@ class MedtronicPumpPlugin @Inject constructor(
} }
@Synchronized @Synchronized
private fun workWithStatusRefresh( private fun workWithStatusRefresh(action: StatusRefreshAction, statusRefreshType: MedtronicStatusRefreshType?, time: Long?): Map<MedtronicStatusRefreshType, Long>? {
action: StatusRefreshAction, //
statusRefreshType: MedtronicStatusRefreshType?, //
time: Long?
): Map<MedtronicStatusRefreshType, Long>? {
return when (action) { return when (action) {
StatusRefreshAction.Add -> { StatusRefreshAction.Add -> {
statusRefreshMap[statusRefreshType!!] = time!! statusRefreshMap[statusRefreshType!!] = time!!

View file

@ -1,127 +0,0 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble;
import android.os.SystemClock;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil;
import info.nightscout.shared.logging.AAPSLogger;
import info.nightscout.shared.logging.LTag;
/**
* Created by geoff on 5/26/16.
*/
public class RFSpyReader {
private final AAPSLogger aapsLogger;
ExecutorService executor = Executors.newSingleThreadExecutor();
private final RileyLinkBLE rileyLinkBle;
private final Semaphore waitForRadioData = new Semaphore(0, true);
private final LinkedBlockingQueue<byte[]> mDataQueue = new LinkedBlockingQueue<>();
private int acquireCount = 0;
private int releaseCount = 0;
private boolean stopAtNull = true;
RFSpyReader(AAPSLogger aapsLogger, RileyLinkBLE rileyLinkBle) {
this.aapsLogger = aapsLogger;
this.rileyLinkBle = rileyLinkBle;
}
void setRileyLinkEncodingType(RileyLinkEncodingType encodingType) {
aapsLogger.debug("setRileyLinkEncodingType: " + encodingType);
stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || //
encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink);
}
// This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen.
byte[] poll(int timeout_ms) {
aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "Entering poll at t==" + SystemClock.uptimeMillis() + ", timeout is " + timeout_ms
+ " mDataQueue size is " + mDataQueue.size());
if (mDataQueue.isEmpty()) {
try {
// block until timeout or data available.
// returns null if timeout.
byte[] dataFromQueue = mDataQueue.poll(timeout_ms, TimeUnit.MILLISECONDS);
if (dataFromQueue != null) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [" + ByteUtil.shortHexString(dataFromQueue) + "] at t=="
+ SystemClock.uptimeMillis());
} else {
aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis());
}
return dataFromQueue;
} catch (InterruptedException e) {
aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data");
}
}
return null;
}
// Call this from the "response count" notification handler.
void newDataIsAvailable() {
releaseCount++;
aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData released(count=" + releaseCount + ") at t="
+ SystemClock.uptimeMillis());
waitForRadioData.release();
}
public void start() {
executor.execute(() -> {
UUID serviceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO);
UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA);
BLECommOperationResult result;
//noinspection InfiniteLoopStatement
while (true) {
try {
acquireCount++;
waitForRadioData.acquire();
aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData acquired (count=" + acquireCount + ") at t="
+ SystemClock.uptimeMillis());
SystemClock.sleep(100);
SystemClock.sleep(1);
result = rileyLinkBle.readCharacteristicBlocking(serviceUUID, radioDataUUID);
SystemClock.sleep(100);
if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) {
if (stopAtNull) {
// only data up to the first null is valid
for (int i = 0; i < result.value.length; i++) {
if (result.value[i] == 0) {
result.value = ByteUtil.substring(result.value, 0, i);
break;
}
}
}
mDataQueue.add(result.value);
} else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) {
aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted");
} else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) {
aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out");
} else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) {
aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress");
} else if (result.resultCode == BLECommOperationResult.RESULT_NONE) {
aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: " + result.resultCode);
}
} catch (InterruptedException e) {
aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data");
}
}
});
}
}

View file

@ -0,0 +1,98 @@
package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble
import android.os.SystemClock
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit
/**
* Created by geoff on 5/26/16.
*/
class RFSpyReader internal constructor(private val aapsLogger: AAPSLogger, private val rileyLinkBle: RileyLinkBLE) {
private var executor = Executors.newSingleThreadExecutor()
private val waitForRadioData = Semaphore(0, true)
private val mDataQueue = LinkedBlockingQueue<ByteArray>()
private var acquireCount = 0
private var releaseCount = 0
private var stopAtNull = true
fun setRileyLinkEncodingType(encodingType: RileyLinkEncodingType) {
aapsLogger.debug("setRileyLinkEncodingType: $encodingType")
stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink)
}
// This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen.
fun poll(timeout_ms: Int): ByteArray? {
aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}Entering poll at t==${SystemClock.uptimeMillis()}, timeout is $timeout_ms mDataQueue size is ${mDataQueue.size}")
if (mDataQueue.isEmpty()) {
try {
// block until timeout or data available.
// returns null if timeout.
val dataFromQueue = mDataQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
if (dataFromQueue != null)
aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [${ByteUtil.shortHexString(dataFromQueue)}] at t==${SystemClock.uptimeMillis()}")
else
aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis())
return dataFromQueue
} catch (e: InterruptedException) {
aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data")
}
}
return null
}
// Call this from the "response count" notification handler.
fun newDataIsAvailable() {
releaseCount++
aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}waitForRadioData released(count=$releaseCount) at t=${SystemClock.uptimeMillis()}")
waitForRadioData.release()
}
fun start() {
executor.execute {
val serviceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO)
val radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA)
var result: BLECommOperationResult
while (true) {
try {
acquireCount++
waitForRadioData.acquire()
aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}waitForRadioData acquired (count=$acquireCount) at t=${SystemClock.uptimeMillis()}")
SystemClock.sleep(100)
result = rileyLinkBle.readCharacteristicBlocking(serviceUUID, radioDataUUID)
SystemClock.sleep(100)
if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) {
if (stopAtNull) {
// only data up to the first null is valid
for (i in result.value.indices) {
if (result.value[i].toInt() == 0) {
result.value = ByteUtil.substring(result.value, 0, i)
break
}
}
}
mDataQueue.add(result.value)
} else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED)
aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted")
else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT)
aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out")
else if (result.resultCode == BLECommOperationResult.RESULT_BUSY)
aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress")
else if (result.resultCode == BLECommOperationResult.RESULT_NONE)
aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: ${result.resultCode}")
} catch (e: InterruptedException) {
aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data")
}
}
}
}
}