You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

91 lines
2.5 KiB

package net.aiterp.git.ykonsole2.infrastructure.testing
import net.aiterp.git.ykonsole2.domain.runtime.*
import net.aiterp.git.ykonsole2.infrastructure.drivers.abstracts.ActiveDriver
import kotlinx.coroutines.delay
import net.aiterp.git.ykonsole2.application.logging.log
import kotlin.math.abs
import kotlin.math.roundToInt
import kotlin.random.Random
import kotlin.random.nextInt
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
class TestDriver(private val secondLength: Duration) : ActiveDriver() {
private var time = 0
private var calories = 0.0
private var distance = 0.0
private var level = 0
private var speed = 50.0
private var pulse = 70.0
private var running = false
private var connected = false
private val currentState
get() = listOf(
Level(level),
Time(time),
Calories(calories.toInt()),
Distance(distance.toInt()),
Pulse(pulse.roundToInt()),
RpmSpeed(speed.roundToInt()),
)
override suspend fun onCommand(command: Command, output: FlowBus<Event>) {
if (!connected && command !is ConnectCommand) {
// Don't interfere with other drivers
return
}
log.info("Received command: $command")
val ev = when (command) {
is ConnectCommand -> {
if (command.device.connectionString.startsWith("test:")) {
delay(Random.nextInt(100..300).milliseconds)
connected = true
Connected(initial = true)
} else {
log.info("Ignoring device: ${command.device.name}")
null
}
}
DisconnectCommand -> Disconnected.also {
connected = false
time = 0
calories = 0.0
distance = 0.0
}
is SetValueCommand -> when (command.value) {
is Level -> {
level = command.value.raw
ValuesReceived(currentState)
}
else -> null
}
SkipCommand -> null
StartCommand -> Started.also { running = true }
StopCommand -> Stopped.also { running = false }
}
ev?.let { output.emit(it) }
}
override suspend fun onTick(output: FlowBus<Event>) {
if (running && connected) {
time += 1
calories += ((level + 1).toDouble() / 10) * Random.nextDouble(0.1, 0.4)
distance += ((level + 1).toDouble() / 10) * Random.nextDouble(1.5, 2.5)
speed = 100.0 - (level * Random.nextDouble(1.0, 2.5))
pulse = maxOf(60.0, minOf(140.0, Random.nextDouble(pulse - 1 - (level / 10), pulse + 1 + (level / 10))))
output.emit(ValuesReceived(currentState))
}
delay(secondLength)
}
}