IntelliSerra (iSerra) is a framework for the management of an intelligent greenhouse intended as a self-regulating environment that creates an optimal micro-climate for plant growth. The climatic conditions inside the greenhouse (temperature, humidity, brightness, soil moisture, ..) are continuously monitored by sensors. Small variations in these conditions trigger automatic actions in response through actuators. Our system allows the management of a territorially extended monoculture greenhouse divided into zones. Each zone can contain different types of sensors and actuators.
Main technologies used are:
- [Akka] - the system is built on top of akka actors
- [TuProlog] - used as engine for rules inference
You must download the library from "Releases" section and import it in your local maven repository since it is not published.
- In order to define new Actions and Categories you must extend it.
// Some custom categories
case object Humidity extends Category[DoubleType]
case object AirTemperature extends Category[DoubleType]
...
// Some custom actions
final case class Water(override val time: FiniteDuration) extends TimedAction
final case class Dehumidifies(override val switchStatus: Boolean) extends ToggledAction
...
- You must define an aggregation logic for each category created
import AggregationFunctions._
val aggregators = List(
createAggregator(AirTemperature)(avg),
createAggregator(Humidity)(max)
)
- You can define actuation rules
val rules = List(
Humidity < 45.0 && AirTemperature < 40.0 execute Water(10 seconds),
Humidity < 50.0 execute Dehumidifies(false),
Humidity > 70.0 execute Dehumidifies(true)
...
)
- Start your greenhouse server!
val config = ServerConfig(
"greenhousename", "hostname", port = 8080,
ZoneConfig(actionsEvaluationPeriod = ..., stateEvaluationPeriod = ..., aggregators),
RuleConfig(rules)
)
// start the server
GreenHouseServer(config).start()
Define and deploy your actuators and sensors. For example:
val humidiySensor = Sensor("humidity1", Humidity, sensingPeriod = 5 seconds)
val dehumActuator = Actuator("dehum1", Dehumidifies.getClass) {
case (state, Dehumidifies(true)) => ... // do something to real world
case (state, Dehumidifies(false)) => ...
}
val deploy = DeviceDeploy("greenhousename", "hostname", port = 8080)
deploy.join(humiditySensor) // its async operation
deploy.join(dehumActuator)
val client = GreenhouseClient("greenhousename", "hostname", port = 8080)
for {
_ <- client.createZone("zone1") // its async operation
_ <- client.associateEntity("dehum1", "zone1")
}
// retrieve zone state client.getState("zone1")
Apache 2.0