@@ -2,6 +2,9 @@ package center.sciprog.controls.demo.thermo
22
33import kotlinx.coroutines.sync.Mutex
44import kotlinx.coroutines.sync.withLock
5+ import kotlinx.datetime.LocalDateTime
6+ import kotlinx.datetime.TimeZone
7+ import kotlinx.datetime.toLocalDateTime
58import kotlinx.serialization.Serializable
69import space.kscience.controls.api.valueType
710import space.kscience.controls.constructor.*
@@ -11,6 +14,7 @@ import space.kscience.dataforge.meta.MetaConverter
1114import space.kscience.dataforge.meta.ValueType
1215import space.kscience.dataforge.names.asName
1316import kotlin.math.abs
17+ import kotlin.time.Clock
1418import kotlin.time.Duration.Companion.milliseconds
1519
1620@Serializable
@@ -56,6 +60,40 @@ class ThermoSensorAnalyzer(
5660
5761 private val mutex = Mutex ()
5862
63+ // cache analyzer config values
64+
65+ private val daily = analyzerConfig.correction.daily
66+
67+ private val yearly = analyzerConfig.correction.yearly
68+
69+ private fun computeCorrection (time : LocalDateTime ): Double {
70+ val dailyCorrection = if (daily.isNullOrEmpty()) {
71+ 0.0
72+ } else {
73+ daily.entries.filter { it.key <= time.hour }.maxByOrNull{ it.key }?.value ? : 0.0
74+ }
75+
76+ val yearlyCorrection = if (yearly.isNullOrEmpty()) {
77+ 0.0
78+ } else {
79+ yearly.entries.filter { it.key <= time.dayOfYear }.maxByOrNull { it.key }?.value ? : 0.0
80+ }
81+
82+ return dailyCorrection + yearlyCorrection
83+ }
84+
85+ private val warningThreshold = analyzerConfig.warningThreshold
86+
87+ private val alarmThreshold = analyzerConfig.alarmThreshold
88+
89+ private fun computeWarningThreshold (
90+ time : LocalDateTime = Clock .System .now().toLocalDateTime(TimeZone .currentSystemDefault())
91+ ): Double = warningThreshold + computeCorrection(time)
92+
93+ private fun computeAlarmThreshold (
94+ time : LocalDateTime = Clock .System .now().toLocalDateTime(TimeZone .currentSystemDefault())
95+ ): Double = alarmThreshold + computeCorrection(time)
96+
5997 private val statusUpdateJob = temperature.onNext(
6098 writes = listOf (status)
6199 ) { next ->
@@ -76,8 +114,8 @@ class ThermoSensorAnalyzer(
76114 averagedTemperatureState.value = average
77115
78116 val newStatus = when {
79- average > analyzerConfig. computeAlarmThreshold() -> ThermoSensorStatus .Alarm
80- average > analyzerConfig. computeWarningThreshold() -> ThermoSensorStatus .Warning
117+ average > computeAlarmThreshold() -> ThermoSensorStatus .Alarm
118+ average > computeWarningThreshold() -> ThermoSensorStatus .Warning
81119 else -> ThermoSensorStatus .Normal
82120 }
83121
0 commit comments