Skip to content

Commit

Permalink
feat(hub): implement kotlin luminosity source
Browse files Browse the repository at this point in the history
  • Loading branch information
tassiluca committed Feb 28, 2024
1 parent c850a00 commit dd74744
Show file tree
Hide file tree
Showing 16 changed files with 217 additions and 211 deletions.
1 change: 1 addition & 0 deletions smart-hub-direct-kt/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {

dependencies {
implementation(libs.kotlinx.coroutines.swing)
implementation(project(":smart-hub-direct"))
}

application {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.github.tassiLuca.hub.adapters

import io.github.tassiLuca.hub.adapters.ui.SourceUI
import io.github.tassiLuca.hub.core.Luminosity
import io.github.tassiLuca.hub.core.LuminosityEntry
import io.github.tassiLuca.hub.core.SensorEvent
import io.github.tassiLuca.hub.core.SensorSource
import io.github.tassiLuca.hub.core.Temperature
import io.github.tassiLuca.hub.core.TemperatureEntry
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import scala.runtime.BoxedUnit
import kotlin.coroutines.CoroutineContext

/** A graphical temperature source. */
class GraphicalSource : SensorSource<SensorEvent>, CoroutineScope {

private val views = setOf(
SourceUI("temperature") { s, d ->
publishTemperatureEntry(s, d as Double)
BoxedUnit.UNIT
},
SourceUI("luminosity") { s, d ->
publishLuminosityEntry(s, d as Double)
BoxedUnit.UNIT
},
)
private val entries = MutableSharedFlow<SensorEvent>()

override val sensorEvents: SharedFlow<SensorEvent> = entries.asSharedFlow()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main

init {
views.forEach {
it.pack()
it.isVisible = true
}
}

private fun publishTemperatureEntry(sensorName: String, temperature: Temperature) = launch {
entries.emit(TemperatureEntry(sensorName, temperature))
}

private fun publishLuminosityEntry(sensorName: String, luminosity: Luminosity) = launch {
entries.emit(LuminosityEntry(sensorName, luminosity))
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
package io.github.tassiLuca.hub.adapters

import io.github.tassiLuca.hub.application.ThermostatHubManager
import io.github.tassiLuca.hub.application.LightingManager
import io.github.tassiLuca.hub.application.ThermostatManager
import io.github.tassiLuca.hub.core.LuminosityEntry
import io.github.tassiLuca.hub.core.TemperatureEntry
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext

/** A mocked hub manager. */
class MockedHubManager(coroutineContext: CoroutineContext) {
class MockedHubManager(override val coroutineContext: CoroutineContext) : CoroutineScope {

/** The dashboard. */
val dashboard = SwingDashboard()
val dashboard = SwingDashboardService()

/** The thermostat hub. */
val thermostatHub = ThermostatHubManager(dashboard, coroutineContext)
/** The thermostat manager. */
val thermostatManager = ThermostatManager(dashboard, coroutineContext)

/** The lighting system manager. */
val lightingManager = LightingManager(dashboard, coroutineContext)

/** The sensor source. */
val sensorSource = GraphicalTemperatureSource()
val sensorSource = GraphicalSource()

/** Runs the mocked hub manager. */
suspend fun run() {
val temperatureFlow: Flow<TemperatureEntry> = sensorSource.sensorEvents
suspend fun run() = coroutineScope {
val temperatureFlow = sensorSource.sensorEvents
.filter { it is TemperatureEntry }
.map { it as TemperatureEntry }
thermostatHub.run(temperatureFlow)
val luminosityFlow = sensorSource.sensorEvents
.filter { it is LuminosityEntry }
.map { it as LuminosityEntry }
launch { thermostatManager.run(temperatureFlow) }
lightingManager.run(luminosityFlow)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.tassiLuca.hub.adapters

import io.github.tassiLuca.hub.adapters.ui.DashboardUI
import io.github.tassiLuca.hub.core.Luminosity
import io.github.tassiLuca.hub.core.Temperature
import io.github.tassiLuca.hub.core.ports.DashboardService
import javax.swing.SwingUtilities

/** Swing dashboard. */
class SwingDashboardService : DashboardService {
private val view = DashboardUI()

override fun temperatureUpdated(newTemperature: Temperature) = SwingUtilities.invokeLater {
view.temperatureLabel().text = "$newTemperature °C"
}

override fun luminosityUpdated(newLuminosity: Luminosity) {
view.luminosityLabel().text = "$newLuminosity lux"
}

override fun onHeaterNotified() = SwingUtilities.invokeLater {
view.heaterLabel().text = "On"
}

override fun offHeaterNotified() = SwingUtilities.invokeLater {
view.heaterLabel().text = "Off"
}

override fun alertNotified(message: String) = SwingUtilities.invokeLater {
view.alertsModel().insertRow(0, arrayOf(message))
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.github.tassiLuca.hub.application

import io.github.tassiLuca.hub.core.LightingSystem
import io.github.tassiLuca.hub.core.LuminosityEntry
import io.github.tassiLuca.hub.core.ports.DashboardService
import kotlinx.coroutines.flow.Flow
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration.Companion.seconds

/** Manages the thermostat and the temperature sensors. */
class LightingManager(dashboardService: DashboardService, coroutineContext: CoroutineContext) {

/** The thermostat. */
val lightingSystem = LightingSystem(SAMPLING_WINDOW, coroutineContext, dashboardService)

/** Runs the thermostat and the temperature sensors. */
suspend fun run(sensorSource: Flow<LuminosityEntry>) {
println("LightingManager: run")
lightingSystem.run()
sensorSource.collect {
println("LightingManager: $it")
lightingSystem.react(it)
}
}

companion object {
private val SAMPLING_WINDOW = 5.seconds
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@ import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration.Companion.seconds

/** Manages the thermostat and the temperature sensors. */
class ThermostatHubManager(dashboardService: DashboardService, coroutineContext: CoroutineContext) {
class ThermostatManager(dashboardService: DashboardService, coroutineContext: CoroutineContext) {

/** The thermostat. */
val thermostat = Thermostat(TEMPERATURE_TARGET, SAMPLING_WINDOW, dashboardService, coroutineContext)

/** The temperature sensors checker. */
val temperatureSensorsChecker = SensorHealthChecker<TemperatureEntry>()
val temperatureSensorsChecker = SensorHealthChecker<TemperatureEntry>(
SAMPLING_WINDOW,
coroutineContext,
dashboardService,
)

/** Runs the thermostat and the temperature sensors. */
suspend fun run(sensorSource: Flow<TemperatureEntry>) {
thermostat.run()
temperatureSensorsChecker.run()
sensorSource.collect {
thermostat.react(it)
temperatureSensorsChecker.react(it)
Expand Down
Loading

0 comments on commit dd74744

Please sign in to comment.