diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index bddc712f5..b6ca00350 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Scala uses: olafurpg/setup-scala@v12 with: - java-version: adopt@1.11 + java-version: openjdk@1.17.0 - name: Cache Coursier uses: actions/cache@v3.3.1 with: diff --git a/build.sbt b/build.sbt index d1a58a9f6..7d1b27d6c 100644 --- a/build.sbt +++ b/build.sbt @@ -94,31 +94,6 @@ publish / skip := true // Projects ////////////// -lazy val giapi = project - .in(file("modules/giapi")) - .enablePlugins(GitBranchPrompt) - .settings(commonSettings: _*) - .settings( - addCompilerPlugin(Plugins.kindProjectorPlugin), - libraryDependencies ++= Seq( - Cats.value, - Mouse.value, - Shapeless.value, - CatsEffect.value, - Fs2, - GiapiJmsUtil, - GiapiJmsProvider, - GiapiStatusService, - Giapi, - GiapiCommandsClient - ) ++ Logging.value ++ Monocle.value ++ LucumaCore.value, - libraryDependencies ++= Seq(GmpStatusGateway % "test", - GmpStatusDatabase % "test", - GmpCmdJmsBridge % "test", - NopSlf4j % "test" - ) ++ MUnit.value - ) - lazy val ocs2_api = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Pure) .in(file("modules/ocs2_api")) @@ -282,7 +257,8 @@ lazy val seqexec_server = project Log4CatsNoop.value, TestLibs.value, PPrint.value, - ACM + ACM, + GiapiScala ) ++ MUnit.value ++ Http4s ++ Http4sClient ++ PureConfig ++ SeqexecOdb ++ Monocle.value ++ WDBAClient ++ Circe.value ) @@ -293,7 +269,6 @@ lazy val seqexec_server = project buildInfoPackage := "seqexec.server" ) .dependsOn(seqexec_engine % "compile->compile;test->test", - giapi, ocs2_api.jvm, seqexec_model.jvm % "compile->compile;test->test" ) diff --git a/modules/giapi/src/main/scala/giapi/client/GiapiClient.scala b/modules/giapi/src/main/scala/giapi/client/GiapiClient.scala deleted file mode 100644 index 4b4116932..000000000 --- a/modules/giapi/src/main/scala/giapi/client/GiapiClient.scala +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import scala.concurrent.duration._ - -import edu.gemini.aspen.giapi.commands.Activity -import edu.gemini.aspen.giapi.commands.SequenceCommand -import giapi.client.commands.Command -import giapi.client.commands.CommandResult -import giapi.client.commands.Configuration - -///////////////////////////////////////////////////////////////// -// The GiapiClient comprises the common commands for such clients -///////////////////////////////////////////////////////////////// -trait GiapiClient[F[_]] { - import GiapiClient.DefaultCommandTimeout - - def giapi: Giapi[F] - - def test: F[CommandResult] = - giapi.command(Command(SequenceCommand.TEST, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def init: F[CommandResult] = - giapi.command(Command(SequenceCommand.INIT, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def datum: F[CommandResult] = - giapi.command(Command(SequenceCommand.DATUM, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def park: F[CommandResult] = - giapi.command(Command(SequenceCommand.PARK, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def verify: F[CommandResult] = - giapi.command(Command(SequenceCommand.VERIFY, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def endVerify: F[CommandResult] = - giapi.command(Command(SequenceCommand.END_VERIFY, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def guide: F[CommandResult] = - giapi.command(Command(SequenceCommand.GUIDE, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def endGuide: F[CommandResult] = - giapi.command(Command(SequenceCommand.END_GUIDE, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def observe[A: GiapiConfig](dataLabel: A, timeout: FiniteDuration): F[CommandResult] = - giapi.command(Command( - SequenceCommand.OBSERVE, - Activity.PRESET_START, - Configuration.single(commands.DataLabelCfg, dataLabel) - ), - timeout - ) - - def endObserve: F[CommandResult] = - giapi.command(Command(SequenceCommand.END_OBSERVE, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def pause: F[CommandResult] = - giapi.command(Command(SequenceCommand.PAUSE, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def continue: F[CommandResult] = - giapi.command(Command(SequenceCommand.CONTINUE, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def stop: F[CommandResult] = - giapi.command(Command(SequenceCommand.STOP, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def abort: F[CommandResult] = - giapi.command(Command(SequenceCommand.ABORT, Activity.PRESET_START, Configuration.Zero), - DefaultCommandTimeout - ) - - def genericApply(configuration: Configuration): F[CommandResult] = - giapi.command(Command( - SequenceCommand.APPLY, - Activity.PRESET_START, - configuration - ), - DefaultCommandTimeout - ) -} - -object GiapiClient { - val DefaultCommandTimeout: FiniteDuration = 60.seconds -} diff --git a/modules/giapi/src/main/scala/giapi/client/GiapiConfig.scala b/modules/giapi/src/main/scala/giapi/client/GiapiConfig.scala deleted file mode 100644 index e32a8deda..000000000 --- a/modules/giapi/src/main/scala/giapi/client/GiapiConfig.scala +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -// Produce a configuration string for Giapi. -trait GiapiConfig[T] { - def configValue(t: T): String -} - -object GiapiConfig { - implicit val stringConfig: GiapiConfig[String] = t => t - implicit val intConfig: GiapiConfig[Int] = _.toString - implicit val doubleConfig: GiapiConfig[Double] = d => f"$d%1.6f" - implicit val floatConfig: GiapiConfig[Float] = d => f"$d%1.6f" - - @inline - def apply[A](implicit instance: GiapiConfig[A]): GiapiConfig[A] = instance - - def instance[A](f: A => String): GiapiConfig[A] = new GiapiConfig[A] { - def configValue(t: A) = f(t) - } -} diff --git a/modules/giapi/src/main/scala/giapi/client/GiapiDb.scala b/modules/giapi/src/main/scala/giapi/client/GiapiDb.scala deleted file mode 100644 index 9fd4e9aa2..000000000 --- a/modules/giapi/src/main/scala/giapi/client/GiapiDb.scala +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import cats.Applicative -import cats.effect.Concurrent -import cats.syntax.all._ -import fs2.Stream -import fs2.concurrent.SignallingRef - -sealed trait StatusValue extends Product with Serializable - -object StatusValue { - final case class IntValue(value: Int) extends StatusValue - final case class StringValue(value: String) extends StatusValue - final case class FloatValue(value: Float) extends StatusValue - final case class DoubleValue(value: Double) extends StatusValue - - def intValue(s: StatusValue): Option[Int] = s match { - case IntValue(v) => ItemGetter[Int].value(v) - case _ => none - } - def stringValue(s: StatusValue): Option[String] = s match { - case StringValue(v) => ItemGetter[String].value(v) - case _ => none - } - def floatValue(s: StatusValue): Option[Float] = s match { - case FloatValue(v) => ItemGetter[Float].value(v) - case _ => none - } - def doubleValue(s: StatusValue): Option[Double] = s match { - case DoubleValue(v) => ItemGetter[Double].value(v) - case _ => none - } -} - -///////////////////////////////////////////////////////////////// -// The GiapiDb stores values streamed from the GMP -///////////////////////////////////////////////////////////////// -trait GiapiDb[F[_]] { - - def value(i: String): F[Option[StatusValue]] - - def update[A: ItemGetter](i: String, s: A): F[Unit] - - def discrete: Stream[F, Map[String, StatusValue]] -} - -object GiapiDb { - def newDb[F[_]: Concurrent]: F[GiapiDb[F]] = - SignallingRef[F, Map[String, StatusValue]](Map.empty).map { ref => - new GiapiDb[F] { - def value(i: String): F[Option[StatusValue]] = - ref.get.map(_.get(i)) - - def update[A: ItemGetter](i: String, s: A): F[Unit] = - ItemGetter[A].value(s) match { - case Some(a: Int) => - ref.update(_ + (i -> StatusValue.IntValue(a))) - case Some(a: String) => - ref.update(_ + (i -> StatusValue.StringValue(a))) - case Some(a: Float) => - ref.update(_ + (i -> StatusValue.FloatValue(a))) - case Some(a: Double) => - ref.update(_ + (i -> StatusValue.DoubleValue(a))) - case _ => - Applicative[F].unit - } - - override def discrete: Stream[F, Map[String, StatusValue]] = ref.discrete - } - } -} diff --git a/modules/giapi/src/main/scala/giapi/client/GiapiStatusDb.scala b/modules/giapi/src/main/scala/giapi/client/GiapiStatusDb.scala deleted file mode 100644 index b2c2f53e8..000000000 --- a/modules/giapi/src/main/scala/giapi/client/GiapiStatusDb.scala +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import scala.jdk.CollectionConverters._ -import cats.Applicative -import cats.ApplicativeError -import cats.effect.{ Async, Resource, Sync } -import cats.effect.implicits._ -import cats.effect.std.{ Dispatcher, Queue } -import cats.syntax.all._ -import edu.gemini.aspen.giapi.status.StatusHandler -import edu.gemini.aspen.giapi.status.StatusItem -import edu.gemini.aspen.giapi.statusservice.StatusHandlerAggregate -import edu.gemini.aspen.giapi.util.jms.status.StatusGetter -import edu.gemini.jms.activemq.provider.ActiveMQJmsProvider -import fs2.Stream - -///////////////////////////////////////////////////////////////// -// Links status streaming with the giapi db -///////////////////////////////////////////////////////////////// -trait GiapiStatusDb[F[_]] { - - // Tries to read a value from the db and returns non if not found - def optional(i: String): F[Option[StatusValue]] - - // Tries to read a value from the db and throws an exception in not found - def value(i: String): F[StatusValue] - - def discrete: Stream[F, Map[String, StatusValue]] - - private[giapi] def close: F[Unit] -} - -object GiapiStatusDb { - private def dbUpdate[F[_]: Applicative]( - db: GiapiDb[F], - name: String, - a: Any - ): F[Unit] = - a match { - case a: Int => - db.update(name, a) - case a: String => - db.update(name, a) - case a: Float => - db.update(name, a) - case a: Double => - db.update(name, a) - case _ => - Applicative[F].unit - } - - private def streamItemsToDb[F[_]: Async]( - agg: StatusHandlerAggregate, - db: GiapiDb[F], - items: List[String] - ): F[Unit] = { - def statusHandler(q: Queue[F, (String, Any)])(dispatcher: Dispatcher[F]): StatusHandler = - new StatusHandler { - - override def update[B](item: StatusItem[B]): Unit = - // Check the item name and enqueue it - if (items.contains(item.getName)) { - Option(item.getValue).foreach { a => - dispatcher.unsafeRunAndForget(q.offer((item.getName, a))) - } - } - - override def getName: String = "Giapi status db" - } - - // A trivial resource that binds and unbinds a status handler. - def bind(q: Queue[F, (String, Any)]): Resource[F, StatusHandler] = - // The dispatcher is used only to "offer" items to a Queue, therefore sequential should be OK. - Dispatcher.sequential[F](true).flatMap { dispatcher => - Resource.make( - Async[F].delay { - val sh = statusHandler(q)(dispatcher) - agg.bindStatusHandler(sh) - sh - } - )(sh => Async[F].delay(agg.unbindStatusHandler(sh))) - } - - // Create a queue and put updates to forward them to the db - val s = for { - q <- Stream.eval(Queue.unbounded[F, (String, Any)]) - _ <- Stream.resource(bind(q)) - _ <- Stream.fromQueueUnterminated(q).evalMap { case (n, v) => dbUpdate(db, n, v) } - } yield () - s.compile.drain - } - - private def initSG[F[_]: Applicative]( - db: GiapiDb[F], - sg: StatusGetter, - items: List[String] - ): F[List[Unit]] = - sg.getAllStatusItems.asScala.toList - .collect { - case s: StatusItem[_] if items.contains(s.getName) => s - } - .traverse { s => - dbUpdate(db, s.getName, s.getValue) - } - - private def initDb[F[_]: Sync]( - c: ActiveMQJmsProvider, - db: GiapiDb[F], - items: List[String] - ): F[List[Unit]] = - Resource - .make(Giapi.statusGetter[F](c))(g => Sync[F].delay(g.stopJms())) - .use(initSG(db, _, items)) - - /** - * Creates a new status db in simulation - */ - def simulatedDb[F[_]: ApplicativeError[*[_], Throwable]]: GiapiStatusDb[F] = - new GiapiStatusDb[F] { - def optional(i: String): F[Option[StatusValue]] = - none.pure[F] - - def value(i: String): F[StatusValue] = - ApplicativeError[F, Throwable] - .raiseError( - new GiapiException("No values available in a simulated db") - ) - - def discrete: Stream[F, Map[String, StatusValue]] = - Stream.empty - - def close: F[Unit] = Applicative[F].unit - } - - /** - * Creates a new status db that listens for status items as they are produced - * - * @param url - * Url of the giapi server - * @param items - * List of items to monitor - */ - def newStatusDb[F[_]: Async]( - url: String, - items: List[String] - ): F[GiapiStatusDb[F]] = - for { - c <- Sync[F].delay(new ActiveMQJmsProvider(url)) // Build the connection - ss <- Giapi.statusStreamer[F](c) // giapi artifacts - db <- GiapiDb.newDb - _ <- initDb[F](c, db, items) // Get the initial values - f <- streamItemsToDb[F](ss.aggregate, db, items).start // run in the background - } yield new GiapiStatusDb[F] { - def optional(i: String): F[Option[StatusValue]] = - db.value(i) - - def value(i: String): F[StatusValue] = - optional(i) - .ensure(new GiapiException(s"Giapi channel $i not found"))( - _.isDefined - ) - .map { - _.orNull - } // orNull lets us typecheck but it will never be used due to the `ensure` call above - - def discrete: Stream[F, Map[String, StatusValue]] = - db.discrete - - def close: F[Unit] = - for { - _ <- Sync[F].delay(ss.ss.stopJms()) // Close the listener - _ <- Sync[F].delay(c.stopConnection()) // Disconnect from amq - _ <- Sync[F].delay(f.cancel) // Stop the fiber - } yield () - } - -} diff --git a/modules/giapi/src/main/scala/giapi/client/commands/package.scala b/modules/giapi/src/main/scala/giapi/client/commands/package.scala deleted file mode 100644 index 0082b16f0..000000000 --- a/modules/giapi/src/main/scala/giapi/client/commands/package.scala +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import scala.concurrent.duration.Duration -import scala.concurrent.duration.FiniteDuration -import scala.jdk.CollectionConverters._ - -import cats._ -import cats.effect._ -import cats.syntax.all._ -import edu.gemini.aspen.giapi.commands.Activity -import edu.gemini.aspen.giapi.commands.ConfigPath -import edu.gemini.aspen.giapi.commands.DefaultConfiguration -import edu.gemini.aspen.giapi.commands.HandlerResponse -import edu.gemini.aspen.giapi.commands.HandlerResponse.Response -import edu.gemini.aspen.giapi.commands.SequenceCommand -import edu.gemini.aspen.giapi.commands.{ Command => GiapiCommand } -import edu.gemini.aspen.giapi.commands.{ Configuration => GiapiConfiguration } -import edu.gemini.aspen.gmp.commands.jms.client.CommandSenderClient -import giapi.client.syntax.giapiconfig._ - -package commands { - - final case class CommandResult(response: Response) - final case class CommandResultException(response: Response, message: String) - extends RuntimeException - - object CommandResultException { - - def timedOut(after: FiniteDuration): CommandResultException = - CommandResultException(Response.ERROR, s"Timed out response after: $after") - } - - final case class Configuration(config: Map[ConfigPath, String]) { - - def value(path: String): Option[String] = - config.get(ConfigPath.configPath(path)) - - def contains(path: String): Boolean = - config.contains(ConfigPath.configPath(path)) - - def remove(path: String): Configuration = - Configuration(config - ConfigPath.configPath(path)) - - def toGiapi: GiapiConfiguration = - new DefaultConfiguration(new java.util.TreeMap(config.asJava)) - } - - object Configuration { - val Zero: Configuration = Configuration(Map.empty) - - def single[A: GiapiConfig](key: String, value: A): Configuration = - Configuration(Map(ConfigPath.configPath(key) -> value.configValue)) - - implicit val eq: Eq[Configuration] = Eq.by(_.config) - - implicit val monoid: Monoid[Configuration] = new Monoid[Configuration] { - def empty: Configuration = Zero - - def combine(a: Configuration, b: Configuration): Configuration = - Configuration(a.config |+| b.config) - } - } - - final case class Command( - sequenceCommand: SequenceCommand, - activity: Activity, - config: Configuration - ) { - - def toGiapi: GiapiCommand = - new GiapiCommand(sequenceCommand, activity, config.toGiapi) - } - -} - -package object commands { - val DataLabelCfg = "DATA_LABEL" - - implicit val responseEq: Eq[Response] = Eq.instance { case (a, b) => - a.name === b.name - } - - implicit val scEq: Eq[SequenceCommand] = Eq.fromUniversalEquals - - /** - * Send a command over giapi - * @param commandsClient - * Client interface to send the command to the client and await the response - * @param command - * The actual command sent - * @param timeout - * Timeout to await a response, often 2 seconds - * @tparam F - * Effect type - * @return - * the result of the operation - */ - def sendCommand[F[_]: Async]( - commandsClient: CommandSenderClient, - command: Command, - timeout: Duration - ): F[CommandResult] = - Async[F].async_ { cb => - val hr = commandsClient.sendCommand( - command.toGiapi, - (hr: HandlerResponse, _: GiapiCommand) => { - if (hr.getResponse === Response.ERROR || hr.getResponse === Response.NOANSWER) { - cb(Left(CommandResultException(hr.getResponse, hr.getMessage))) - } else { - cb(Right(CommandResult(hr.getResponse))) - } - () - }, - timeout.toMillis - ) - if (hr.getResponse === Response.ERROR || hr.getResponse === Response.NOANSWER) { - cb( - Left( - CommandResultException(hr.getResponse, - if (hr.getResponse === Response.NOANSWER) - "No answer from the instrument" - else hr.getMessage - ) - ) - ) - } else if (hr.getResponse === Response.COMPLETED) { - cb(Right(CommandResult(hr.getResponse))) - } - // A third case is ACCEPTED but that is handled on the callback - } -} diff --git a/modules/giapi/src/main/scala/giapi/client/ghost/GhostClient.scala b/modules/giapi/src/main/scala/giapi/client/ghost/GhostClient.scala deleted file mode 100644 index f82ea218c..000000000 --- a/modules/giapi/src/main/scala/giapi/client/ghost/GhostClient.scala +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client.ghost - -import scala.concurrent.duration._ -import cats.effect._ -import cats.syntax.all._ -import giapi.client.Giapi -import giapi.client.GiapiClient -import cats.effect.Temporal - -/** Client for GHOST */ -sealed trait GhostClient[F[_]] extends GiapiClient[F] - -object GhostClient { - private final class GhostClientImpl[F[_]](override val giapi: Giapi[F]) extends GhostClient[F] - - // Used for simulations - def simulatedGhostClient[F[_]: Temporal]: Resource[F, GhostClient[F]] = - Resource.eval( - Giapi.simulatedGiapiConnection[F].connect.map(new GhostClientImpl(_)) - ) - - def ghostClient[F[_]: Async]( - url: String - ): Resource[F, GhostClient[F]] = { - val ghostStatus: Resource[F, Giapi[F]] = - Resource.make(Giapi.giapiConnection[F](url).connect)(_.close) - - val ghostSequence: Resource[F, Giapi[F]] = - Resource.make(Giapi.giapiConnection[F](url).connect)(_.close) - - for { - _ <- ghostStatus - c <- ghostSequence - } yield new GhostClientImpl(c) - } -} - -object GhostExample extends IOApp { - - val url = "failover:(tcp://127.0.0.1:61616)" - - val ghostClient: Resource[IO, GhostClient[IO]] = - GhostClient.ghostClient(url) - - def run(args: List[String]): IO[ExitCode] = - ghostClient.use { client => - for { - r <- client.observe("TEST_S20180509", 5.seconds) - _ <- IO(println(r)) // scalastyle:off console.io - } yield ExitCode.Success - } - -} diff --git a/modules/giapi/src/main/scala/giapi/client/gpi/GpiClient.scala b/modules/giapi/src/main/scala/giapi/client/gpi/GpiClient.scala deleted file mode 100644 index e74c01cdf..000000000 --- a/modules/giapi/src/main/scala/giapi/client/gpi/GpiClient.scala +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client.gpi - -import scala.concurrent.duration._ -import cats.effect.Resource -import cats.syntax.all._ -import edu.gemini.aspen.giapi.commands.Activity -import edu.gemini.aspen.giapi.commands.SequenceCommand -import fs2.Stream -import giapi.client.Giapi -import giapi.client.GiapiClient -import giapi.client.GiapiStatusDb -import giapi.client.commands.Command -import giapi.client.commands.CommandResult -import giapi.client.commands.Configuration -import mouse.boolean._ -import cats.effect.Temporal -import cats.effect.kernel.Async - -sealed trait GpiClient[F[_]] extends GiapiClient[F] { - - def heartbeat: F[Int] - - def fpmMask: F[String] - - def aoDarkLevel: F[Float] - - def heartbeatS: F[Stream[F, Int]] - - def calExitShutter(position: Boolean): F[CommandResult] - - def observingMode(mode: String): F[CommandResult] - - def ifsConfigure(integrationTime: Double, coAdds: Int, readoutMode: Int): F[CommandResult] - - def alignAndCalib: F[CommandResult] - - def statusDb: GiapiStatusDb[F] -} - -object GpiClient { - val ALIGN_AND_CALIB_DEFAULT_MODE: Int = 4 - - /** - * Client for GPI - */ - final private class GpiClientImpl[F[_]]( - override val giapi: Giapi[F], - val statusDb: GiapiStatusDb[F] - ) extends GpiClient[F] { - import GiapiClient.DefaultCommandTimeout - // Align and Calib is fairly variable in duration. it can take a long time and still succeed - // The 6 minutes timeout is based on current practice but if the system is very miss aligned - // It could take longer and succeed but on the other hand we don't want to wait too long - // in case of error - val ACCommandTimeout: FiniteDuration = 6.minutes - - // ///////////// - // Status items - // ///////////// - def heartbeat: F[Int] = - giapi.get[Int]("gpi:heartbeat") - - def fpmMask: F[String] = - giapi.get[String]("gpi:fpmMask") - - def aoDarkLevel: F[Float] = - giapi.get[Float]("gpi:ao:darkLevel") - - // /////////////////// - // Streaming statuses - // /////////////////// - def heartbeatS: F[Stream[F, Int]] = - giapi.stream[Int]("gpi:heartbeat") - - // ////////////////////// - // GPI Specific commands - // ////////////////////// - - // TODO Use OCS constants for open/close - private def shutter(shutterName: String, position: Boolean): F[CommandResult] = - giapi.command(Command( - SequenceCommand.APPLY, - Activity.PRESET_START, - Configuration.single(s"gpi:selectShutter.$shutterName", position.fold(1, 0)) - ), - DefaultCommandTimeout - ) - - def entranceShutter(position: Boolean): F[CommandResult] = - shutter("entranceShutter", position) - - def calExitShutter(position: Boolean): F[CommandResult] = - shutter("calExitShutter", position) - - def calEntranceShutter(position: Boolean): F[CommandResult] = - shutter("calEntranceShutter", position) - - def calReferenceShutter(position: Boolean): F[CommandResult] = - shutter("calReferenceShutter", position) - - def calScienceShutter(position: Boolean): F[CommandResult] = - shutter("calScienceShutter", position) - - def alignAndCalib: F[CommandResult] = - giapi.command(Command( - SequenceCommand.APPLY, - Activity.PRESET_START, - Configuration.single("gpi:alignAndCalib.part1", ALIGN_AND_CALIB_DEFAULT_MODE) - ), - ACCommandTimeout - ) - - // TODO Use OCS constants - def observingMode(mode: String): F[CommandResult] = - giapi.command(Command(SequenceCommand.APPLY, - Activity.PRESET_START, - Configuration.single("gpi:observationMode.mode", mode) - ), - DefaultCommandTimeout - ) - - def ifsFilter(filter: String): F[CommandResult] = - giapi.command(Command( - SequenceCommand.APPLY, - Activity.PRESET_START, - Configuration.single("gpi:ifs:selectIfsFilter.maskStr", filter) - ), - DefaultCommandTimeout - ) - - def ifsConfigure(integrationTime: Double, coAdds: Int, readoutMode: Int): F[CommandResult] = - giapi.command( - Command( - SequenceCommand.APPLY, - Activity.PRESET_START, - List( - Configuration.single("gpi:configIfs.integrationTime", integrationTime), - Configuration.single("gpi:configIfs.numCoadds", coAdds), - Configuration.single("gpi:configIfs.readoutMode", readoutMode) - ).combineAll - ), - DefaultCommandTimeout - ) - } - - // Used for simulations - def simulatedGpiClient[F[_]: Temporal]: Resource[F, GpiClient[F]] = - Resource.eval( - Giapi - .simulatedGiapiConnection[F] - .connect - .map(new GpiClientImpl[F](_, GiapiStatusDb.simulatedDb[F])) - ) - - def gpiClient[F[_]: Async]( - url: String, - statusesToMonitor: List[String] - ): Resource[F, GpiClient[F]] = { - val giapi: Resource[F, Giapi[F]] = - Resource.make( - Giapi.giapiConnection[F](url).connect - )(_.close) - - val db: Resource[F, GiapiStatusDb[F]] = - Resource.make( - GiapiStatusDb - .newStatusDb[F](url, statusesToMonitor) - )(_.close) - - (giapi, db).mapN(new GpiClientImpl[F](_, _)).widen[GpiClient[F]] - } - -} - -object GPIExample extends cats.effect.IOApp { - - import cats.effect.IO - import cats.effect.ExitCode - import scala.concurrent.duration._ - - val url = "failover:(tcp://127.0.0.1:61616)" - - val gpi: Resource[IO, GpiClient[IO]] = - GpiClient.gpiClient[IO](url, Nil) - - val gpiStatus: IO[(Vector[Int], Int, String, Float)] = - gpi.use { client => - for { - hs <- client.heartbeatS.flatMap(_.take(3).compile.toVector) - h <- client.heartbeat - f <- client.fpmMask - o <- client.aoDarkLevel - } yield (hs, h, f, o) - } - - val gpiSequence: IO[CommandResult] = - gpi.use { client => - for { - _ <- client.calExitShutter(true) // Open the shutter - _ <- client.observingMode("Y_coron") // Change observing mode - _ <- client.ifsConfigure(1.5, 1, 4) // Configure the IFS - f <- client.observe("TEST_S20180509", 5.seconds) // observe - _ <- client.park // Park at the end - } yield f - } - - def putLn(a: Any): IO[Unit] = - IO.delay(println(a)) // scalastyle:off console.io - - def run(args: List[String]): IO[ExitCode] = - for { - _ <- gpiStatus.flatMap(putLn) - _ <- gpiSequence.flatMap(putLn) - } yield ExitCode.Success - -} diff --git a/modules/giapi/src/main/scala/giapi/client/gpi/package.scala b/modules/giapi/src/main/scala/giapi/client/gpi/package.scala deleted file mode 100644 index 06ef3b007..000000000 --- a/modules/giapi/src/main/scala/giapi/client/gpi/package.scala +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client.gpi - -import cats.Eq -import cats.syntax.all._ - -sealed trait GpiGuiding extends Product with Serializable - -object GpiGuiding { - case object Guiding extends GpiGuiding - case object NotGuiding extends GpiGuiding - - def fromInt(i: Int): GpiGuiding = if (i === 1) Guiding else NotGuiding - - implicit val eqGpiGuiding: Eq[GpiGuiding] = Eq.fromUniversalEquals -} diff --git a/modules/giapi/src/main/scala/giapi/client/package.scala b/modules/giapi/src/main/scala/giapi/client/package.scala deleted file mode 100644 index 9fba3b6b5..000000000 --- a/modules/giapi/src/main/scala/giapi/client/package.scala +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi - -import scala.concurrent.duration._ - -import cats._ -import cats.effect._ -import cats.effect.std.Queue -import cats.effect.implicits._ -import cats.syntax.all._ -import edu.gemini.aspen.giapi.commands.HandlerResponse.Response -import edu.gemini.aspen.giapi.commands.SequenceCommand -import edu.gemini.aspen.giapi.status.StatusHandler -import edu.gemini.aspen.giapi.status.StatusItem -import edu.gemini.aspen.giapi.statusservice.StatusHandlerAggregate -import edu.gemini.aspen.giapi.statusservice.StatusService -import edu.gemini.aspen.giapi.util.jms.status.StatusGetter -import edu.gemini.aspen.gmp.commands.jms.client.CommandSenderClient -import edu.gemini.jms.activemq.provider.ActiveMQJmsProvider -import fs2.Stream -import giapi.client.commands.Command -import giapi.client.commands.CommandResultException -import giapi.client.commands._ -import shapeless.Typeable._ -import cats.effect.Temporal - -package object client { - - /** - * Allowed types according to GIAPI - */ - implicit val strItemGetter: ItemGetter[String] = new ItemGetter[String] {} - - implicit val doubleItemGetter: ItemGetter[Double] = new ItemGetter[Double] {} - - implicit val intItemGetter: ItemGetter[Int] = new ItemGetter[Int] {} - - implicit val floatItemGetter: ItemGetter[Float] = new ItemGetter[Float] {} -} - -package client { - - import cats.effect.std.Dispatcher - import giapi.client.commands.CommandResult - - final case class GiapiException(str: String) extends RuntimeException(str) - - /** - * Typeclass to present as evidence when calling `Giapi.get` - */ - sealed abstract class ItemGetter[A: shapeless.Typeable] { - - /** - * Attempt to convert any value to A as sent by StatusHandler - */ - def value(p: Any): Option[A] = shapeless.Typeable[A].cast(p) - } - - object ItemGetter { - - @inline - def apply[F](implicit instance: ItemGetter[F]): ItemGetter[F] = instance - } - - /** - * Represents a connection to a GIAPi based instrument - * - * @tparam F - * Effect type - */ - trait GiapiConnection[F[_]] { - def connect: F[Giapi[F]] - } - - /** - * Algebra to interact with a GIAPI instrument - * - * @tparam F - * Effect Type - */ - trait Giapi[F[_]] { - - /** - * Returns a value for the status item. If not found or there is an error, an exception could be - * thrown - */ - def get[A: ItemGetter](statusItem: String): F[A] - - /** - * Attempts to read a value. If not found an empty F is returned - */ - def getO[A: ItemGetter](statusItem: String): F[Option[A]] - - /** - * Executes a command as defined on GIAPI Note that commands can end in ERROR or COMPLETED Giapi - * has an extra case where we have a command ACCEPTED and it will complete in the future That - * makes handling easier with callbacks on Java land but on IO-land it makes more sense to wait - * for ERROR/COMPLETED and do async calls above this level - * - * This decision may be review in the future - */ - def command(command: Command, timeout: FiniteDuration): F[CommandResult] - - /** - * Returns a stream of values for the status item. - */ - def stream[A: ItemGetter](statusItem: String): F[Stream[F, A]] - - /** - * Close the connection - */ - private[giapi] def close: F[Unit] - } - - /** - * Interpreters - */ - object Giapi { - - final case class StatusStreamer(aggregate: StatusHandlerAggregate, ss: StatusService) - - def statusGetter[F[_]: Sync](c: ActiveMQJmsProvider): F[StatusGetter] = - Sync[F].delay { - val sg = new StatusGetter("statusGetter") - sg.startJms(c) - sg - } - - private def commandSenderClient[F[_]: Applicative]( - c: ActiveMQJmsProvider - ): F[CommandSenderClient] = - Applicative[F].pure { - new CommandSenderClient(c) - } - - def statusStreamer[F[_]: Sync](c: ActiveMQJmsProvider): F[StatusStreamer] = - Sync[F].delay { - val aggregate = new StatusHandlerAggregate() - val statusService = new StatusService(aggregate, "statusService", "*") - statusService.startJms(c) - StatusStreamer(aggregate, statusService) - } - - private def streamItem[F[_]: Async, A: ItemGetter]( - agg: StatusHandlerAggregate, - statusItem: String - ): F[Stream[F, A]] = - Sync[F].delay { - - def statusHandler(q: Queue[F, A])(dispatcher: Dispatcher[F]): StatusHandler = - new StatusHandler { - - override def update[B](item: StatusItem[B]): Unit = - // Check the item name and attempt convert it to A - if (item.getName === statusItem) { - ItemGetter[A].value(item.getValue).foreach { a => - dispatcher.unsafeRunAndForget(q.offer(a)) - } - } - - override def getName: String = "StatusHandler" - } - - // A trivial resource that binds and unbinds a status handler. - def bind(q: Queue[F, A]): Resource[F, StatusHandler] = - // The dispatcher is used only to "offer" items to a Queue, therefore sequential should - // be OK. - Dispatcher.sequential[F](true).flatMap { dispatcher => - Resource.make( - Async[F].delay { - val sh = statusHandler(q)(dispatcher) - agg.bindStatusHandler(sh) - sh - } - )(sh => Async[F].delay(agg.unbindStatusHandler(sh))) - } - - // Put the items in a queue as they arrive to the stream - for { - q <- Stream.eval(Queue.unbounded[F, A]) - _ <- Stream.resource(bind(q)) - i <- Stream.fromQueueUnterminated(q) - } yield i - } - - /** - * Interpreter on F - * - * @param url - * Url to connect to - * @tparam F - * Effect type - */ - def giapiConnection[F[_]: Async]( - url: String - ): GiapiConnection[F] = - new GiapiConnection[F] { - private def giapi( - c: ActiveMQJmsProvider, - sg: StatusGetter, - cc: CommandSenderClient, - ss: StatusStreamer - ) = - new Giapi[F] { - private val commandsAckTimeout = 2000.milliseconds - - override def get[A: ItemGetter](statusItem: String): F[A] = - getO[A](statusItem).flatMap { - case Some(a) => a.pure[F] - case None => - Sync[F].raiseError(GiapiException(s"Status item $statusItem not found")) - } - - def getO[A: ItemGetter](statusItem: String): F[Option[A]] = - Sync[F].delay { - val item = sg.getStatusItem[A](statusItem) - Option(item).map(_.getValue) - } - - override def command(command: Command, timeOut: FiniteDuration): F[CommandResult] = { - val error = CommandResultException.timedOut(timeOut) - val e = ApplicativeError[F, Throwable].raiseError[CommandResult](error) - commands.sendCommand(cc, command, commandsAckTimeout).timeoutTo(timeOut, e) - } - - override def stream[A: ItemGetter](statusItem: String): F[Stream[F, A]] = - streamItem[F, A](ss.aggregate, statusItem) - - override def close: F[Unit] = - for { - _ <- Sync[F].delay(sg.stopJms()) - _ <- Sync[F].delay(ss.ss.stopJms()) - _ <- Sync[F].delay(c.stopConnection()) - } yield () - - } - - private def build(c: ActiveMQJmsProvider): F[Giapi[F]] = - for { - sg <- statusGetter[F](c) - cc <- commandSenderClient[F](c) - ss <- statusStreamer[F](c) - } yield giapi(c, sg, cc, ss) - - def connect: F[Giapi[F]] = - for { - c <- Sync[F].delay(new ActiveMQJmsProvider(url)) // Build the connection - _ <- Sync[F].delay(c.startConnection()) // Start the connection - c <- build(c) // Build the interpreter - } yield c - } - - /** - * Interpreter on Id - */ - def giapiConnectionId: GiapiConnection[Id] = new GiapiConnection[Id] { - override def connect: Id[Giapi[Id]] = new Giapi[Id] { - override def get[A: ItemGetter](statusItem: String): Id[A] = - sys.error(s"Cannot read $statusItem") - override def getO[A: ItemGetter](statusItem: String): Id[Option[A]] = None - override def stream[A: ItemGetter](statusItem: String): Id[Stream[Id, A]] = - sys.error(s"Cannot read $statusItem") - override def command(command: Command, timeout: FiniteDuration): Id[CommandResult] = - CommandResult(Response.COMPLETED) - override def close: Id[Unit] = () - } - } - - /** - * Simulator interpreter on IO, Reading items will fail and all commands will succeed - */ - def simulatedGiapiConnection[F[_]](implicit - T: Temporal[F], - F: ApplicativeError[F, Throwable] - ): GiapiConnection[F] = new GiapiConnection[F] { - override def connect: F[Giapi[F]] = F.pure(new Giapi[F] { - override def get[A: ItemGetter](statusItem: String): F[A] = - F.raiseError(new RuntimeException(s"Cannot read $statusItem")) - override def getO[A: ItemGetter](statusItem: String): F[Option[A]] = F.pure(None) - override def stream[A: ItemGetter](statusItem: String): F[Stream[F, A]] = - F.pure(Stream.empty.covary[F]) - override def command(command: Command, timeout: FiniteDuration): F[CommandResult] = - if (command.sequenceCommand === SequenceCommand.OBSERVE) { - T.sleep(timeout) *> - F.pure(CommandResult(Response.COMPLETED)) - } else { - T.sleep(5.seconds) *> - F.pure(CommandResult(Response.COMPLETED)) - } - override def close: F[Unit] = F.unit - }) - } - - } - -} diff --git a/modules/giapi/src/main/scala/giapi/client/syntax/giapiconfig.scala b/modules/giapi/src/main/scala/giapi/client/syntax/giapiconfig.scala deleted file mode 100644 index f9f9c540d..000000000 --- a/modules/giapi/src/main/scala/giapi/client/syntax/giapiconfig.scala +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client.syntax - -import giapi.client.GiapiConfig - -final class GiapiConfigOps[A](val a: A) extends AnyVal { - def configValue(implicit c: GiapiConfig[A]): String = - c.configValue(a) -} - -trait ToGiapiConfigOps { - implicit def ToGiapiConfigOps[A](value: A): GiapiConfigOps[A] = - new GiapiConfigOps(value) -} - -object giapiconfig extends ToGiapiConfigOps diff --git a/modules/giapi/src/main/scala/giapi/client/syntax/package.scala b/modules/giapi/src/main/scala/giapi/client/syntax/package.scala deleted file mode 100644 index 45fc764c5..000000000 --- a/modules/giapi/src/main/scala/giapi/client/syntax/package.scala +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -/** - * Syntax classes for GIAPI clients, organized like Cats. - */ -package object syntax { - object all extends ToGiapiConfigOps -} diff --git a/modules/giapi/src/main/scala/giapi/client/syntax/status.scala b/modules/giapi/src/main/scala/giapi/client/syntax/status.scala deleted file mode 100644 index 9c6d273ee..000000000 --- a/modules/giapi/src/main/scala/giapi/client/syntax/status.scala +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client.syntax - -import giapi.client.GiapiConfig -import giapi.client.StatusValue - -object status { - - implicit class ToGiapiStatusOps(val s: StatusValue) extends AnyVal { - def intValue: Option[Int] = StatusValue.intValue(s) - def stringValue: Option[String] = StatusValue.stringValue(s) - def floatValue: Option[Float] = StatusValue.floatValue(s) - def doubleValue: Option[Double] = StatusValue.doubleValue(s) - } - - implicit class ToGiapiStatusOpsOpt(val s: Option[StatusValue]) extends AnyVal { - def intValue: Option[Int] = s.flatMap(StatusValue.intValue) - def stringValue: Option[String] = s.flatMap(StatusValue.stringValue) - def floatValue: Option[Float] = s.flatMap(StatusValue.floatValue) - def doubleValue: Option[Double] = s.flatMap(StatusValue.doubleValue) - def intCfg(implicit ev: GiapiConfig[Int]): Option[String] = - intValue.map(ev.configValue) - def stringCfg(implicit ev: GiapiConfig[String]): Option[String] = - stringValue.map(ev.configValue) - def floatCfg(implicit ev: GiapiConfig[Float]): Option[String] = - floatValue.map(ev.configValue) - def doubleCfg(implicit ev: GiapiConfig[Double]): Option[String] = - doubleValue.map(ev.configValue) - } -} diff --git a/modules/giapi/src/main/scala/giapi/enums/GiapiStatus.scala b/modules/giapi/src/main/scala/giapi/enums/GiapiStatus.scala deleted file mode 100644 index 049de7990..000000000 --- a/modules/giapi/src/main/scala/giapi/enums/GiapiStatus.scala +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.enums - -import cats.syntax.eq._ -import lucuma.core.util.Enumerated -import lucuma.core.enums.Instrument - -/** - * Enumerated type for Giapi Status. - * @group Enumerations (Generated) - */ -sealed abstract class GiapiStatus( - val tag: String, - val instrument: Instrument, - val statusType: GiapiType, - val statusItem: String -) extends Product - with Serializable - -object GiapiStatus { - - /** @group Constructors */ - case object GpiGuiding - extends GiapiStatus("GpiGuiding", Instrument.Gpi, GiapiType.Int, "gpi:guiding") - - /** @group Constructors */ - case object GpiAlignAndCalibState - extends GiapiStatus("GpiAlignAndCalibState", - Instrument.Gpi, - GiapiType.Int, - "gpi:alignCalibMode" - ) - - /** All members of GiapiStatus, in canonical order. */ - val all: List[GiapiStatus] = - List(GpiGuiding, GpiAlignAndCalibState) - - /** Select the member of GiapiStatus with the given tag, if any. */ - def fromTag(s: String): Option[GiapiStatus] = - all.find(_.tag === s) - - /** Select the member of GiapiStatus with the given tag, throwing if absent. */ - def unsafeFromTag(s: String): GiapiStatus = - fromTag(s).getOrElse(throw new NoSuchElementException(s"GiapiStatus: Invalid tag: '$s'")) - - /** @group Typeclass Instances */ - implicit val GiapiStatusEnumerated: Enumerated[GiapiStatus] = - new Enumerated[GiapiStatus] { - def all = GiapiStatus.all - def tag(a: GiapiStatus) = a.tag - override def unsafeFromTag(s: String): GiapiStatus = - GiapiStatus.unsafeFromTag(s) - } - -} diff --git a/modules/giapi/src/main/scala/giapi/enums/GiapiStatusApply.scala b/modules/giapi/src/main/scala/giapi/enums/GiapiStatusApply.scala deleted file mode 100644 index 55c33b1f5..000000000 --- a/modules/giapi/src/main/scala/giapi/enums/GiapiStatusApply.scala +++ /dev/null @@ -1,1896 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.enums - -import cats.syntax.eq._ -import lucuma.core.util.Enumerated -import lucuma.core.enums.Instrument - -/** - * Enumerated type for Giapi Status Apply. - * @group Enumerations (Generated) - */ -sealed abstract class GiapiStatusApply( - val tag: String, - val instrument: Instrument, - val statusType: GiapiType, - val statusItem: String, - val applyItem: String, - val tolerance: Option[BigDecimal] -) extends Product - with Serializable - -object GiapiStatusApply { - - /** @group Constructors */ - case object GpiAdc - extends GiapiStatusApply("GpiAdc", - Instrument.Gpi, - GiapiType.Int, - "gpi:adcDeploy", - "gpi:selectAdc.deploy", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiUseAo - extends GiapiStatusApply("GpiUseAo", - Instrument.Gpi, - GiapiType.Int, - "gpi:ao:useAo", - "gpi:configAo.useAo", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiAoOptimize - extends GiapiStatusApply("GpiAoOptimize", - Instrument.Gpi, - GiapiType.Int, - "gpi:ao:optimization", - "gpi:configAo.optimize", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiUseCal - extends GiapiStatusApply("GpiUseCal", - Instrument.Gpi, - GiapiType.Int, - "gpi:cal:useCal", - "gpi:configCal.useCal", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiFpmPinholeBias - extends GiapiStatusApply("GpiFpmPinholeBias", - Instrument.Gpi, - GiapiType.Int, - "gpi:cal:fpmPinholeBias", - "gpi:configCal.fpmPinholeBias", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIntegrationTime - extends GiapiStatusApply("GpiIntegrationTime", - Instrument.Gpi, - GiapiType.Float, - "gpi:currentIntegrationTime", - "gpi:configIfs.integrationTime", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiNumCoadds - extends GiapiStatusApply("GpiNumCoadds", - Instrument.Gpi, - GiapiType.Int, - "gpi:currentNumCoadds", - "gpi:configIfs.numCoadds", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiMagI - extends GiapiStatusApply("GpiMagI", - Instrument.Gpi, - GiapiType.Float, - "gpi:starIntensity", - "gpi:configAo.magnitudeI", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiMagH - extends GiapiStatusApply("GpiMagH", - Instrument.Gpi, - GiapiType.Float, - "gpi:cal:magH", - "gpi:configCal.magnitudeH", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiCalEntranceShutter - extends GiapiStatusApply("GpiCalEntranceShutter", - Instrument.Gpi, - GiapiType.Int, - "gpi:calEntranceShutter", - "gpi:selectShutter.calEntranceShutter", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiCalReferenceShutter - extends GiapiStatusApply("GpiCalReferenceShutter", - Instrument.Gpi, - GiapiType.Int, - "gpi:referenceShutter", - "gpi:selectShutter.calReferenceShutter", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiCalScienceShutter - extends GiapiStatusApply("GpiCalScienceShutter", - Instrument.Gpi, - GiapiType.Int, - "gpi:scienceShutter", - "gpi:selectShutter.calScienceShutter", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiEntranceShutter - extends GiapiStatusApply("GpiEntranceShutter", - Instrument.Gpi, - GiapiType.Int, - "gpi:omssEntranceShutter", - "gpi:selectShutter.entranceShutter", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiCalExitShutter - extends GiapiStatusApply("GpiCalExitShutter", - Instrument.Gpi, - GiapiType.Int, - "gpi:calExitShutter", - "gpi:selectShutter.calExitShutter", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiPupilCamera - extends GiapiStatusApply("GpiPupilCamera", - Instrument.Gpi, - GiapiType.Int, - "gpi:pupilViewingMirror", - "gpi:selectPupilCamera.deploy", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiSCPower - extends GiapiStatusApply("GpiSCPower", - Instrument.Gpi, - GiapiType.Float, - "gpi:artificialSourceSCpower", - "gpi:selectSource.sourceSCpower", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiSCAttenuation - extends GiapiStatusApply("GpiSCAttenuation", - Instrument.Gpi, - GiapiType.Float, - "gpi:artificialSourceSCDb", - "gpi:selectSource.sourceSCatten", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiSrcVis - extends GiapiStatusApply("GpiSrcVis", - Instrument.Gpi, - GiapiType.Int, - "gpi:artificialSourceVIS", - "gpi:selectSource.sourceVis", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiSrcIR - extends GiapiStatusApply("GpiSrcIR", - Instrument.Gpi, - GiapiType.Int, - "gpi:artificialSourceIR", - "gpi:selectSource.sourceIr", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiPolarizerDeplay - extends GiapiStatusApply("GpiPolarizerDeplay", - Instrument.Gpi, - GiapiType.Int, - "gpi:polarModulatorDeploy", - "gpi:configPolarizer.deploy", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiObservationMode - extends GiapiStatusApply("GpiObservationMode", - Instrument.Gpi, - GiapiType.String, - "gpi:observationMode", - "gpi:observationMode.mode", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIFSFilter - extends GiapiStatusApply("GpiIFSFilter", - Instrument.Gpi, - GiapiType.String, - "gpi:ifsFilter", - "gpi:ifs:selectIfsFilter.maskStr", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiPPM - extends GiapiStatusApply("GpiPPM", - Instrument.Gpi, - GiapiType.String, - "gpi:ppmMask", - "gpi:selectPupilPlaneMask.maskStr", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiFPM - extends GiapiStatusApply("GpiFPM", - Instrument.Gpi, - GiapiType.String, - "gpi:fpmMask", - "gpi:selectFocalPlaneMask.maskStr", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiLyot - extends GiapiStatusApply("GpiLyot", - Instrument.Gpi, - GiapiType.String, - "gpi:lyotMask", - "gpi:selectLyotMask.maskStr", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiAlignAndCalib - extends GiapiStatusApply("GpiAlignAndCalib", - Instrument.Gpi, - GiapiType.Int, - "gpi:alignAndCalib.part1", - "gpi:alignAndCalib.part1", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIFSReadMode - extends GiapiStatusApply("GpiIFSReadMode", - Instrument.Gpi, - GiapiType.Int, - "gpi:currentReadMode", - "gpi:configIfs.readoutMode", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIFSStartX - extends GiapiStatusApply("GpiIFSStartX", - Instrument.Gpi, - GiapiType.Int, - "gpi:currentStartX", - "gpi:gpi:configIfs.startx", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIFSStartY - extends GiapiStatusApply("GpiIFSStartY", - Instrument.Gpi, - GiapiType.Int, - "gpi:currentStartY", - "gpi:gpi:configIfs.starty", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIFSEndX - extends GiapiStatusApply("GpiIFSEndX", - Instrument.Gpi, - GiapiType.Int, - "gpi:currentEndX", - "gpi:gpi:configIfs.endx", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiIFSEndY - extends GiapiStatusApply("GpiIFSEndY", - Instrument.Gpi, - GiapiType.Int, - "gpi:currentEndY", - "gpi:gpi:configIfs.endy", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GpiPolarizerAngle - extends GiapiStatusApply("GpiPolarizerAngle", - Instrument.Gpi, - GiapiType.Float, - "gpi:polarizerAngle", - "gpi:configPolarizer.angle", - Some(1.0000) - ) - - /** @group Constructors */ - case object GhostAdc1 - extends GiapiStatusApply("GhostAdc1", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:adc1.type", - "ghost:cc:cu:adc1.type", - None - ) - - /** @group Constructors */ - case object GhostAdc2 - extends GiapiStatusApply("GhostAdc2", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:adc2.type", - "ghost:cc:cu:adc2.type", - None - ) - - /** @group Constructors */ - case object GhostFiberAgitator1 - extends GiapiStatusApply("GhostFiberAgitator1", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:slu:fa1.active", - "ghost:cc:slu:fa1.type", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostFiberAgitator2 - extends GiapiStatusApply("GhostFiberAgitator2", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:slu:fa2.active", - "ghost:cc:slu:fa2.type", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostRedExposureTime - extends GiapiStatusApply("GhostRedExposureTime", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:red.exposedRQ", - "ghost:dc:red.duration", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostRedExposureCount - extends GiapiStatusApply("GhostRedExposureCount", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.repeat", - "ghost:dc:red.repeat", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostRedBinningRcf - extends GiapiStatusApply("GhostRedBinningRcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red:binx", - "ghost:dc:red.rcf", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostRedBinningCcf - extends GiapiStatusApply("GhostRedBinningCcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red:biny", - "ghost:dc:red.ccf", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostRedUnit - extends GiapiStatusApply("GhostRedUnit", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:red.unit", - "ghost:dc:red.unit", - None - ) - - /** @group Constructors */ - case object GhostRedRequestType - extends GiapiStatusApply("GhostRedRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:red.request_type", - "ghost:dc:red.request_type", - None - ) - - /** @group Constructors */ - case object GhostRedRepeat - extends GiapiStatusApply("GhostRedRepeat", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.repeat", - "ghost:dc:red.repeat", - None - ) - - /** @group Constructors */ - case object GhostRedReadMode - extends GiapiStatusApply("GhostRedReadMode", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.read_mode", - "ghost:dc:red.read_mode", - None - ) - - /** @group Constructors */ - case object GhostRedImageType - extends GiapiStatusApply("GhostRedImageType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:red.imagetyp", - "ghost:dc:red.imagetyp", - None - ) - - /** @group Constructors */ - case object GhostRedDoDisplay - extends GiapiStatusApply("GhostRedDoDisplay", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.do_display", - "ghost:dc:red.do_display", - None - ) - - /** @group Constructors */ - case object GhostRedDoFlush - extends GiapiStatusApply("GhostRedDoFlush", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.do_flush", - "ghost:dc:red.do_flush", - None - ) - - /** @group Constructors */ - case object GhostRedDoContinuous - extends GiapiStatusApply("GhostRedDoContinous", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.do_continuous", - "ghost:dc:red.do_continuous", - None - ) - - /** @group Constructors */ - case object GhostRedDoReadout - extends GiapiStatusApply("GhostRedDoReadout", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.do_readout", - "ghost:dc:red.do_readout", - None - ) - - /** @group Constructors */ - case object GhostRedDoSave - extends GiapiStatusApply("GhostRedDoSave", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:red.do_save", - "ghost:dc:red.do_save", - None - ) - - /** @group Constructors */ - case object GhostRedCcdType - extends GiapiStatusApply("GhostRedCcdType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:red.ccd_type", - "ghost:dc:red.ccd_type", - None - ) - - /** @group Constructors */ - case object GhostRedCcdRequestType - extends GiapiStatusApply("GhostRedCcdRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:red.ccd_request_type", - "ghost:dc:red.ccd_request_type", - None - ) - - /** @group Constructors */ - case object GhostRedDuration - extends GiapiStatusApply("GhostRedDuration", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:red.duration", - "ghost:dc:red.duration", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostBlueExposureTime - extends GiapiStatusApply("GhostBlueExposureTime", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:blue.exposedRQ", - "ghost:dc:blue.duration", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostBlueExposureCount - extends GiapiStatusApply("GhostBlueExposureCount", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.repeat:GhostBlue.repeat", - "ghost:dc:blue.repeat", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostBlueBinningRcf - extends GiapiStatusApply("GhostBlueBinningRcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue:binx", - "ghost:dc:blue.rcf", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostBlueBinningCcf - extends GiapiStatusApply("GhostBlueBinningCcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue:biny", - "ghost:dc:blue.ccf", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostBlueUnit - extends GiapiStatusApply("GhostBlueUnit", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:blue.unit", - "ghost:dc:blue.unit", - None - ) - - /** @group Constructors */ - case object GhostBlueRequestType - extends GiapiStatusApply("GhostBlueRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:blue.request_type", - "ghost:dc:blue.request_type", - None - ) - - /** @group Constructors */ - case object GhostBlueRepeat - extends GiapiStatusApply("GhostBlueRepeat", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.repeat", - "ghost:dc:blue.repeat", - None - ) - - /** @group Constructors */ - case object GhostBlueReadMode - extends GiapiStatusApply("GhostBlueReadMode", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.read_mode", - "ghost:dc:blue.read_mode", - None - ) - - /** @group Constructors */ - case object GhostBlueImageType - extends GiapiStatusApply("GhostBlueImageType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:blue.imagetyp", - "ghost:dc:blue.imagetyp", - None - ) - - /** @group Constructors */ - case object GhostBlueDoDisplay - extends GiapiStatusApply("GhostBlueDoDisplay", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.do_display", - "ghost:dc:blue.do_display", - None - ) - - /** @group Constructors */ - case object GhostBlueDoFlush - extends GiapiStatusApply("GhostBlueDoFlush", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.do_flush", - "ghost:dc:blue.do_flush", - None - ) - - /** @group Constructors */ - case object GhostBlueDoContinuous - extends GiapiStatusApply("GhostBlueDoContinous", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.do_continuous", - "ghost:dc:blue.do_continuous", - None - ) - - /** @group Constructors */ - case object GhostBlueDoReadout - extends GiapiStatusApply("GhostBlueDoReadout", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.do_readout", - "ghost:dc:blue.do_readout", - None - ) - - /** @group Constructors */ - case object GhostBlueDoSave - extends GiapiStatusApply("GhostBlueDoSave", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:blue.do_save", - "ghost:dc:blue.do_save", - None - ) - - /** @group Constructors */ - case object GhostBlueCcdType - extends GiapiStatusApply("GhostBlueCcdType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:blue.ccd_type", - "ghost:dc:blue.ccd_type", - None - ) - - /** @group Constructors */ - case object GhostBlueCcdRequestType - extends GiapiStatusApply("GhostBlueCcdRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:blue.ccd_request_type", - "ghost:dc:blue.ccd_request_type", - None - ) - - /** @group Constructors */ - case object GhostBlueDuration - extends GiapiStatusApply("GhostBlueDuration", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:blue.duration", - "ghost:dc:blue.duration", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU1Type - extends GiapiStatusApply("GhostIFU1Type", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:cu:ifu1.type", - "ghost:cc:cu:ifu1.type", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU1X - extends GiapiStatusApply("GhostIFU1X", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.fpx", - "ghost:cc:cu:ifu1.fpx", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU1Y - extends GiapiStatusApply("GhostIFU1Y", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.fpy", - "ghost:cc:cu:ifu1.fpy", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU1MoveMode - extends GiapiStatusApply("GhostIFU1MoveMode", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.move_mode", - "ghost:cc:cu:ifu1.move_mode", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU2Type - extends GiapiStatusApply("GhostIFU2Type", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:cu:ifu2.type", - "ghost:cc:cu:ifu2.type", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU2X - extends GiapiStatusApply("GhostIFU2X", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.fpx", - "ghost:cc:cu:ifu2.fpx", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU2Y - extends GiapiStatusApply("GhostIFU2Y", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.fpy", - "ghost:cc:cu:ifu2.fpy", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU2MoveMode - extends GiapiStatusApply("GhostIFU2MoveMode", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.move_mode", - "ghost:cc:cu:ifu2.move_mode", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU1Target - extends GiapiStatusApply("GhostIFU1Target", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:cu:ifu1.target", - "ghost:cc:cu:ifu1.target", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU2Target - extends GiapiStatusApply("GhostIFU2Target", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:cu:ifu2.target", - "ghost:cc:cu:ifu2.target", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU1Bundle - extends GiapiStatusApply("GhostIFU1Bundle", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:cu:ifu1.bundle", - "ghost:cc:cu:ifu1.bundle", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostIFU2Bundle - extends GiapiStatusApply("GhostIFU2Bundle", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:cu:ifu2.bundle", - "ghost:cc:cu:ifu2.bundle", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostSRIFU1CoordsRADeg - extends GiapiStatusApply("GhostSRIFU1CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.ra", - "ghost:cc:cu:ifu1.ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostSRIFU1CoordsDecDeg - extends GiapiStatusApply("GhostSRIFU1CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.dec", - "ghost:cc:cu:ifu1.dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostSRIFU2CoordsRADeg - extends GiapiStatusApply("GhostSRIFU2CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.ra", - "ghost:cc:cu:ifu2.ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostSRIFU2CoordsDecDeg - extends GiapiStatusApply("GhostSRIFU2CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.dec", - "ghost:cc:cu:ifu2.dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostHRIFU1CoordsRADeg - extends GiapiStatusApply("GhostHRIFU1CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.ra", - "ghost:cc:cu:ifu1.ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostHRIFU1CoordsDecDeg - extends GiapiStatusApply("GhostHRIFU1CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu1.dec", - "ghost:cc:cu:ifu1.dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostHRIFU2CoordsRADeg - extends GiapiStatusApply("GhostHRIFU2CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.ra", - "ghost:cc:cu:ifu2.ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostHRIFU2CoordsDecDeg - extends GiapiStatusApply("GhostHRIFU2CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:cc:cu:ifu2.dec", - "ghost:cc:cu:ifu2.dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget1Name - extends GiapiStatusApply( - "GhostUserTarget1Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target1_name", - "ghost:cc:cu:targets.target1_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget1CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget1CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target1_ra", - "ghost:cc:cu:targets.target1_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget1CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget1CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target1_dec", - "ghost:cc:cu:targets.target1_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget2Name - extends GiapiStatusApply( - "GhostUserTarget2Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target2_name", - "ghost:cc:cu:targets.target2_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget2CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget2CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target2_ra", - "ghost:cc:cu:targets.target2_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget2CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget2CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target2_dec", - "ghost:cc:cu:targets.target2_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget3Name - extends GiapiStatusApply( - "GhostUserTarget3Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target3_name", - "ghost:cc:cu:targets.target3_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget3CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget3CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target3_ra", - "ghost:cc:cu:targets.target3_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget3CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget3CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target3_dec", - "ghost:cc:cu:targets.target3_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget4Name - extends GiapiStatusApply( - "GhostUserTarget4Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target4_name", - "ghost:cc:cu:targets.target4_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget4CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget4CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target4_ra", - "ghost:cc:cu:targets.target4_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget4CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget4CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target4_dec", - "ghost:cc:cu:targets.target4_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget5Name - extends GiapiStatusApply( - "GhostUserTarget5Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target5_name", - "ghost:cc:cu:targets.target5_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget5CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget5CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target5_ra", - "ghost:cc:cu:targets.target5_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget5CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget5CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target5_dec", - "ghost:cc:cu:targets.target5_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget6Name - extends GiapiStatusApply( - "GhostUserTarget6Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target6_name", - "ghost:cc:cu:targets.target6_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget6CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget6CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target6_ra", - "ghost:cc:cu:targets.target6_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget6CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget6CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target6_dec", - "ghost:cc:cu:targets.target6_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget7Name - extends GiapiStatusApply( - "GhostUserTarget7Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target7_name", - "ghost:cc:cu:targets.target7_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget7CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget7CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target7_ra", - "ghost:cc:cu:targets.target7_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget7CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget7CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target7_dec", - "ghost:cc:cu:targets.target7_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget8Name - extends GiapiStatusApply( - "GhostUserTarget8Name", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:cu:targets.target8_name", - "ghost:cc:cu:targets.target8_name", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget8CoordsRADeg - extends GiapiStatusApply( - "GhostUserTarget8CoordsRADeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target8_ra", - "ghost:cc:cu:targets.target8_ra", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTarget8CoordsDecDeg - extends GiapiStatusApply( - "GhostUserTarget8CoordsDecDeg", - Instrument.Ghost, - GiapiType.Double, - "ghost:cc:cu:targets.target8_dec", - "ghost:cc:cu:targets.target8_dec", - Option.empty[BigDecimal] - ) - - /** @group Constructors */ - case object GhostUserTargetCount - extends GiapiStatusApply( - "GhostUserTargetCount", - Instrument.Ghost, - GiapiType.Int, - "ghost:cc:cu:targets.targets.n_targets", - "ghost:cc:cu:targets.targets.n_targets", - Option.empty[BigDecimal] - ) - - // SlitViemw - /** @group Constructors */ - case object GhostSVCcdRequestType - extends GiapiStatusApply("GhostSVCcdRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:sv.ccd_request_type", - "ghost:dc:sv.ccd_request_type", - None - ) - - /** @group Constructors */ - case object GhostSVRequestType - extends GiapiStatusApply("GhostSVRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:sv.request_type", - "ghost:dc:sv.request_type", - None - ) - - /** @group Constructors */ - case object GhostSVRepeat - extends GiapiStatusApply("GhostSVRepeat", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.repeat", - "ghost:dc:sv.repeat", - None - ) - - /** @group Constructors */ - case object GhostSVRunNumber - extends GiapiStatusApply("GhostSVRunNumber", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.run_number", - "ghost:dc:sv.run_number", - None - ) - - /** @group Constructors */ - case object GhostSVDuration - extends GiapiStatusApply("GhostSVDuration", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.duration", - "ghost:dc:sv.duration", - None - ) - - /** @group Constructors */ - case object GhostSVUnit - extends GiapiStatusApply("GhostSVUnit", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.unit", - "ghost:dc:sv.unit", - None - ) - - /** @group Constructors */ - case object GhostSVDoSave - extends GiapiStatusApply("GhostSVDoSave", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.do_save", - "ghost:dc:sv.do_save", - None - ) - - /** @group Constructors */ - case object GhostSVDoDisplay - extends GiapiStatusApply("GhostSVDoDisplay", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.do_display", - "ghost:dc:sv.do_display", - None - ) - - /** @group Constructors */ - case object GhostSVRcf - extends GiapiStatusApply("GhostSVRcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.rcf", - "ghost:dc:sv.rcf", - None - ) - - /** @group Constructors */ - case object GhostSVCcf - extends GiapiStatusApply("GhostSVCcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.ccf", - "ghost:dc:sv.ccf", - None - ) - - /** @group Constructors */ - case object GhostSVImageType - extends GiapiStatusApply("GhostSVImageType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:sv.imagetyp", - "ghost:dc:sv.imagetyp", - None - ) - - /** @group Constructors */ - case object GhostSVNRegions - extends GiapiStatusApply("GhostSVNRegions", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.nregions", - "ghost:dc:sv.nregions", - None - ) - - /** @group Constructors */ - case object GhostSVXO - extends GiapiStatusApply("GhostSVXO", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.xo", - "ghost:dc:sv.xo", - None - ) - - /** @group Constructors */ - case object GhostSVYO - extends GiapiStatusApply("GhostSVYO", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.yo", - "ghost:dc:sv.yo", - None - ) - - /** @group Constructors */ - case object GhostSVWidth - extends GiapiStatusApply("GhostSVWidth", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.width", - "ghost:dc:sv.width", - None - ) - - /** @group Constructors */ - case object GhostSVHeigth - extends GiapiStatusApply("GhostSVHeight", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.height", - "ghost:dc:sv.height", - None - ) - - /** @group Constructors */ - case object GhostSVIFU1BlueThreshold - extends GiapiStatusApply("GhostSVIFU1BlueThreshold", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.ifu1bluethreshold", - "ghost:dc:sv.ifu1bluethreshold", - None - ) - - /** @group Constructors */ - case object GhostSVIFU1BlueThresholdEnabled - extends GiapiStatusApply( - "GhostSVIFU1BlueThresholdEnabled", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.ifu1bluethreshold_enabled", - "ghost:dc:sv.ifu1bluethreshold_enabled", - None - ) - - /** @group Constructors */ - case object GhostSVIFU1RedThreshold - extends GiapiStatusApply("GhostSVIFU1RedThreshold", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.ifu1redthreshold", - "ghost:dc:sv.ifu1redthreshold", - None - ) - - /** @group Constructors */ - case object GhostSVIFU1RedThresholdEnabled - extends GiapiStatusApply( - "GhostSVIFU1RedThresholdEnabled", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.ifu1redthreshold_enabled", - "ghost:dc:sv.ifu1redthreshold_enabled", - None - ) - - /** @group Constructors */ - case object GhostSVIFU2BlueThreshold - extends GiapiStatusApply("GhostSVIFU2BlueThreshold", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.ifu2bluethreshold", - "ghost:dc:sv.ifu2bluethreshold", - None - ) - - /** @group Constructors */ - case object GhostSVIFU2BlueThresholdEnabled - extends GiapiStatusApply( - "GhostSVIFU2BlueThresholdEnabled", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.ifu2bluethreshold_enabled", - "ghost:dc:sv.ifu2bluethreshold_enabled", - None - ) - - /** @group Constructors */ - case object GhostSVIFU2RedThreshold - extends GiapiStatusApply("GhostSVIFU2RedThreshold", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.ifu2redthreshold", - "ghost:dc:sv.ifu2redthreshold", - None - ) - - /** @group Constructors */ - case object GhostSVIFU2RedThresholdEnabled - extends GiapiStatusApply( - "GhostSVIFU2RedThresholdEnabled", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.ifu2redthreshold_enabled", - "ghost:dc:sv.ifu2redthreshold_enabled", - None - ) - - /** @group Constructors */ - case object GhostSVHIBlueThreshold - extends GiapiStatusApply("GhostSVHIBlueThreshold", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.hibluethreshold", - "ghost:dc:sv.hibluethreshold", - None - ) - - /** @group Constructors */ - case object GhostSVHIBlueThresholdEnabled - extends GiapiStatusApply("GhostSVHIBlueThresholdEnabled", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.hibluethreshold_enabled", - "ghost:dc:sv.hibluethreshold_enabled", - None - ) - - /** @group Constructors */ - case object GhostSVHIRedThreshold - extends GiapiStatusApply("GhostSVHIRedThreshold", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:sv.hiredthreshold", - "ghost:dc:sv.hiredthreshold", - None - ) - - /** @group Constructors */ - case object GhostSVHIRedThresholdEnabled - extends GiapiStatusApply("GhostSVHIRedThresholdEnabled", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.hiredthreshold_enabled", - "ghost:dc:sv.hiredthreshold_enabled", - None - ) - - /** @group Constructors */ - case object GhostSVZeroAccumulatedFlux - extends GiapiStatusApply("GhostSVZeroAccumulatedFlux", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.zero_accumulated_flux", - "ghost:dc:sv.zero_accumulated_flux", - None - ) - - /** @group Constructors */ - case object GhostSVDoContinuous - extends GiapiStatusApply("GhostSVDoContinuous", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:sv.do_continuous", - "ghost:dc:sv.do_continuous", - None - ) - - // Guiding Camera - /** @group Constructors */ - case object GhostAGCcdRequestType - extends GiapiStatusApply("GhostAGCcdRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:ag.ccd_request_type", - "ghost:dc:ag.ccd_request_type", - None - ) - - /** @group Constructors */ - case object GhostAGRequestType - extends GiapiStatusApply("GhostAGRequestType", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:dc:ag.request_type", - "ghost:dc:ag.request_type", - None - ) - - /** @group Constructors */ - case object GhostAGRepeat - extends GiapiStatusApply("GhostAGRepeat", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.repeat", - "ghost:dc:ag.repeat", - None - ) - - /** @group Constructors */ - case object GhostAGDuration - extends GiapiStatusApply("GhostAGDuration", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.duration", - "ghost:dc:ag.duration", - None - ) - - /** @group Constructors */ - case object GhostAGUnit - extends GiapiStatusApply("GhostAGUnit", - Instrument.Ghost, - GiapiType.Double, - "ghost:sad:dc:ag.unit", - "ghost:dc:ag.unit", - None - ) - - /** @group Constructors */ - case object GhostAGDoSave - extends GiapiStatusApply("GhostAGDoSave", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.do_save", - "ghost:dc:ag.do_save", - None - ) - - /** @group Constructors */ - case object GhostAGDoDisplay - extends GiapiStatusApply("GhostAGDoDisplay", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.do_display", - "ghost:dc:ag.do_display", - None - ) - - /** @group Constructors */ - case object GhostAGRcf - extends GiapiStatusApply("GhostAGRcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.rcf", - "ghost:dc:ag.rcf", - None - ) - - /** @group Constructors */ - case object GhostAGCcf - extends GiapiStatusApply("GhostAGCcf", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.ccf", - "ghost:dc:ag.ccf", - None - ) - - /** @group Constructors */ - case object GhostAGXO - extends GiapiStatusApply("GhostAGXO", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.xo", - "ghost:dc:ag.xo", - None - ) - - /** @group Constructors */ - case object GhostAGYO - extends GiapiStatusApply("GhostAGYO", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.yo", - "ghost:dc:ag.yo", - None - ) - - /** @group Constructors */ - case object GhostAGWidth - extends GiapiStatusApply("GhostAGWidth", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.width", - "ghost:dc:ag.width", - None - ) - - /** @group Constructors */ - case object GhostAGHeigth - extends GiapiStatusApply("GhostAGHeight", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.height", - "ghost:dc:ag.height", - None - ) - - /** @group Constructors */ - case object GhostAGEnableGuide - extends GiapiStatusApply("GhostAGEnableGuide", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.enable_guide", - "ghost:dc:ag.enable_guide", - None - ) - - /** @group Constructors */ - case object GhostAGBackground - extends GiapiStatusApply("GhostAGBackground", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.background", - "ghost:dc:ag.background", - None - ) - - /** @group Constructors */ - case object GhostAGSimulateFlux - extends GiapiStatusApply("GhostAGSimulateFlux", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.simulate_flux", - "ghost:dc:ag.simulate_flux", - None - ) - - /** @group Constructors */ - case object GhostAGDoContinuous - extends GiapiStatusApply("GhostAGDoContinuous", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:dc:ag.do_continuous", - "ghost:dc:ag.do_continuous", - None - ) - - /** @group Constructors */ - case object GhostThXeLamp - extends GiapiStatusApply("GhostThXeLamp", - Instrument.Ghost, - GiapiType.Int, - "ghost:sad:cc:slu:hclPower.value", - "ghost:cc:slu:ins.hclPowerCtl", - None - ) - - /** @group Constructors */ - case object GhostSlitMaskPositioner - extends GiapiStatusApply("GhostSlitMaskPositioner", - Instrument.Ghost, - GiapiType.String, - "ghost:sad:cc:slu:smp.position", - "ghost:cc:slu:smp.position", - None - ) - - /** @group Constructors */ - case object GhostSlitMaskPositionerType - extends GiapiStatusApply("GhostSlitMaskPositionerType", - Instrument.Ghost, - GiapiType.String, - "ghost:cc:slu:smp.type", - "ghost:cc:slu:smp.type", - None - ) - - /** All members of GiapiStatusApply, in canonical order. */ - val all: List[GiapiStatusApply] = - List( - GpiAdc, - GpiUseAo, - GpiAoOptimize, - GpiUseCal, - GpiFpmPinholeBias, - GpiIntegrationTime, - GpiNumCoadds, - GpiMagI, - GpiMagH, - GpiCalEntranceShutter, - GpiCalReferenceShutter, - GpiCalScienceShutter, - GpiEntranceShutter, - GpiCalExitShutter, - GpiPupilCamera, - GpiSCPower, - GpiSCAttenuation, - GpiSrcVis, - GpiSrcIR, - GpiPolarizerDeplay, - GpiObservationMode, - GpiIFSFilter, - GpiPPM, - GpiFPM, - GpiLyot, - GpiAlignAndCalib, - GpiIFSReadMode, - GpiIFSStartX, - GpiIFSStartY, - GpiIFSEndX, - GpiIFSEndY, - GpiPolarizerAngle, - GhostAdc1, - GhostAdc2, - GhostFiberAgitator1, - GhostFiberAgitator2, - GhostRedExposureTime, - GhostRedExposureCount, - GhostRedBinningRcf, - GhostRedBinningCcf, - GhostRedUnit, - GhostRedRequestType, - GhostRedRepeat, - GhostRedReadMode, - GhostRedImageType, - GhostRedDoDisplay, - GhostRedDoFlush, - GhostRedDoContinuous, - GhostRedDoReadout, - GhostRedDoSave, - GhostRedDoSave, - GhostRedCcdType, - GhostRedCcdRequestType, - GhostRedDuration, - GhostBlueExposureTime, - GhostBlueExposureCount, - GhostBlueBinningRcf, - GhostBlueBinningCcf, - GhostBlueUnit, - GhostBlueRequestType, - GhostBlueRepeat, - GhostBlueReadMode, - GhostBlueImageType, - GhostBlueDoDisplay, - GhostBlueDoFlush, - GhostBlueDoContinuous, - GhostBlueDoReadout, - GhostBlueDoSave, - GhostBlueDoSave, - GhostBlueCcdType, - GhostBlueCcdRequestType, - GhostBlueDuration, - GhostIFU1Type, - GhostIFU1X, - GhostIFU1Y, - GhostIFU1MoveMode, - GhostIFU2Type, - GhostIFU2X, - GhostIFU2Y, - GhostIFU2MoveMode, - GhostIFU1Target, - GhostIFU2Target, - GhostIFU1Bundle, - GhostIFU2Bundle, - GhostSRIFU1CoordsRADeg, - GhostSRIFU1CoordsDecDeg, - GhostSRIFU2CoordsRADeg, - GhostSRIFU2CoordsDecDeg, - GhostHRIFU1CoordsRADeg, - GhostHRIFU1CoordsDecDeg, - GhostHRIFU2CoordsRADeg, - GhostHRIFU2CoordsDecDeg, - GhostUserTarget1Name, - GhostUserTarget1CoordsRADeg, - GhostUserTarget1CoordsDecDeg, - GhostUserTarget2Name, - GhostUserTarget2CoordsRADeg, - GhostUserTarget2CoordsDecDeg, - GhostUserTarget3Name, - GhostUserTarget3CoordsRADeg, - GhostUserTarget3CoordsDecDeg, - GhostUserTarget4Name, - GhostUserTarget4CoordsRADeg, - GhostUserTarget4CoordsDecDeg, - GhostUserTarget5Name, - GhostUserTarget5CoordsRADeg, - GhostUserTarget5CoordsDecDeg, - GhostUserTarget6Name, - GhostUserTarget6CoordsRADeg, - GhostUserTarget6CoordsDecDeg, - GhostUserTarget7Name, - GhostUserTarget7CoordsRADeg, - GhostUserTarget7CoordsDecDeg, - GhostUserTarget8Name, - GhostUserTarget8CoordsRADeg, - GhostUserTarget8CoordsDecDeg, - GhostUserTargetCount, - GhostSVCcdRequestType, - GhostSVRequestType, - GhostSVRepeat, - GhostSVRunNumber, - GhostSVDuration, - GhostSVUnit, - GhostSVDoSave, - GhostSVDoDisplay, - GhostSVRcf, - GhostSVCcf, - GhostSVImageType, - GhostSVNRegions, - GhostSVXO, - GhostSVYO, - GhostSVWidth, - GhostSVHeigth, - GhostSVIFU1BlueThreshold, - GhostSVIFU1BlueThresholdEnabled, - GhostSVIFU1RedThreshold, - GhostSVIFU1RedThresholdEnabled, - GhostSVIFU2BlueThreshold, - GhostSVIFU2BlueThresholdEnabled, - GhostSVIFU2RedThreshold, - GhostSVIFU2RedThresholdEnabled, - GhostSVHIBlueThreshold, - GhostSVHIBlueThresholdEnabled, - GhostSVHIRedThreshold, - GhostSVHIRedThresholdEnabled, - GhostSVZeroAccumulatedFlux, - GhostSVDoContinuous, - GhostAGCcdRequestType, - GhostAGRequestType, - GhostAGRepeat, - GhostAGDuration, - GhostAGUnit, - GhostAGDoSave, - GhostAGDoDisplay, - GhostAGRcf, - GhostAGCcf, - GhostAGXO, - GhostAGYO, - GhostAGWidth, - GhostAGHeigth, - GhostAGEnableGuide, - GhostAGBackground, - GhostAGSimulateFlux, - GhostAGDoContinuous, - GhostThXeLamp, - GhostSlitMaskPositioner, - GhostSlitMaskPositionerType - ) - - /** Select the member of GiapiStatusApply with the given tag, if any. */ - def fromTag(s: String): Option[GiapiStatusApply] = - all.find(_.tag === s) - - /** Select the member of GiapiStatusApply with the given tag, throwing if absent. */ - def unsafeFromTag(s: String): GiapiStatusApply = - fromTag(s).getOrElse(throw new NoSuchElementException(s"GiapiStatusApply: Invalid tag: '$s'")) - - /** @group Typeclass Instances */ - implicit val GiapiStatusApplyEnumerated: Enumerated[GiapiStatusApply] = - new Enumerated[GiapiStatusApply] { - def all = GiapiStatusApply.all - def tag(a: GiapiStatusApply) = a.tag - override def unsafeFromTag(s: String): GiapiStatusApply = - GiapiStatusApply.unsafeFromTag(s) - } - -} diff --git a/modules/giapi/src/main/scala/giapi/enums/GiapiType.scala b/modules/giapi/src/main/scala/giapi/enums/GiapiType.scala deleted file mode 100644 index a04a25ad9..000000000 --- a/modules/giapi/src/main/scala/giapi/enums/GiapiType.scala +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.enums - -import cats.syntax.eq._ -import lucuma.core.util.Enumerated - -/** - * Enumerated type for giapi status types. - * @group Enumerations (Generated) - */ -sealed abstract class GiapiType( - val tag: String -) extends Product - with Serializable - -object GiapiType { - - /** @group Constructors */ - case object String extends GiapiType("String") - - /** @group Constructors */ - case object Int extends GiapiType("Int") - - /** @group Constructors */ - case object Float extends GiapiType("Float") - - /** @group Constructors */ - case object Double extends GiapiType("Double") - - /** All members of GiapiType, in canonical order. */ - val all: List[GiapiType] = - List(String, Int, Float, Double) - - /** Select the member of GiapiType with the given tag, if any. */ - def fromTag(s: String): Option[GiapiType] = - all.find(_.tag === s) - - /** Select the member of GiapiType with the given tag, throwing if absent. */ - def unsafeFromTag(s: String): GiapiType = - fromTag(s).getOrElse(throw new NoSuchElementException(s"GiapiType: Invalid tag: '$s'")) - - /** @group Typeclass Instances */ - implicit val GiapiTypeEnumerated: Enumerated[GiapiType] = - new Enumerated[GiapiType] { - def all = GiapiType.all - def tag(a: GiapiType) = a.tag - override def unsafeFromTag(s: String): GiapiType = - GiapiType.unsafeFromTag(s) - } - -} diff --git a/modules/giapi/src/test/scala/giapi/client/GiapiArbitraries.scala b/modules/giapi/src/test/scala/giapi/client/GiapiArbitraries.scala deleted file mode 100644 index e527bc618..000000000 --- a/modules/giapi/src/test/scala/giapi/client/GiapiArbitraries.scala +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import cats.syntax.all._ -import giapi.client.commands._ -import org.scalacheck.Arbitrary -import org.scalacheck.Cogen -import org.scalacheck.Arbitrary._ - -trait GiapiArbitraries { - implicit val configurationArb = Arbitrary { - for { - m <- arbitrary[Map[String, String]] - } yield m - .map { case (k, v) => - Configuration.single(k, v) - } - .toList - .combineAll - } - - implicit val configurationCogen: Cogen[Configuration] = - Cogen[Map[String, String]].contramap { - _.config.map { case (c, v) => - (c.getName, v) - } - } -} diff --git a/modules/giapi/src/test/scala/giapi/client/GiapiCommandSpec.scala b/modules/giapi/src/test/scala/giapi/client/GiapiCommandSpec.scala deleted file mode 100644 index 99e6aff8c..000000000 --- a/modules/giapi/src/test/scala/giapi/client/GiapiCommandSpec.scala +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import cats.effect.{ IO, Resource } -import munit.CatsEffectSuite -import giapi.client.commands._ -import edu.gemini.jms.activemq.provider.ActiveMQJmsProvider -import edu.gemini.aspen.giapi.commands.{ - Activity, - Command => JCommand, - CompletionListener, - HandlerResponse, - SequenceCommand -} -import edu.gemini.aspen.giapi.commands.HandlerResponse.Response -import edu.gemini.aspen.gmp.commands.jms.clientbridge.CommandMessagesBridgeImpl -import edu.gemini.aspen.gmp.commands.jms.clientbridge.CommandMessagesConsumer -import edu.gemini.aspen.giapi.commands.CommandSender -import scala.concurrent.duration._ -import org.scalatest.EitherValues - -final case class GmpCommands(amq: ActiveMQJmsProvider, cmc: CommandMessagesConsumer) - -object GmpCommands { - - def amqUrl(name: String): String = - s"vm://$name?broker.useJmx=false&marshal=false&broker.persistent=false" - - def amqUrlConnect(name: String): String = - s"vm://$name?marshal=false&broker.persistent=false&create=false" - - /** - * Setup a mini gmp that can store and provide status items - */ - def createGmpCommands(amqUrl: String, handleCommands: Boolean): IO[GmpCommands] = IO.apply { - // Local in memory broker - val amq = new ActiveMQJmsProvider(amqUrl) - amq.startConnection() - val cs = new CommandSender() { - // This is essentially an instrument simulator - // we test several possible scenarios - override def sendCommand(command: JCommand, listener: CompletionListener): HandlerResponse = - sendCommand(command, listener, 0) - - override def sendCommand( - command: JCommand, - listener: CompletionListener, - timeout: Long - ): HandlerResponse = - command.getSequenceCommand match { - case SequenceCommand.INIT => HandlerResponse.COMPLETED - case SequenceCommand.PARK => HandlerResponse.ACCEPTED - case _ => HandlerResponse.NOANSWER - } - - } - val cmb = new CommandMessagesBridgeImpl(amq, cs) - val commandMessagesConsumer = new CommandMessagesConsumer(cmb) - if (handleCommands) { - commandMessagesConsumer.startJms(amq) - } - - GmpCommands(amq, commandMessagesConsumer) - } - - def closeGmpCommands(gmp: GmpCommands): IO[Unit] = IO.apply { - gmp.cmc.stopJms() - gmp.amq.stopConnection() - } -} - -/** - * Tests of the giapi api - */ -final class GiapiCommandSpec extends CatsEffectSuite with EitherValues { - - def client(amqUrl: String, handleCommands: Boolean): Resource[IO, Giapi[IO]] = - for { - _ <- Resource.make(GmpCommands.createGmpCommands(amqUrl, handleCommands))( - GmpCommands.closeGmpCommands - ) - c <- Resource.make(Giapi.giapiConnection[IO](amqUrl).connect)(_.close) - } yield c - - test("Test sending a command with no handlers".ignore) { // This test passes but the backend doesn't clean up properly - client(GmpCommands.amqUrl("test1"), false) - .use { c => - c.command(Command(SequenceCommand.TEST, Activity.PRESET, Configuration.Zero), 1.second) - .attempt - } - .map(assertEquals(_, Left(CommandResultException(Response.ERROR, "Message cannot be null")))) - } - - test("Test sending a command with no answer") { - client(GmpCommands.amqUrl("test2"), true) - .use { c => - c.command(Command(SequenceCommand.TEST, Activity.PRESET, Configuration.Zero), 1.second) - .attempt - } - .map( - assertEquals( - _, - Left(CommandResultException(Response.NOANSWER, "No answer from the instrument")) - ) - ) - } - - test("Test sending a command with immediate answer") { - client(GmpCommands.amqUrl("test3"), true) - .use { c => - c.command(Command(SequenceCommand.INIT, Activity.PRESET, Configuration.Zero), 1.second) - .attempt - } - .map(assertEquals(_, Right(CommandResult(Response.COMPLETED)))) - } - - test("Test sending a command with accepted but never completed answer") { - val timeout = 1.second - client(GmpCommands.amqUrl("test4"), true) - .use { c => - c.command(Command(SequenceCommand.PARK, Activity.PRESET, Configuration.Zero), timeout) - .attempt - } - .map(assertEquals(_, Left(CommandResultException.timedOut(timeout)))) - } - -} diff --git a/modules/giapi/src/test/scala/giapi/client/GiapiStatusSpec.scala b/modules/giapi/src/test/scala/giapi/client/GiapiStatusSpec.scala deleted file mode 100644 index 493ef452b..000000000 --- a/modules/giapi/src/test/scala/giapi/client/GiapiStatusSpec.scala +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client - -import cats.effect.{ IO, Resource } -import munit.CatsEffectSuite -import edu.gemini.aspen.giapi.status.impl.BasicStatus -import edu.gemini.aspen.giapi.util.jms.JmsKeys -import edu.gemini.aspen.gmp.statusdb.StatusDatabase -import edu.gemini.aspen.gmp.statusgw.jms.JmsStatusDispatcher -import edu.gemini.aspen.gmp.statusgw.jms.StatusItemRequestListener -import edu.gemini.jms.activemq.provider.ActiveMQJmsProvider -import edu.gemini.jms.api.BaseMessageConsumer -import edu.gemini.jms.api.DestinationData -import edu.gemini.jms.api.DestinationType -import edu.gemini.jms.api.JmsSimpleMessageSelector -import org.scalatest.matchers.must.Matchers.matchPattern - -final case class GmpStatus( - amq: ActiveMQJmsProvider, - dispatcher: JmsStatusDispatcher, - msgConsumer: BaseMessageConsumer -) - -object GmpStatus { - - def amqUrl(name: String): String = - s"vm://$name?broker.useJmx=false&marshal=false&broker.persistent=false" - - def amqUrlConnect(name: String): String = - s"vm://$name?marshal=false&broker.persistent=false&create=false" - - /** - * Setup a mini gmp that can store and provide status items - */ - def createGmpStatus(amqUrl: String, intItemName: String, strItemName: String): IO[GmpStatus] = - IO.apply { - // Local in memory broker - val amq = new ActiveMQJmsProvider(amqUrl) - amq.startConnection() - - // Setup status listeners and db to answer status queries - val database = new StatusDatabase() - val dispatcher = new JmsStatusDispatcher("Status Dispatcher") - dispatcher.startJms(amq) - val msgConsumer = new BaseMessageConsumer( - "Status Consumer", - new DestinationData(JmsKeys.GW_STATUS_REQUEST_DESTINATION, DestinationType.TOPIC), - new StatusItemRequestListener(database, dispatcher), - new JmsSimpleMessageSelector( - JmsKeys.GW_STATUS_REQUEST_TYPE_PROPERTY + " = '" + JmsKeys.GW_STATUS_REQUEST_TYPE_ITEM + "'" - ) - ) - - msgConsumer.startJms(amq) - // Set a status item - database.update(new BasicStatus[Int](intItemName, 1)) - database.update(new BasicStatus[String](strItemName, "one")) - GmpStatus(amq, dispatcher, msgConsumer) - } - - def closeGmpStatus(gmp: GmpStatus): IO[Unit] = IO.apply { - gmp.dispatcher.stopJms() - gmp.msgConsumer.stopJms() - gmp.amq.stopConnection() - } -} - -/** - * Tests of the giapi api - */ -final class GiapiStatusSpec extends CatsEffectSuite { - val intItemName = "item:a" - val strItemName = "item:b" - - def client( - amqUrl: String, - intItemName: String, - strItemName: String - ): Resource[IO, (GmpStatus, Giapi[IO])] = - for { - g <- Resource.make(GmpStatus.createGmpStatus(amqUrl, intItemName, strItemName))( - GmpStatus.closeGmpStatus - ) - c <- Resource.make(Giapi.giapiConnection[IO](amqUrl).connect)(_.close) - } yield (g, c) - - test("Test reading an existing status item") { - client(GmpStatus.amqUrl("tests1"), intItemName, strItemName) - .use { case (_, c) => - c.get[Int](intItemName) - } - .map(assertEquals(_, 1)) - } - - test("Test reading an status with string type") { - client(GmpStatus.amqUrl("tests2"), intItemName, strItemName) - .use { case (_, c) => - c.get[String](strItemName) - } - .attempt - .map(assertEquals(_, Right("one"))) - } - - test("Test reading an unknown status item") { - client(GmpStatus.amqUrl("tests3"), intItemName, strItemName) - .use { case (_, c) => - c.get[Int]("item:u") - } - .attempt - .map(matchPattern { case Left(GiapiException(_)) => }) - } - - test("Test reading an unknown status item as optional") { - client(GmpStatus.amqUrl("tests4"), intItemName, strItemName) - .use { case (_, c) => - c.getO[Int]("item:u") - } - .map(assertEquals(_, None)) - } - - test("Closing connection should terminate") { - // This should fail but we are mostly concerned with ensuring that it terminates - client(GmpStatus.amqUrl("tests5"), intItemName, strItemName) - .use { case (g, c) => - GmpStatus.closeGmpStatus(g) >> c.get[Int](intItemName) - } - .attempt - .map(matchPattern { case Left(GiapiException(_)) => }) - } - -} diff --git a/modules/giapi/src/test/scala/giapi/client/commands/CommandsSpec.scala b/modules/giapi/src/test/scala/giapi/client/commands/CommandsSpec.scala deleted file mode 100644 index af1b561ca..000000000 --- a/modules/giapi/src/test/scala/giapi/client/commands/CommandsSpec.scala +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA) -// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause - -package giapi.client.commands - -import cats.kernel.laws.discipline._ -import cats.tests.CatsSuite -import giapi.client.GiapiArbitraries - -/** - * Tests Command typeclasses - */ -final class CommandsSpec extends CatsSuite with GiapiArbitraries { - checkAll("Eq[Configuration]", EqTests[Configuration].eqv) - checkAll("Monoid[Configuration]", MonoidTests[Configuration].monoid) -} diff --git a/project/Settings.scala b/project/Settings.scala index 9c6aac5e5..230d89315 100644 --- a/project/Settings.scala +++ b/project/Settings.scala @@ -74,6 +74,7 @@ object Settings { val gmpCommandRecords = "0.7.7" val acm = "0.1.1" val giapi = "1.1.7" + val giapiScala = "0.1.0" val giapiJmsUtil = "0.5.7" val giapiJmsProvider = "1.6.7" val giapiCommandsClient = "0.2.7" @@ -263,6 +264,7 @@ object Settings { ) // GIAPI Libraries + val GiapiScala = "edu.gemini" %% "giapi" % LibraryVersions.giapiScala val EpicsService = "edu.gemini.epics" % "epics-service" % LibraryVersions.epicsService val GmpCommandsRecords = "edu.gemini.gmp" % "gmp-commands-records" % LibraryVersions.gmpCommandRecords