From 431a060a8c3aea1863abc8d87f4cb279557bc8c2 Mon Sep 17 00:00:00 2001 From: Carlos Quiroz Date: Fri, 26 Jan 2024 15:41:50 -0300 Subject: [PATCH 1/3] Add support to input probeGuide --- build.sbt | 3 +- .../navigate/server/tcs/ProbeGuide.scala | 16 ++++++++++ .../server/tcs/TelescopeGuideConfig.scala | 3 +- .../server/src/main/resources/NewTCC.graphql | 9 +++++- .../web/server/http4s/NavigateMappings.scala | 13 ++++++++- .../server/http4s/NavigateMappingsTest.scala | 29 +++++++++++++++++++ project/Settings.scala | 5 ++++ 7 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 modules/server/src/main/scala/navigate/server/tcs/ProbeGuide.scala diff --git a/build.sbt b/build.sbt index 5365f834..d24f5dc2 100644 --- a/build.sbt +++ b/build.sbt @@ -147,7 +147,8 @@ lazy val navigate_server = project libraryDependencies ++= Seq( CatsEffect.value, Fs2, - Log4Cats.value + Log4Cats.value, + LucumaAgs ) ++ MUnit.value ++ LucumaCore.value ++ Http4sClient ) .dependsOn(navigate_model % "compile->compile;test->test") diff --git a/modules/server/src/main/scala/navigate/server/tcs/ProbeGuide.scala b/modules/server/src/main/scala/navigate/server/tcs/ProbeGuide.scala new file mode 100644 index 00000000..0073b245 --- /dev/null +++ b/modules/server/src/main/scala/navigate/server/tcs/ProbeGuide.scala @@ -0,0 +1,16 @@ +// 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 navigate.server.tcs + +import cats.Eq +import cats.Show +import cats.derived.* +import lucuma.ags.GuideProbe + +/** Data type for guide config. */ +case class ProbeGuide( + from: GuideProbe, + to: GuideProbe +) derives Eq, + Show diff --git a/modules/server/src/main/scala/navigate/server/tcs/TelescopeGuideConfig.scala b/modules/server/src/main/scala/navigate/server/tcs/TelescopeGuideConfig.scala index 96bfa962..8f77f39e 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TelescopeGuideConfig.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TelescopeGuideConfig.scala @@ -12,6 +12,7 @@ case class TelescopeGuideConfig( mountGuide: Boolean, m1Guide: M1GuideConfig, m2Guide: M2GuideConfig, - dayTimeMode: Boolean + dayTimeMode: Boolean, + probeGuide: Option[ProbeGuide] ) derives Eq, Show diff --git a/modules/web/server/src/main/resources/NewTCC.graphql b/modules/web/server/src/main/resources/NewTCC.graphql index d7529a36..96cb1727 100644 --- a/modules/web/server/src/main/resources/NewTCC.graphql +++ b/modules/web/server/src/main/resources/NewTCC.graphql @@ -1,4 +1,4 @@ -#import NonEmptyString, Sidereal, TargetId, Nonsidereal from "lucuma/schemas/ObservationDB.graphql" +#import NonEmptyString, Sidereal, GuideProbe, TargetId, Nonsidereal from "lucuma/schemas/ObservationDB.graphql" #import SiderealInput, NonsiderealInput, WavelengthInput, AngleInput from "lucuma/schemas/ObservationDB.graphql" #import Long, BigDecimal, Timestamp, TimeSpanInput from "lucuma/schemas/ObservationDB.graphql" @@ -156,6 +156,13 @@ input GuideConfigurationInput { mountOffload: Boolean! """Flag for day time tests. It sets all gains to 0""" daytimeMode: Boolean! + """Probe names to be used for guiding""" + probeGuide: ProbeGuideInput +} + +input ProbeGuideInput { + from: GuideProbe + to: GuideProbe } enum LogLevel { diff --git a/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala b/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala index 246fa952..8390f4f2 100644 --- a/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala +++ b/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala @@ -36,6 +36,7 @@ import lucuma.core.math.RadialVelocity import lucuma.core.math.RightAscension import lucuma.core.math.Wavelength import lucuma.core.util.TimeSpan +import lucuma.ags.GuideProbe import mouse.boolean.given import navigate.model.Distance import navigate.model.enums.M1Source @@ -55,6 +56,7 @@ import navigate.server.tcs.M1GuideConfig.M1GuideOn import navigate.server.tcs.M2GuideConfig import navigate.server.tcs.Origin import navigate.server.tcs.ParkStatus +import navigate.server.tcs.ProbeGuide import navigate.server.tcs.ResetPointing import navigate.server.tcs.RotatorTrackConfig import navigate.server.tcs.RotatorTrackingMode @@ -648,6 +650,11 @@ object NavigateMappings extends GrackleParsers { rc <- l.collectFirst { case ("rotator", ObjectValue(v)) => parseRotatorConfig(v) }.flatten } yield TcsConfig(t, in, oi, rc) + def parseProbeGuide(l: List[(String, Value)]): Option[ProbeGuide] = for { + f <- l.collectFirst { case ("from", EnumValue(v)) => parseEnumerated[GuideProbe](v) }.flatten + t <- l.collectFirst { case ("to", EnumValue(v)) => parseEnumerated[GuideProbe](v) }.flatten + } yield ProbeGuide(f, t) + def parseGuideConfig(l: List[(String, Value)]): Option[TelescopeGuideConfig] = { val m2: List[TipTiltSource] = l.collectFirst { case ("m2Inputs", ListValue(v)) => v.collect { case EnumValue(v) => parseEnumerated[TipTiltSource](v) }.flattenOption @@ -661,6 +668,9 @@ object NavigateMappings extends GrackleParsers { val dayTimeMode = l.collectFirst { case ("daytimeMode", BooleanValue(v)) => v }.exists(identity) + val probeGuide = + l.collectFirst { case ("probeGuide", ObjectValue(v)) => parseProbeGuide(v) }.flatten + l.collectFirst { case ("mountOffload", BooleanValue(v)) => v } .map { mount => TelescopeGuideConfig( @@ -670,7 +680,8 @@ object NavigateMappings extends GrackleParsers { M2GuideConfig.M2GuideOff, M2GuideConfig.M2GuideOn(coma && m1.isDefined, m2.toSet) ), - dayTimeMode + dayTimeMode, + probeGuide ) } } diff --git a/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala b/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala index 394b320c..cf471450 100644 --- a/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala +++ b/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala @@ -615,6 +615,35 @@ class NavigateMappingsTest extends CatsEffectSuite { ) } + test("Set probeGuide") { + for { + eng <- buildServer + log <- Topic[IO, ILoggingEvent] + gd <- Topic[IO, GuideState] + mp <- NavigateMappings[IO](eng, log, gd) + r <- mp.compileAndRun( + """ + |mutation { guideEnable( config: { + | m2Inputs: [ OIWFS ] + | m2Coma: true + | m1Input: OIWFS + | mountOffload: true + | daytimeMode: false + | probeGuide: { + | from: GMOS_OIWFS + | to: GMOS_OIWFS + | } + | } + |) { + | result + |} } + |""".stripMargin + ) + } yield assert( + extractResult[OperationOutcome](r, "guideEnable").exists(_ === OperationOutcome.success) + ) + } + } object NavigateMappingsTest { diff --git a/project/Settings.scala b/project/Settings.scala index 1643db79..6167022d 100644 --- a/project/Settings.scala +++ b/project/Settings.scala @@ -56,6 +56,8 @@ object Settings { // Lucuma val lucumaCore = "0.91.1" val lucumaSchemas = "0.69.0" + val lucumaSchemas = "0.68.0" + val lucumaAgs = "0.44.5" val grackle = "0.18.0" @@ -176,6 +178,9 @@ object Settings { ) val LucumaSchemas = "edu.gemini" %% "lucuma-schemas" % LibraryVersions.lucumaSchemas + val LucumaAgs = + "edu.gemini" %% "lucuma-ags" % LibraryVersions.lucumaAgs + val Grackle = Def.setting( Seq( "org.typelevel" %% "grackle-core" % LibraryVersions.grackle, From ba5fbe8d0fa5904a49ec68484fd7eb5b267f40b2 Mon Sep 17 00:00:00 2001 From: Carlos Quiroz Date: Sun, 28 Jan 2024 15:41:12 -0300 Subject: [PATCH 2/3] Set channels to provide the guide mode when doing enableGuide --- .../server/tcs/TcsBaseControllerEpics.scala | 17 ++++- .../navigate/server/tcs/TcsChannels.scala | 24 ++++++- .../navigate/server/tcs/TcsEpicsSystem.scala | 36 ++++++++++ ...cala => TcsBaseControllerEpicsSuite.scala} | 66 +++++++++++++++++-- .../server/tcs/TestTcsEpicsSystem.scala | 34 +++++++++- .../web/server/http4s/NavigateMappings.scala | 2 +- .../server/http4s/NavigateMappingsTest.scala | 31 ++++++++- project/Settings.scala | 3 +- 8 files changed, 198 insertions(+), 15 deletions(-) rename modules/server/src/test/scala/navigate/server/tcs/{TcsBaseControllerEpicsSpec.scala => TcsBaseControllerEpicsSuite.scala} (94%) diff --git a/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala b/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala index d64b4d3f..b7bc22f8 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala @@ -372,7 +372,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( val m1 = (x: TcsCommands[F]) => config.m1Guide match { - case M1GuideConfig.M1GuideOff => x.m1GuideCommand.state(false) + case M1GuideConfig.M1GuideOff => + x.m1GuideCommand.state(false).guideModeCommand.setMode(config.probeGuide) case M1GuideConfig.M1GuideOn(source) => x.m1GuideCommand .state(true) @@ -384,6 +385,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .frames(1) .m1GuideConfigCommand .filename("") + .guideModeCommand + .setMode(config.probeGuide) } config.m2Guide match { @@ -396,6 +399,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .mode(config.mountGuide) .mountGuideCommand .source("SCS") + .guideModeCommand + .setMode(config.probeGuide) .post .verifiedRun(ConnectionTimeout) case M2GuideConfig.M2GuideOn(coma, sources) => @@ -405,7 +410,11 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .flatMap(x => beams.map(y => (x, y))) .foldLeft( requireReset.fold( - gains(tcsEpics.startCommand(timeout)).m2GuideResetCommand.mark.post + tcsEpics + .startCommand(timeout) + .m2GuideResetCommand + .mark + .post .verifiedRun(ConnectionTimeout), ApplyCommandResult.Completed.pure[F] ) @@ -427,6 +436,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .beam(beam) .m2GuideConfigCommand .reset(false) + .guideModeCommand + .setMode(config.probeGuide) .post .verifiedRun(ConnectionTimeout), r.pure[F] @@ -441,6 +452,8 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .mode(config.mountGuide) .mountGuideCommand .source("SCS") + .guideModeCommand + .setMode(config.probeGuide) .post .verifiedRun(ConnectionTimeout), ApplyCommandResult.Completed.pure[F] diff --git a/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala b/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala index 11b3289c..b6fc23fe 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala @@ -49,7 +49,8 @@ case class TcsChannels[F[_]]( mountGuide: MountGuideChannels[F], oiwfs: WfsChannels[F], guide: GuideConfigStatusChannels[F], - guiderGains: GuiderGainsChannels[F] + guiderGains: GuiderGainsChannels[F], + guideMode: GuideModeChannels[F] ) object TcsChannels { @@ -513,6 +514,23 @@ object TcsChannels { ) } + case class GuideModeChannels[F[_]]( + state: Channel[F, String], + from: Channel[F, String], + to: Channel[F, String] + ) + + object GuideModeChannels { + def build[F[_]]( + service: EpicsService[F], + top: TcsTop + ): Resource[F, GuideModeChannels[F]] = for { + state <- service.getChannel[String](top.value, "wfsGuideMode.A") + from <- service.getChannel[String](top.value, "wfsGuideMode.B") + to <- service.getChannel[String](top.value, "wfsGuideMode.C") + } yield GuideModeChannels(state, from, to) + } + object GuiderGains { def build[F[_]]( service: EpicsService[F], @@ -601,6 +619,7 @@ object TcsChannels { oi <- WfsChannels.build(service, tcsTop, "oiwfs", "oi") gd <- GuideConfigStatusChannels.build(service, tcsTop) gg <- GuiderGains.build(service, pwfs1Top, pwfs2Top, oiTop) + gm <- GuideModeChannels.build(service, tcsTop) } yield TcsChannels[F]( tt, p1tt, @@ -631,7 +650,8 @@ object TcsChannels { mng, oi, gd, - gg + gg, + gm ) } } diff --git a/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala b/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala index 062efa33..0afa77b5 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala @@ -10,6 +10,7 @@ import cats.effect.Resource import cats.effect.Temporal import cats.effect.std.Dispatcher import eu.timepit.refined.types.string.NonEmptyString +import lucuma.ags.GuideProbe import lucuma.core.math.Angle import mouse.all.* import navigate.epics.Channel @@ -89,6 +90,7 @@ object TcsEpicsSystem { val p1GuiderGainsCmd: Command3Channels[F, Double, Double, Double] val p2GuiderGainsCmd: Command3Channels[F, Double, Double, Double] val oiGuiderGainsCmd: Command3Channels[F, Double, Double, Double] + val guideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] // val offsetACmd: OffsetCmd[F] // val offsetBCmd: OffsetCmd[F] @@ -897,6 +899,21 @@ object TcsEpicsSystem { ) } + + override val guideModeCommand: GuideModeCommand[F, TcsCommands[F]] = + new GuideModeCommand[F, TcsCommands[F]] { + override def setMode(pg: Option[ProbeGuide]): TcsCommands[F] = + pg.fold( + addParam(tcsEpics.guideModeCmd.setParam1(BinaryOnOff.Off)) + )(pg => + addMultipleParams( + List(tcsEpics.guideModeCmd.setParam1(BinaryOnOff.On), + tcsEpics.guideModeCmd.setParam2(pg.from), + tcsEpics.guideModeCmd.setParam3(pg.to) + ) + ) + ) + } } class TcsEpicsSystemImpl[F[_]: Monad: Parallel](epics: TcsEpics[F], st: TcsStatus[F]) @@ -911,6 +928,12 @@ object TcsEpicsSystem { applyCmd: GeminiApplyCommand[F], channels: TcsChannels[F] ) extends TcsEpics[F] { + given Encoder[GuideProbe, String] = _ match { + case GuideProbe.GmosOiwfs => "OIWFS" + case GuideProbe.Pwfs1 => "PWFS1" + case GuideProbe.Pwfs2 => "PWFS2" + } + override def post(timeout: FiniteDuration): VerifiedEpics[F, F, ApplyCommandResult] = applyCmd.post(timeout) @@ -1073,6 +1096,14 @@ object TcsEpicsSystem { channels.guiderGains.oiTiltGain, channels.guiderGains.oiFocusGain ) + + override val guideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] = + Command3Channels( + channels.telltale, + channels.guideMode.state, + channels.guideMode.from, + channels.guideMode.to + ) } case class ParameterlessCommandChannels[F[_]: Monad]( @@ -1508,6 +1539,10 @@ object TcsEpicsSystem { def fileName(v: String): S } + trait GuideModeCommand[F[_], +S] { + def setMode(pg: Option[ProbeGuide]): S + } + trait WfsSignalProcConfigCommand[F[_], +S] { def darkFilename(v: String): S } @@ -1561,6 +1596,7 @@ object TcsEpicsSystem { val mountGuideCommand: MountGuideCommand[F, TcsCommands[F]] val oiWfsCommands: WfsCommands[F, TcsCommands[F]] val guiderGainsCommands: GuiderGainsCommand[F, TcsCommands[F]] + val guideModeCommand: GuideModeCommand[F, TcsCommands[F]] } /* diff --git a/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSpec.scala b/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala similarity index 94% rename from modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSpec.scala rename to modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala index cf7d5eda..68de793a 100644 --- a/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSpec.scala +++ b/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala @@ -6,6 +6,7 @@ package navigate.server.tcs import cats.effect.IO import cats.effect.Ref import cats.syntax.all.* +import lucuma.ags.GuideProbe import lucuma.core.math.Angle import lucuma.core.math.Coordinates import lucuma.core.math.Epoch @@ -34,7 +35,7 @@ import TcsBaseController.* import M2GuideConfig.M2GuideOn import TestTcsEpicsSystem.GuideConfigState -class TcsBaseControllerEpicsSpec extends CatsEffectSuite { +class TcsBaseControllerEpicsSuite extends CatsEffectSuite { private val DefaultTimeout: FiniteDuration = FiniteDuration(1, TimeUnit.SECONDS) @@ -574,7 +575,8 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite { mountGuide = true, m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs), m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)), - dayTimeMode = false + dayTimeMode = false, + probeGuide = none ) for { @@ -660,7 +662,8 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite { mountGuide = true, m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs), m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)), - dayTimeMode = true + dayTimeMode = true, + probeGuide = none ) for { @@ -746,7 +749,8 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite { mountGuide = true, m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs), m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)), - false + dayTimeMode = false, + probeGuide = none ) for { @@ -772,6 +776,7 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite { assert(r1.m2GuideReset.connected) assert(r1.mountGuide.mode.connected) assert(r1.mountGuide.source.connected) + assert(r1.guideMode.state.connected) assertEquals(r1.m1Guide.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.On.some) assertEquals(r1.m1GuideConfig.source.value.flatMap(Enumerated[M1Source].fromTag), @@ -804,6 +809,59 @@ class TcsBaseControllerEpicsSpec extends CatsEffectSuite { assertEquals(r2.mountGuide.mode.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.Off.some ) + assertEquals(r1.guideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), + BinaryOnOff.Off.some + ) + } + } + + test("Set guide mode OIWFS to OIWFS") { + val guideCfg = TelescopeGuideConfig( + mountGuide = true, + m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs), + m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)), + dayTimeMode = false, + probeGuide = ProbeGuide(GuideProbe.GmosOiwfs, GuideProbe.GmosOiwfs).some + ) + + for { + x <- createController + (st, ctr) = x + _ <- ctr.enableGuide(guideCfg) + r1 <- st.get + } yield { + assert(r1.guideMode.state.connected) + + assertEquals(r1.guideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), + BinaryOnOff.On.some + ) + assertEquals(r1.guideMode.from.value, "OIWFS".some) + assertEquals(r1.guideMode.to.value, "OIWFS".some) + } + } + + test("Set guide mode PWFS1 to PWFS2") { + val guideCfg = TelescopeGuideConfig( + mountGuide = true, + m1Guide = M1GuideConfig.M1GuideOn(M1Source.Oiwfs), + m2Guide = M2GuideOn(true, Set(TipTiltSource.Oiwfs)), + dayTimeMode = false, + probeGuide = ProbeGuide(GuideProbe.Pwfs1, GuideProbe.Pwfs2).some + ) + + for { + x <- createController + (st, ctr) = x + _ <- ctr.enableGuide(guideCfg) + r1 <- st.get + } yield { + assert(r1.guideMode.state.connected) + + assertEquals(r1.guideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), + BinaryOnOff.On.some + ) + assertEquals(r1.guideMode.from.value, "PWFS1".some) + assertEquals(r1.guideMode.to.value, "PWFS2".some) } } diff --git a/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala b/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala index 68fff46d..16e8443f 100644 --- a/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala +++ b/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala @@ -20,6 +20,7 @@ import navigate.server.epicsdata.BinaryOnOff import navigate.server.epicsdata.BinaryYesNo import navigate.server.tcs.TcsChannels.EnclosureChannels import navigate.server.tcs.TcsChannels.GuideConfigStatusChannels +import navigate.server.tcs.TcsChannels.GuideModeChannels import navigate.server.tcs.TcsChannels.GuiderGainsChannels import navigate.server.tcs.TcsChannels.M1GuideConfigChannels import navigate.server.tcs.TcsChannels.M2GuideConfigChannels @@ -156,6 +157,20 @@ object TestTcsEpicsSystem { ) } + case class GuideModeState( + state: TestChannel.State[String], + from: TestChannel.State[String], + to: TestChannel.State[String] + ) + + object GuideModeState { + val default: GuideModeState = GuideModeState( + TestChannel.State.default, + TestChannel.State.default, + TestChannel.State.default + ) + } + case class WfsChannelState( observe: WfsObserveChannelState, stop: TestChannel.State[CadDirective], @@ -233,7 +248,8 @@ object TestTcsEpicsSystem { m2GuideReset: TestChannel.State[CadDirective], mountGuide: MountGuideState, guideStatus: GuideConfigState, - guiderGains: GuiderGainsState + guiderGains: GuiderGainsState, + guideMode: GuideModeState ) val defaultState: State = State( @@ -335,7 +351,8 @@ object TestTcsEpicsSystem { m2GuideReset = TestChannel.State.default, mountGuide = MountGuideState.default, guideStatus = GuideConfigState.default, - guiderGains = GuiderGainsState.default + guiderGains = GuiderGainsState.default, + guideMode = GuideModeState.default ) def buildEnclosureChannels[F[_]: Applicative](s: Ref[F, State]): EnclosureChannels[F] = @@ -685,6 +702,16 @@ object TestTcsEpicsSystem { new TestChannel[F, State, String](s, l.andThen(Focus[GuiderGainsState](_.oiFocusGain))), new TestChannel[F, State, BinaryYesNo](s, l.andThen(Focus[GuiderGainsState](_.oiReset))) ) + + def buildGuideModeChannels[F[_]: Applicative]( + s: Ref[F, State], + l: Lens[State, GuideModeState] + ): GuideModeChannels[F] = GuideModeChannels( + new TestChannel[F, State, String](s, l.andThen(Focus[GuideModeState](_.state))), + new TestChannel[F, State, String](s, l.andThen(Focus[GuideModeState](_.from))), + new TestChannel[F, State, String](s, l.andThen(Focus[GuideModeState](_.to))) + ) + def buildChannels[F[_]: Applicative](s: Ref[F, State]): TcsChannels[F] = TcsChannels( telltale = @@ -727,7 +754,8 @@ object TestTcsEpicsSystem { mountGuide = buildMountGuideChannels(s, Focus[State](_.mountGuide)), oiwfs = buildWfsChannels(s, Focus[State](_.oiWfs)), guide = buildGuideStateChannels(s, Focus[State](_.guideStatus)), - guiderGains = buildGuiderGainsChannels(s, Focus[State](_.guiderGains)) + guiderGains = buildGuiderGainsChannels(s, Focus[State](_.guiderGains)), + guideMode = buildGuideModeChannels(s, Focus[State](_.guideMode)) ) def build[F[_]: Monad: Parallel](s: Ref[F, State]): TcsEpicsSystem[F] = diff --git a/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala b/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala index 8390f4f2..003dfa46 100644 --- a/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala +++ b/modules/web/server/src/main/scala/navigate/web/server/http4s/NavigateMappings.scala @@ -27,6 +27,7 @@ import grackle.Value.StringValue import grackle.circe.CirceMapping import grackle.syntax.given import io.circe.syntax.* +import lucuma.ags.GuideProbe import lucuma.core.math.Coordinates import lucuma.core.math.Declination import lucuma.core.math.Epoch @@ -36,7 +37,6 @@ import lucuma.core.math.RadialVelocity import lucuma.core.math.RightAscension import lucuma.core.math.Wavelength import lucuma.core.util.TimeSpan -import lucuma.ags.GuideProbe import mouse.boolean.given import navigate.model.Distance import navigate.model.enums.M1Source diff --git a/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala b/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala index cf471450..174d6cb7 100644 --- a/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala +++ b/modules/web/server/src/test/scala/navigate/web/server/http4s/NavigateMappingsTest.scala @@ -615,7 +615,7 @@ class NavigateMappingsTest extends CatsEffectSuite { ) } - test("Set probeGuide") { + test("Set probeGuide OIWFS to OIWFS") { for { eng <- buildServer log <- Topic[IO, ILoggingEvent] @@ -644,6 +644,35 @@ class NavigateMappingsTest extends CatsEffectSuite { ) } + test("Set probeGuide PWFS1 to PWFS2") { + for { + eng <- buildServer + log <- Topic[IO, ILoggingEvent] + gd <- Topic[IO, GuideState] + mp <- NavigateMappings[IO](eng, log, gd) + r <- mp.compileAndRun( + """ + |mutation { guideEnable( config: { + | m2Inputs: [ OIWFS ] + | m2Coma: true + | m1Input: OIWFS + | mountOffload: true + | daytimeMode: false + | probeGuide: { + | from: PWFS_1 + | to: PWFS_2 + | } + | } + |) { + | result + |} } + |""".stripMargin + ) + } yield assert( + extractResult[OperationOutcome](r, "guideEnable").exists(_ === OperationOutcome.success) + ) + } + } object NavigateMappingsTest { diff --git a/project/Settings.scala b/project/Settings.scala index 6167022d..cc22458c 100644 --- a/project/Settings.scala +++ b/project/Settings.scala @@ -55,8 +55,7 @@ object Settings { // Lucuma val lucumaCore = "0.91.1" - val lucumaSchemas = "0.69.0" - val lucumaSchemas = "0.68.0" + val lucumaSchemas = "0.70.0" val lucumaAgs = "0.44.5" val grackle = "0.18.0" From e6d7577214d332baf776d4bc583c937f64e83dd1 Mon Sep 17 00:00:00 2001 From: Carlos Quiroz Date: Tue, 30 Jan 2024 11:07:48 -0300 Subject: [PATCH 3/3] Rename guideMode methods to probeGuideMode --- .../server/tcs/TcsBaseControllerEpics.scala | 10 +++---- .../navigate/server/tcs/TcsChannels.scala | 12 ++++----- .../navigate/server/tcs/TcsEpicsSystem.scala | 26 +++++++++---------- .../tcs/TcsBaseControllerEpicsSuite.scala | 20 +++++++------- .../server/tcs/TestTcsEpicsSystem.scala | 24 ++++++++--------- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala b/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala index b7bc22f8..1433a0fa 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TcsBaseControllerEpics.scala @@ -373,7 +373,7 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( val m1 = (x: TcsCommands[F]) => config.m1Guide match { case M1GuideConfig.M1GuideOff => - x.m1GuideCommand.state(false).guideModeCommand.setMode(config.probeGuide) + x.m1GuideCommand.state(false).probeGuideModeCommand.setMode(config.probeGuide) case M1GuideConfig.M1GuideOn(source) => x.m1GuideCommand .state(true) @@ -385,7 +385,7 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .frames(1) .m1GuideConfigCommand .filename("") - .guideModeCommand + .probeGuideModeCommand .setMode(config.probeGuide) } @@ -399,7 +399,7 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .mode(config.mountGuide) .mountGuideCommand .source("SCS") - .guideModeCommand + .probeGuideModeCommand .setMode(config.probeGuide) .post .verifiedRun(ConnectionTimeout) @@ -436,7 +436,7 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .beam(beam) .m2GuideConfigCommand .reset(false) - .guideModeCommand + .probeGuideModeCommand .setMode(config.probeGuide) .post .verifiedRun(ConnectionTimeout), @@ -452,7 +452,7 @@ class TcsBaseControllerEpics[F[_]: Async: Parallel]( .mode(config.mountGuide) .mountGuideCommand .source("SCS") - .guideModeCommand + .probeGuideModeCommand .setMode(config.probeGuide) .post .verifiedRun(ConnectionTimeout), diff --git a/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala b/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala index b6fc23fe..a00e07d7 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TcsChannels.scala @@ -50,7 +50,7 @@ case class TcsChannels[F[_]]( oiwfs: WfsChannels[F], guide: GuideConfigStatusChannels[F], guiderGains: GuiderGainsChannels[F], - guideMode: GuideModeChannels[F] + probeGuideMode: ProbeGuideModeChannels[F] ) object TcsChannels { @@ -514,21 +514,21 @@ object TcsChannels { ) } - case class GuideModeChannels[F[_]]( + case class ProbeGuideModeChannels[F[_]]( state: Channel[F, String], from: Channel[F, String], to: Channel[F, String] ) - object GuideModeChannels { + object ProbeGuideModeChannels { def build[F[_]]( service: EpicsService[F], top: TcsTop - ): Resource[F, GuideModeChannels[F]] = for { + ): Resource[F, ProbeGuideModeChannels[F]] = for { state <- service.getChannel[String](top.value, "wfsGuideMode.A") from <- service.getChannel[String](top.value, "wfsGuideMode.B") to <- service.getChannel[String](top.value, "wfsGuideMode.C") - } yield GuideModeChannels(state, from, to) + } yield ProbeGuideModeChannels(state, from, to) } object GuiderGains { @@ -619,7 +619,7 @@ object TcsChannels { oi <- WfsChannels.build(service, tcsTop, "oiwfs", "oi") gd <- GuideConfigStatusChannels.build(service, tcsTop) gg <- GuiderGains.build(service, pwfs1Top, pwfs2Top, oiTop) - gm <- GuideModeChannels.build(service, tcsTop) + gm <- ProbeGuideModeChannels.build(service, tcsTop) } yield TcsChannels[F]( tt, p1tt, diff --git a/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala b/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala index 0afa77b5..81913d4c 100644 --- a/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala +++ b/modules/server/src/main/scala/navigate/server/tcs/TcsEpicsSystem.scala @@ -90,7 +90,7 @@ object TcsEpicsSystem { val p1GuiderGainsCmd: Command3Channels[F, Double, Double, Double] val p2GuiderGainsCmd: Command3Channels[F, Double, Double, Double] val oiGuiderGainsCmd: Command3Channels[F, Double, Double, Double] - val guideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] + val probeGuideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] // val offsetACmd: OffsetCmd[F] // val offsetBCmd: OffsetCmd[F] @@ -900,16 +900,16 @@ object TcsEpicsSystem { } - override val guideModeCommand: GuideModeCommand[F, TcsCommands[F]] = - new GuideModeCommand[F, TcsCommands[F]] { + override val probeGuideModeCommand: ProbeGuideModeCommand[F, TcsCommands[F]] = + new ProbeGuideModeCommand[F, TcsCommands[F]] { override def setMode(pg: Option[ProbeGuide]): TcsCommands[F] = pg.fold( - addParam(tcsEpics.guideModeCmd.setParam1(BinaryOnOff.Off)) + addParam(tcsEpics.probeGuideModeCmd.setParam1(BinaryOnOff.Off)) )(pg => addMultipleParams( - List(tcsEpics.guideModeCmd.setParam1(BinaryOnOff.On), - tcsEpics.guideModeCmd.setParam2(pg.from), - tcsEpics.guideModeCmd.setParam3(pg.to) + List(tcsEpics.probeGuideModeCmd.setParam1(BinaryOnOff.On), + tcsEpics.probeGuideModeCmd.setParam2(pg.from), + tcsEpics.probeGuideModeCmd.setParam3(pg.to) ) ) ) @@ -1097,12 +1097,12 @@ object TcsEpicsSystem { channels.guiderGains.oiFocusGain ) - override val guideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] = + override val probeGuideModeCmd: Command3Channels[F, BinaryOnOff, GuideProbe, GuideProbe] = Command3Channels( channels.telltale, - channels.guideMode.state, - channels.guideMode.from, - channels.guideMode.to + channels.probeGuideMode.state, + channels.probeGuideMode.from, + channels.probeGuideMode.to ) } @@ -1539,7 +1539,7 @@ object TcsEpicsSystem { def fileName(v: String): S } - trait GuideModeCommand[F[_], +S] { + trait ProbeGuideModeCommand[F[_], +S] { def setMode(pg: Option[ProbeGuide]): S } @@ -1596,7 +1596,7 @@ object TcsEpicsSystem { val mountGuideCommand: MountGuideCommand[F, TcsCommands[F]] val oiWfsCommands: WfsCommands[F, TcsCommands[F]] val guiderGainsCommands: GuiderGainsCommand[F, TcsCommands[F]] - val guideModeCommand: GuideModeCommand[F, TcsCommands[F]] + val probeGuideModeCommand: ProbeGuideModeCommand[F, TcsCommands[F]] } /* diff --git a/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala b/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala index 68de793a..7e89634e 100644 --- a/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala +++ b/modules/server/src/test/scala/navigate/server/tcs/TcsBaseControllerEpicsSuite.scala @@ -776,7 +776,7 @@ class TcsBaseControllerEpicsSuite extends CatsEffectSuite { assert(r1.m2GuideReset.connected) assert(r1.mountGuide.mode.connected) assert(r1.mountGuide.source.connected) - assert(r1.guideMode.state.connected) + assert(r1.probeGuideMode.state.connected) assertEquals(r1.m1Guide.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.On.some) assertEquals(r1.m1GuideConfig.source.value.flatMap(Enumerated[M1Source].fromTag), @@ -809,7 +809,7 @@ class TcsBaseControllerEpicsSuite extends CatsEffectSuite { assertEquals(r2.mountGuide.mode.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.Off.some ) - assertEquals(r1.guideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), + assertEquals(r1.probeGuideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.Off.some ) } @@ -830,13 +830,13 @@ class TcsBaseControllerEpicsSuite extends CatsEffectSuite { _ <- ctr.enableGuide(guideCfg) r1 <- st.get } yield { - assert(r1.guideMode.state.connected) + assert(r1.probeGuideMode.state.connected) - assertEquals(r1.guideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), + assertEquals(r1.probeGuideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.On.some ) - assertEquals(r1.guideMode.from.value, "OIWFS".some) - assertEquals(r1.guideMode.to.value, "OIWFS".some) + assertEquals(r1.probeGuideMode.from.value, "OIWFS".some) + assertEquals(r1.probeGuideMode.to.value, "OIWFS".some) } } @@ -855,13 +855,13 @@ class TcsBaseControllerEpicsSuite extends CatsEffectSuite { _ <- ctr.enableGuide(guideCfg) r1 <- st.get } yield { - assert(r1.guideMode.state.connected) + assert(r1.probeGuideMode.state.connected) - assertEquals(r1.guideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), + assertEquals(r1.probeGuideMode.state.value.flatMap(Enumerated[BinaryOnOff].fromTag), BinaryOnOff.On.some ) - assertEquals(r1.guideMode.from.value, "PWFS1".some) - assertEquals(r1.guideMode.to.value, "PWFS2".some) + assertEquals(r1.probeGuideMode.from.value, "PWFS1".some) + assertEquals(r1.probeGuideMode.to.value, "PWFS2".some) } } diff --git a/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala b/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala index 16e8443f..98f1af1e 100644 --- a/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala +++ b/modules/server/src/test/scala/navigate/server/tcs/TestTcsEpicsSystem.scala @@ -20,13 +20,13 @@ import navigate.server.epicsdata.BinaryOnOff import navigate.server.epicsdata.BinaryYesNo import navigate.server.tcs.TcsChannels.EnclosureChannels import navigate.server.tcs.TcsChannels.GuideConfigStatusChannels -import navigate.server.tcs.TcsChannels.GuideModeChannels import navigate.server.tcs.TcsChannels.GuiderGainsChannels import navigate.server.tcs.TcsChannels.M1GuideConfigChannels import navigate.server.tcs.TcsChannels.M2GuideConfigChannels import navigate.server.tcs.TcsChannels.MountGuideChannels import navigate.server.tcs.TcsChannels.OriginChannels import navigate.server.tcs.TcsChannels.ProbeChannels +import navigate.server.tcs.TcsChannels.ProbeGuideModeChannels import navigate.server.tcs.TcsChannels.ProbeTrackingChannels import navigate.server.tcs.TcsChannels.RotatorChannels import navigate.server.tcs.TcsChannels.SlewChannels @@ -157,14 +157,14 @@ object TestTcsEpicsSystem { ) } - case class GuideModeState( + case class ProbeGuideModeState( state: TestChannel.State[String], from: TestChannel.State[String], to: TestChannel.State[String] ) - object GuideModeState { - val default: GuideModeState = GuideModeState( + object ProbeGuideModeState { + val default: ProbeGuideModeState = ProbeGuideModeState( TestChannel.State.default, TestChannel.State.default, TestChannel.State.default @@ -249,7 +249,7 @@ object TestTcsEpicsSystem { mountGuide: MountGuideState, guideStatus: GuideConfigState, guiderGains: GuiderGainsState, - guideMode: GuideModeState + probeGuideMode: ProbeGuideModeState ) val defaultState: State = State( @@ -352,7 +352,7 @@ object TestTcsEpicsSystem { mountGuide = MountGuideState.default, guideStatus = GuideConfigState.default, guiderGains = GuiderGainsState.default, - guideMode = GuideModeState.default + probeGuideMode = ProbeGuideModeState.default ) def buildEnclosureChannels[F[_]: Applicative](s: Ref[F, State]): EnclosureChannels[F] = @@ -705,11 +705,11 @@ object TestTcsEpicsSystem { def buildGuideModeChannels[F[_]: Applicative]( s: Ref[F, State], - l: Lens[State, GuideModeState] - ): GuideModeChannels[F] = GuideModeChannels( - new TestChannel[F, State, String](s, l.andThen(Focus[GuideModeState](_.state))), - new TestChannel[F, State, String](s, l.andThen(Focus[GuideModeState](_.from))), - new TestChannel[F, State, String](s, l.andThen(Focus[GuideModeState](_.to))) + l: Lens[State, ProbeGuideModeState] + ): ProbeGuideModeChannels[F] = ProbeGuideModeChannels( + new TestChannel[F, State, String](s, l.andThen(Focus[ProbeGuideModeState](_.state))), + new TestChannel[F, State, String](s, l.andThen(Focus[ProbeGuideModeState](_.from))), + new TestChannel[F, State, String](s, l.andThen(Focus[ProbeGuideModeState](_.to))) ) def buildChannels[F[_]: Applicative](s: Ref[F, State]): TcsChannels[F] = @@ -755,7 +755,7 @@ object TestTcsEpicsSystem { oiwfs = buildWfsChannels(s, Focus[State](_.oiWfs)), guide = buildGuideStateChannels(s, Focus[State](_.guideStatus)), guiderGains = buildGuiderGainsChannels(s, Focus[State](_.guiderGains)), - guideMode = buildGuideModeChannels(s, Focus[State](_.guideMode)) + probeGuideMode = buildGuideModeChannels(s, Focus[State](_.probeGuideMode)) ) def build[F[_]: Monad: Parallel](s: Ref[F, State]): TcsEpicsSystem[F] =