<commit_before>package info.nightscout.androidaps.plugins.constraints.bgQualityCheck

import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs

@Singleton
class BgQualityCheckPlugin @Inject constructor(
    injector: HasAndroidInjector,
    aapsLogger: AAPSLogger,
    rh: ResourceHelper,
    private val rxBus: RxBus,
    private val iobCobCalculator: IobCobCalculator,
    private val aapsSchedulers: AapsSchedulers,
    private val fabricPrivacy: FabricPrivacy
) : PluginBase(
    PluginDescription()
        .mainType(PluginType.CONSTRAINTS)
        .neverVisible(true)
        .alwaysEnabled(true)
        .showInList(false)
        .pluginName(R.string.dst_plugin_name),
    aapsLogger, rh, injector
), Constraints {

    private var disposable: CompositeDisposable = CompositeDisposable()

    enum class State {
        UNKNOWN,
        FIVE_MIN_DATA,
        RECALCULATED,
        DOUBLED
    }

    override fun onStart() {
        super.onStart()
        disposable += rxBus
            .toObservable(EventBucketedDataCreated::class.java)
            .observeOn(aapsSchedulers.io)
            .subscribe({ processBgData() }, fabricPrivacy::logException)
    }

    override fun onStop() {
        super.onStop()
        disposable.clear()
    }

    var state: State = State.UNKNOWN
    var message: String = ""

    // Return false if BG values are doubled
    @Suppress("ReplaceGetOrSet")
    override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
        if (state == State.DOUBLED)
            value.set(aapsLogger, false, "Doubled values in BGSource", this)
        return value
    }

    fun processBgData() {
        val readings = iobCobCalculator.ads.getBgReadingsDataTableCopy()
        for (i in readings.indices)
            if (i < readings.size - 2)
                if (abs(readings[i].timestamp - readings[i + 1].timestamp) <= 1000) {
                    state = State.DOUBLED
                    aapsLogger.debug(LTag.CORE, "BG similar. Turning on red state.\n${readings[i]}\n${readings[i+1]}")
                    message = rh.gs(R.string.bg_too_close, readings[i].toString(), readings[i+1].toString())
                    return
                }
        if (iobCobCalculator.ads.lastUsed5minCalculation == true) {
            state = State.FIVE_MIN_DATA
            message = "Data is clean"
        } else if (iobCobCalculator.ads.lastUsed5minCalculation == false) {
            state = State.RECALCULATED
            message = rh.gs(R.string.recalculated_data_used)
        } else {
            state = State.UNKNOWN
            message = ""
        }
    }

    fun icon(): Int =
        when (state) {
            State.UNKNOWN       -> 0
            State.FIVE_MIN_DATA -> 0
            State.RECALCULATED  -> R.drawable.ic_baseline_warning_24_yellow
            State.DOUBLED       -> R.drawable.ic_baseline_warning_24_red
        }
}<commit_msg>increase bg validity check red range to 20s<commit_after>package info.nightscout.androidaps.plugins.constraints.bgQualityCheck

import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs

@Singleton
class BgQualityCheckPlugin @Inject constructor(
    injector: HasAndroidInjector,
    aapsLogger: AAPSLogger,
    rh: ResourceHelper,
    private val rxBus: RxBus,
    private val iobCobCalculator: IobCobCalculator,
    private val aapsSchedulers: AapsSchedulers,
    private val fabricPrivacy: FabricPrivacy
) : PluginBase(
    PluginDescription()
        .mainType(PluginType.CONSTRAINTS)
        .neverVisible(true)
        .alwaysEnabled(true)
        .showInList(false)
        .pluginName(R.string.dst_plugin_name),
    aapsLogger, rh, injector
), Constraints {

    private var disposable: CompositeDisposable = CompositeDisposable()

    enum class State {
        UNKNOWN,
        FIVE_MIN_DATA,
        RECALCULATED,
        DOUBLED
    }

    override fun onStart() {
        super.onStart()
        disposable += rxBus
            .toObservable(EventBucketedDataCreated::class.java)
            .observeOn(aapsSchedulers.io)
            .subscribe({ processBgData() }, fabricPrivacy::logException)
    }

    override fun onStop() {
        super.onStop()
        disposable.clear()
    }

    var state: State = State.UNKNOWN
    var message: String = ""

    // Return false if BG values are doubled
    @Suppress("ReplaceGetOrSet")
    override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
        if (state == State.DOUBLED)
            value.set(aapsLogger, false, "Doubled values in BGSource", this)
        return value
    }

    fun processBgData() {
        val readings = iobCobCalculator.ads.getBgReadingsDataTableCopy()
        for (i in readings.indices)
            if (i < readings.size - 2)
                if (abs(readings[i].timestamp - readings[i + 1].timestamp) <= T.secs(20).msecs()) {
                    state = State.DOUBLED
                    aapsLogger.debug(LTag.CORE, "BG similar. Turning on red state.\n${readings[i]}\n${readings[i+1]}")
                    message = rh.gs(R.string.bg_too_close, readings[i].toString(), readings[i+1].toString())
                    return
                }
        if (iobCobCalculator.ads.lastUsed5minCalculation == true) {
            state = State.FIVE_MIN_DATA
            message = "Data is clean"
        } else if (iobCobCalculator.ads.lastUsed5minCalculation == false) {
            state = State.RECALCULATED
            message = rh.gs(R.string.recalculated_data_used)
        } else {
            state = State.UNKNOWN
            message = ""
        }
    }

    fun icon(): Int =
        when (state) {
            State.UNKNOWN       -> 0
            State.FIVE_MIN_DATA -> 0
            State.RECALCULATED  -> R.drawable.ic_baseline_warning_24_yellow
            State.DOUBLED       -> R.drawable.ic_baseline_warning_24_red
        }
}
{'fraction_non_alphanumeric': 0.09310628948091183, 'fraction_numerical': 0.004394397143641857, 'mean_word_length': 2.700711382113821, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5049338', 'n_tokens_mistral': 2292, 'n_tokens_neox': 2175, 'n_words': 405}