diff --git a/docs/wiki/config/config_preview.yml b/docs/wiki/config/config_preview.yml index cb7c307..c99be7c 100644 --- a/docs/wiki/config/config_preview.yml +++ b/docs/wiki/config/config_preview.yml @@ -47,19 +47,19 @@ groundtruths: - [7, 10.0] - [12, 16.0] delta: - - name: flactuate - args: {range: 1.0, center: [3, 3], distOffset: 0.5, time:[0, 12, 18]} + - name: fluctuate + args: {range: 1.0, center: [3, 3], distOffset: -0.5, time:[0, 12, 18]} timeline: - [0, 7] - [12, 16] - [18, 24] - - [7, change, {target: 16.0, targetTime: 12, center: [3, 3], distOffset: 0.5, time:[7]}] - - [16, change, {target: 10.0, targetTime: 18, center: [3, 3], distOffset: 0.5, time:[16]}] + - [7, change, {target: 16.0, targetTime: 12, center: [3, 3], distOffset: -0.5, time:[7]}] + - [16, change, {target: 10.0, targetTime: 18, center: [3, 3], distOffset: -0.5, time:[16]}] - group: humidity parent: temperature delta: - - [0, humidFromTemp, {dewpoint: 12.0, range: 1.0, center: [3, 3], distOffset: 0.5, time:[0, 7, 12, 16, 18]}] + - [0, humidFromTemp, {dewpoint: 12.0,}] behaviours: - group: temperature diff --git a/src/main/scala/scim/datastruct/Configuration.scala b/src/main/scala/scim/datastruct/Configuration.scala index 2f33abc..6ef6eac 100644 --- a/src/main/scala/scim/datastruct/Configuration.scala +++ b/src/main/scala/scim/datastruct/Configuration.scala @@ -117,7 +117,12 @@ case class Group(name: String, sensorParent: Option[String] = None){ } case class Truth() extends Result[Option[Double]] -case class FunctionArgs(args: Map[String, Any]) +case class FunctionArgs(args: Map[String, Any]) { + def getParam[A](param: String, fallback: A): A = { + // just bruteforce try to get the param, otherwise use fallback + try { args(param).asInstanceOf[A] } catch { case _: Throwable => fallback } + } +} case class BehaviourVector(function: Vector[Option[(SimulationBehaviour, Option[FunctionArgs])]], defaultFunc: SimulationBehaviour = (_: Cell, _: Time, v: Option[Double], _: Option[FunctionArgs]) => v, diff --git a/src/main/scala/scim/lib/Library.scala b/src/main/scala/scim/lib/Library.scala index 091b349..d94f7b2 100644 --- a/src/main/scala/scim/lib/Library.scala +++ b/src/main/scala/scim/lib/Library.scala @@ -313,6 +313,53 @@ package object mapUtil { } +package object behaviourUtil { + implicit class FunctionArgsOption(optional: Option[FunctionArgs]) { + def getParam[B](param: String, fallback: B): B = { + if(optional.isEmpty) { + fallback + } else { + optional.get.getParam(param, fallback) + } + } + } +} + +package object numberUtil { + implicit class ExtendedDouble(number: Double) { + def truncate(decimals: Int): Double = { + val n = Math.pow(10, decimals) + (number * n).toLong.toDouble / n + } + + def range(min: Double, max: Double): Double = { + if(number < min) return min + if(number > max) return max + number + } + + // this is not perfect if the number has accuracy problems + def getNumOfDecimals: Int = { + val limit = 1000 // just a safeguard + def recursiveDecimals(n: Double, run: Int): Int = { + if (n % 1d == 0 || run >= limit) { + 0 + } else { + 1 + recursiveDecimals(n * 10, run + 1) + } + } + recursiveDecimals(number, 1) + } + + def resolution(res: Double): Double = { + val result = (number / res).toLong.toDouble * res + // remove any accuracy artifacts by truncating (if resolution does not have problems) + result.truncate(res.getNumOfDecimals) + } + } + +} + package object yml { val yaml = new Yaml // TODO: handle errors (invalid file/format)