diff --git a/src/main/kotlin/application/presenter/database/serialization/DBSerialization.kt b/src/main/kotlin/application/presenter/database/serialization/DBSerialization.kt index 900dbcc3..39c9646f 100644 --- a/src/main/kotlin/application/presenter/database/serialization/DBSerialization.kt +++ b/src/main/kotlin/application/presenter/database/serialization/DBSerialization.kt @@ -10,6 +10,7 @@ package application.presenter.database.serialization import application.presenter.database.model.TimeSeriesDataType import application.presenter.database.model.TimeSeriesRoomEnvironmentalData +import application.presenter.database.model.TimeSeriesRoomMetadata import entity.environment.Humidity import entity.environment.LightUnit import entity.environment.Luminosity @@ -17,6 +18,8 @@ import entity.environment.Presence import entity.environment.Temperature import entity.environment.TemperatureUnit import entity.zone.RoomEnvironmentalData +import entity.zone.RoomID +import java.time.Instant /** * Extension method that allows to convert a map of [TimeSeriesDataType] -> [TimeSeriesRoomEnvironmentalData] @@ -40,3 +43,45 @@ fun Map.toRoomEnvironmenta }, presence = this[TimeSeriesDataType.PRESENCE]?.let { Presence(it.value > 0) } ) + +/** + * Extension method that allows to convert [RoomEnvironmentalData] in a map of [TimeSeriesRoomEnvironmentalData]. + */ +fun RoomEnvironmentalData.toTimeSeries(dateTime: Instant, roomId: RoomID) = mapOf( + TimeSeriesDataType.TEMPERATURE to this.temperature?.let { + TimeSeriesRoomEnvironmentalData( + dateTime, + TimeSeriesRoomMetadata( + roomId, + TimeSeriesDataType.TEMPERATURE, + it.unit.toString() + ), + it.value + ) + }, + TimeSeriesDataType.HUMIDITY to this.humidity?.let { + TimeSeriesRoomEnvironmentalData( + dateTime, + TimeSeriesRoomMetadata(roomId, TimeSeriesDataType.HUMIDITY), + it.percentage + ) + }, + TimeSeriesDataType.LUMINOSITY to this.luminosity?.let { + TimeSeriesRoomEnvironmentalData( + dateTime, + TimeSeriesRoomMetadata( + roomId, + TimeSeriesDataType.LUMINOSITY, + it.unit.toString() + ), + it.value + ) + }, + TimeSeriesDataType.PRESENCE to this.presence?.let { + TimeSeriesRoomEnvironmentalData( + dateTime, + TimeSeriesRoomMetadata(roomId, TimeSeriesDataType.PRESENCE), + it.presenceDetected.let { p -> if (p) 1.0 else 0.0 } + ) + } +).filter { it.value != null } diff --git a/src/main/kotlin/infrastructure/database/DatabaseManager.kt b/src/main/kotlin/infrastructure/database/DatabaseManager.kt index 908d9c68..b04a6700 100644 --- a/src/main/kotlin/infrastructure/database/DatabaseManager.kt +++ b/src/main/kotlin/infrastructure/database/DatabaseManager.kt @@ -16,6 +16,7 @@ import application.presenter.database.model.TimeSeriesMedicalTechnologyUsage import application.presenter.database.model.TimeSeriesRoomEnvironmentalData import application.presenter.database.model.TimeSeriesRoomMetadata import application.presenter.database.serialization.toRoomEnvironmentalData +import application.presenter.database.serialization.toTimeSeries import com.mongodb.MongoException import com.mongodb.client.MongoCollection import entity.medicaltechnology.MedicalTechnology @@ -82,12 +83,35 @@ class DatabaseManager(customConnectionString: String? = null) : RoomDatabaseMana roomId: RoomID, environmentalData: RoomEnvironmentalData, dateTime: Instant - ): Boolean { - // insert new data to the room_environmental_data collection - // update environmental data to the room document inside the room collection - // the environmental data collection has the room ID associated to the environmental data and a timestamp - // this data model must be created within this package because it is used only here. - TODO("Not yet implemented") + ): Boolean = this.roomTimeSeriesCollection.safeMongoDbWrite(mapOf()) { + // update time series + val updatesMap = environmentalData.toTimeSeries(dateTime, roomId) + insertMany(updatesMap.values.map { it }) + updatesMap + }.let { + // update room info with the latest values + this@DatabaseManager.roomCollection.safeMongoDbWrite(false) { + updateOne( + Room::id eq roomId, + it.toRoomEnvironmentalData().let { roomEnvData -> + listOfNotNull( + roomEnvData.temperature?.let { t -> + setValue(Room::environmentalData / RoomEnvironmentalData::temperature, t) + }, + roomEnvData.humidity?.let { t -> + setValue(Room::environmentalData / RoomEnvironmentalData::humidity, t) + }, + roomEnvData.luminosity?.let { t -> + setValue(Room::environmentalData / RoomEnvironmentalData::luminosity, t) + }, + roomEnvData.presence?.let { t -> + setValue(Room::environmentalData / RoomEnvironmentalData::presence, t) + } + ) + } + ) + true + } } override fun saveMedicalTechnology(medicalTechnology: MedicalTechnology): Boolean =