Skip to content

Commit

Permalink
iss #24: [wip] devices config
Browse files Browse the repository at this point in the history
  • Loading branch information
maizy committed Jan 26, 2017
1 parent d0db1d9 commit d4bed80
Show file tree
Hide file tree
Showing 28 changed files with 379 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.typesafe.scalalogging.LazyLogging
import scalikejdbc._
import ru.maizy.ambient7.analysis.AppOptions
import ru.maizy.ambient7.analysis.service.InfluxDbCo2Service
import ru.maizy.ambient7.core.data.Co2AgentId
import ru.maizy.ambient7.core.data.Co2Agent
import ru.maizy.ambient7.core.util.Dates.dateTimeForUser
import ru.maizy.ambient7.rdbms.Co2Service
import ru.maizy.influxdbclient.{ InfluxDbClient, InfluxDbConnectionSettings }
Expand All @@ -28,7 +28,7 @@ object AggregateCo2Command extends LazyLogging {

val now = ZonedDateTime.now()
// val now = ZonedDateTime.of(2015, 12, 3, 7, 12, 13, 14, ZoneOffset.UTC)
val agentId = Co2AgentId(opts.influxDbAgentName, opts.influxDbTags)
val agentId = Co2Agent(opts.influxDbAgentName, opts.influxDbTags)

val eitherDbStartDate = Co2Service.detectStartDateTime(agentId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import scala.annotation.tailrec
import scala.collection.immutable.ListMap
import scala.util.{ Failure, Success }
import com.typesafe.scalalogging.LazyLogging
import ru.maizy.ambient7.core.data.{ Co2AggregatedLevels, Co2AgentId }
import ru.maizy.ambient7.core.data.{ Co2AggregatedLevels, Co2Agent }
import ru.maizy.influxdbclient.data.{ NullValue, SeriesItem, StringValue }
import ru.maizy.influxdbclient.util.Dates
import ru.maizy.influxdbclient.util.Escape.{ escapeValue, tagsToQueryCondition }
Expand All @@ -30,7 +30,7 @@ object InfluxDbCo2Service extends LazyLogging {
influxDbClient: InfluxDbClient,
from: ZonedDateTime,
until: ZonedDateTime,
agentId: Co2AgentId): Either[String, Co2AggregatedLevels] = {
agentId: Co2Agent): Either[String, Co2AggregatedLevels] = {

require(from.compareTo(until) < 0)

Expand Down Expand Up @@ -86,7 +86,7 @@ object InfluxDbCo2Service extends LazyLogging {
def detectStartDateTime(
influxDbClient: InfluxDbClient,
until: ZonedDateTime,
agentId: Co2AgentId,
agentId: Co2Agent,
maxEmptyDuration: Int = DEFAULT_MAX_EMPTY_DURATION): Either[String, ZonedDateTime] = {

val tagsConditions = tagsToQueryCondition(agentId.tags.asPairs)
Expand Down Expand Up @@ -162,7 +162,7 @@ object InfluxDbCo2Service extends LazyLogging {
startDate: ZonedDateTime,
until: ZonedDateTime,
influxDbClient: InfluxDbClient,
agentId: Co2AgentId): Map[ZonedDateTime, Co2AggregatedLevels] = {
agentId: Co2Agent): Map[ZonedDateTime, Co2AggregatedLevels] = {

@tailrec
def iter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package ru.maizy.ambient7.webapp

import java.time.ZoneId
import ru.maizy.ambient7.core.config.Defaults
import ru.maizy.ambient7.webapp.data.Co2Device
import ru.maizy.ambient7.core.data.Co2Device

case class AppConfig(
// FIXME: migrate to uni config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import scala.collection.immutable.ListMap
import scala.util.{ Failure, Success, Try }
import com.typesafe.scalalogging.LazyLogging
import com.typesafe.config.{ Config, ConfigFactory }
import ru.maizy.ambient7.core.data.{ AgentTags, Co2AgentId }
import ru.maizy.ambient7.core.data.{ AgentTags, Co2Agent, Co2Device }
import ru.maizy.ambient7.webapp.AppConfig
import ru.maizy.ambient7.webapp.data.Co2Device


// TODO: safe config parsing with readable errors
Expand Down Expand Up @@ -59,7 +58,7 @@ trait AppConfigInit extends LazyLogging {
case Left(error) =>
throw new RuntimeException(s"Unable to parse agent-tags '$tagsString' for id=$id, skipping tags: $error")
}
Seq(id -> Co2Device(id, agentId = Co2AgentId(deviceConfig.getString("agent-name"), tags)))
Seq(id -> Co2Device(id, agent = Co2Agent(deviceConfig.getString("agent-name"), tags)))
}

appConfig.copy(co2Devices = ListMap(devicesList: _*))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ package ru.maizy.ambient7.webapp.json
* See LICENSE.txt for details.
*/

import ru.maizy.ambient7.core.json.{ BaseProtocol, Co2AgentIdProtocol }
import ru.maizy.ambient7.webapp.data.Co2Device
import ru.maizy.ambient7.core.data.Co2Device
import ru.maizy.ambient7.core.json.{ BaseProtocol, Co2AgentProtocol }

trait Co2DeviceProtocol extends BaseProtocol with Co2AgentIdProtocol {
trait Co2DeviceProtocol extends BaseProtocol with Co2AgentProtocol {
implicit val deviceFormat = jsonFormat(Co2Device, "id", "agent")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ package ru.maizy.ambient7.webapp.servlet
import java.time.ZonedDateTime
import scalikejdbc._
import spray.json.{ JsNumber, JsObject, JsString, JsValue, pimpAny }
import ru.maizy.ambient7.core.data.Co2Device
import ru.maizy.ambient7.rdbms.Co2Service
import ru.maizy.ambient7.webapp.data.Co2Device
import ru.maizy.ambient7.webapp.servlet.helper.{ AppConfigSupport, DateParamsSupport, DeviceParamSupport }
import ru.maizy.ambient7.webapp.servlet.helper.{ PrimitiveParamsSupport, SprayJsonSupport, TimeZoneSupport }
import ru.maizy.ambient7.webapp.{ Ambient7WebAppStack, AppConfig }
Expand All @@ -30,7 +30,7 @@ class Co2ReportServlet(val appConfig: AppConfig)
val (from, to, device) = getReportParams
val aggregates = DB readOnly { implicit session =>
Co2Service.getHourlyAggregates(
device.agentId,
device.agent,
from,
to
)
Expand All @@ -42,7 +42,7 @@ class Co2ReportServlet(val appConfig: AppConfig)
val (from, to, device) = getReportParams
val aggregates = DB readOnly { implicit session =>
Co2Service.computeDailyAggregates(
device.agentId,
device.agent,
from,
to
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package ru.maizy.ambient7.webapp.servlet.helper
*/

import org.scalatra.ScalatraBase
import ru.maizy.ambient7.webapp.data.Co2Device
import ru.maizy.ambient7.core.data.Co2Device


trait DeviceParamSupport extends ScalatraBase {
Expand Down
2 changes: 1 addition & 1 deletion config/ambient7.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ db {
password = ""
}

influx-db {
influxdb {
database = "ambient7"

baseurl = "http://localhost:8086/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,60 @@ package ru.maizy.ambient7.core.config
*/

import java.nio.file.Path
import ru.maizy.ambient7.core.data.{ AgentTags, Co2Agent, Co2Device, Device, DeviceType, Devices }

case class FromCliDevice(
agent: String = "main",
tags: AgentTags = AgentTags.empty,
deviceType: Option[DeviceType.Type] = None
)

object Ambient7Options {
val CO2_FROM_CLI_ID = "co2-from-cli-arguments"
}

case class Ambient7Options(
universalConfigPath: Option[Path] = None,
influxDb: Option[InfluxDbOptions] = None,
mainDb: Option[DbOptions] = None,
devices: Option[Devices] = None,
selectedDeviceId: Option[String] = None,
fromCliDevice: Option[FromCliDevice] = None,

// TODO: fix this little hack
showHelp: Boolean = false
)
{

lazy val selectedCo2Device: Option[Co2Device] =
generatedFromCliDevice match {
case Some(device: Co2Device) => Some(device)
case _ => selectedDeviceId.flatMap { selectedId => co2Devices.find(_.id == selectedId) }
}

lazy private val generatedFromCliDevice: Option[Device] = {
fromCliDevice.flatMap { fromCli =>
if (fromCli.deviceType.contains(DeviceType.CO2)) {
Some(Co2Device(
id = Ambient7Options.CO2_FROM_CLI_ID,
agent = Co2Agent(
agentName = fromCli.agent,
tags = fromCli.tags
)
))
} else {
None
}
}
}

lazy val co2Devices: List[Co2Device] = {
var resList = List.empty[Co2Device]
generatedFromCliDevice match {
case Some(device: Co2Device) => resList = device :: resList
case _ =>
}
resList = resList ++ devices.map(_.co2Devices).getOrElse(List.empty)
resList
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package ru.maizy.ambient7.core.config.reader

import ru.maizy.ambient7.core.config.{ Ambient7Options, Defaults, FromCliDevice }
import ru.maizy.ambient7.core.data.{ AgentTags, DeviceType }

/**
* Copyright (c) Nikita Kovaliov, maizy.ru, 2017
* See LICENSE.txt for details.
*/


trait DevicesConfigReader extends UniversalConfigReader {

import UniversalConfigReader._

private def cliDeviceOpts(
opts: Ambient7Options, deviceType: DeviceType.Type)(save: FromCliDevice => FromCliDevice): Ambient7Options = {

val currentOpts = opts.fromCliDevice.getOrElse(FromCliDevice(deviceType = Some(deviceType)))
val res = opts.copy(
fromCliDevice = Some(save(currentOpts))
)
res
}

def fillDeviceFromCliOptions(deviceType: DeviceType.Type): Unit = {

cliParser.opt[String]("agent-name")
.valueName { Defaults.INFLUXDB_AGENT_NAME }
.action { (value, opts) => cliDeviceOpts(opts, deviceType)(_.copy(agent = value)) }

val saveTags = (value: String, opts: Ambient7Options) =>
cliDeviceOpts(opts, deviceType)(_.copy(tags = AgentTags(value)))

val validateTags = (value: String) =>
AgentTags.tryParseFromString(value) match {
case Left(error) => cliParser.failure(error)
case Right(_) => cliParser.success
}

cliParser.opt[String]("agent-tags")
.valueName { "position=outdoor,altitude=200,some=val\\,ue" }
.validate(validateTags)
.action(saveTags)
.text { "Any additional InfluxDB record tags"}

// Deprecated
cliParser.opt[String]("influxdb-tags")
.validate(validateTags)
.action(saveTags)
.text { "Deprecated, use --agent-tags"}

appendCheck { opts =>
if (opts.fromCliDevice.isDefined && opts.fromCliDevice.exists(_.deviceType.isEmpty)) {
failure("device type is required")
} else {
success
}
}

()
}

def fillDevicesOptions(): Unit = {
// FIXME: implements

()
}

def fillSelectedDeviceOptions(): Unit = {
cliParser.opt[String]("device-id")
.action { (value, opts) => opts.copy(selectedDeviceId = Some(value)) }
.text { "Selected device" }

// FIXME: implement device append (here or in case class)
()
}

// FIXME: rewrite?
def co2DeviceRequired(): Unit = {
appendCheck { opts =>
val fromCliDefined = opts.fromCliDevice.isDefined
val agentByIdDefined = opts.selectedDeviceId.isDefined &&
!opts.selectedDeviceId.contains(Ambient7Options.CO2_FROM_CLI_ID)
if (fromCliDefined && agentByIdDefined) {
failure("Either --agent-name or --device-id should be defined, but not both")
} else if (opts.selectedDeviceId.isDefined && opts.selectedCo2Device.isEmpty){
val id = opts.selectedDeviceId.getOrElse("wtf?")
failure(s"co2 device with id '$id' not found in config")
} else {
success
}
}
}
}

0 comments on commit d4bed80

Please sign in to comment.