Skip to content

Commit

Permalink
Merge pull request #242 from lsst-ts/tickets/DM-46979
Browse files Browse the repository at this point in the history
Tickets/DM-46979: Make SAL Scripts to park and unpark the TMA.
  • Loading branch information
MarcoRocchietti authored Nov 19, 2024
2 parents ae0ccde + 942b085 commit a44918d
Show file tree
Hide file tree
Showing 8 changed files with 434 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/news/DM-46979.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add SAL scripts to park and unpark the TMA for ``maintel``.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import asyncio

from lsst.ts.standardscripts.maintel.mtmount import ParkMount

asyncio.run(ParkMount.amain())
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import asyncio

from lsst.ts.standardscripts.maintel.mtmount import UnparkMount

asyncio.run(UnparkMount.amain())
23 changes: 23 additions & 0 deletions python/lsst/ts/standardscripts/maintel/mtmount/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from .park_mount import *
from .unpark_mount import *
109 changes: 109 additions & 0 deletions python/lsst/ts/standardscripts/maintel/mtmount/park_mount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.``

__all__ = ["ParkMount"]

import yaml
from lsst.ts import salobj
from lsst.ts.observatory.control.maintel.mtcs import MTCS, MTCSUsages
from lsst.ts.xml.enums import MTMount


class ParkMount(salobj.BaseScript):
"""Park Mount for the MTMount.
Parameters
----------
index : `int`
Index of Script SAL component.
Notes
-----
**Checkpoints**
None
"""

def __init__(self, index):
super().__init__(index=index, descr="Park Mount for the MTMount.")

self.mtcs = None

@classmethod
def get_schema(cls):
schema_yaml = """
$schema: http://json-schema.org/draft-07/schema#
$id: https://github.com/lsst-ts/ts_standardscripts/maintel/mtmount/park_mount.yaml
title: ParkMount v1
description: Configuration for ParkMount.
type: object
properties:
position:
description: The position to park the MTMount.
type: string
enum: ["ZENITH", "HORIZON"]
ignore:
description: >-
CSCs from the group to ignore in status check. Name must
match those in self.group.components, e.g.; hexapod_1.
type: array
items:
type: string
additionalProperties: false
required: [position]
"""
return yaml.safe_load(schema_yaml)

def set_metadata(self, metadata):
pass

async def configure(self, config):
"""Configure script.
Parameters
----------
config : `types.SimpleNamespace`
Script configuration, as defined by `schema`.
"""
self.config = config
self.position = MTMount.ParkPosition[config.position]

if self.mtcs is None:
self.mtcs = MTCS(
domain=self.domain,
intended_usage=MTCSUsages.Slew | MTCSUsages.StateTransition,
log=self.log,
)
await self.mtcs.start_task

if hasattr(self.config, "ignore"):
for comp in self.config.ignore:
if comp not in self.mtcs.components_attr:
self.log.warning(
f"Component {comp} not in CSC Group. "
f"Must be one of {self.mtcs.components_attr}. Ignoring."
)
else:
self.log.debug(f"Ignoring component {comp}.")
setattr(self.mtcs.check, comp, False)

async def run(self):
await self.mtcs.park_mount(position=self.position)
101 changes: 101 additions & 0 deletions python/lsst/ts/standardscripts/maintel/mtmount/unpark_mount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.``

__all__ = ["UnparkMount"]

import yaml
from lsst.ts import salobj
from lsst.ts.observatory.control.maintel.mtcs import MTCS, MTCSUsages


class UnparkMount(salobj.BaseScript):
"""Un-park Mount for the MTMount.
Parameters
----------
index : `int`
Index of Script SAL component.
Notes
-----
**Checkpoints**
None
"""

def __init__(self, index):
super().__init__(index=index, descr="Unpark Mount for the MTMount.")

self.mtcs = None

@classmethod
def get_schema(cls):
schema_yaml = """
$schema: http://json-schema.org/draft-07/schema#
$id: https://github.com/lsst-ts/ts_standardscripts/maintel/mtmount/unpark_mount.yaml
title: UnparkMount v1
description: Configuration for UnparkMount.
type: object
properties:
ignore:
description: >-
CSCs from the group to ignore in status check. Name must
match those in self.group.components, e.g.; hexapod_1.
type: array
items:
type: string
additionalProperties: false
"""
return yaml.safe_load(schema_yaml)

def set_metadata(self, metadata):
pass

async def configure(self, config):
"""Configure script.
Parameters
----------
config : `types.SimpleNamespace`
Script configuration, as defined by `schema`.
"""
self.config = config

if self.mtcs is None:
self.mtcs = MTCS(
domain=self.domain,
intended_usage=MTCSUsages.Slew | MTCSUsages.StateTransition,
log=self.log,
)
await self.mtcs.start_task

if hasattr(self.config, "ignore"):
for comp in self.config.ignore:
if comp not in self.mtcs.components_attr:
self.log.warning(
f"Component {comp} not in CSC Group. "
f"Must be one of {self.mtcs.components_attr}. Ignoring."
)
else:
self.log.debug(f"Ignoring component {comp}.")
setattr(self.mtcs.check, comp, False)

async def run(self):
await self.mtcs.unpark_mount()
78 changes: 78 additions & 0 deletions tests/test_maintel_mtmount_park_mount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# This file is part of ts_standardscripts
#
# Developed for the LSST Telescope and Site Systems.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import contextlib
import unittest

from lsst.ts import standardscripts
from lsst.ts.standardscripts.maintel.mtmount import ParkMount
from lsst.ts.xml.enums import MTMount


class TestParkMount(
standardscripts.BaseScriptTestCase, unittest.IsolatedAsyncioTestCase
):
async def basic_make_script(self, index):
self.script = ParkMount(index=index)
return (self.script,)

@contextlib.asynccontextmanager
async def make_dry_script(self):
async with self.make_script(self):
self.script.mtcs = unittest.mock.AsyncMock()
self.script.mtcs.assert_all_enabled = unittest.mock.AsyncMock()
self.script.mtcs.park_mount = unittest.mock.AsyncMock()
yield

async def test_executable(self):
scripts_dir = standardscripts.get_scripts_dir()
script_path = scripts_dir / "maintel" / "mtmount" / "park_mount.py"
await self.check_executable(script_path)

async def test_configure_ignore(self):
async with self.make_script():
components = ["mtptg"]
await self.configure_script(position="ZENITH", ignore=components)
assert self.script.mtcs.check.mtptg is False

async def test_configure_ignore_not_mtcs_component(self):
async with self.make_script():
# Test the ignore feature with one non-MTCS component.
components = ["not_mtcs_comp", "mtptg"]
await self.configure_script(position="ZENITH", ignore=components)
assert not hasattr(self.script.mtcs.check, "not_mtcs_comp")
assert self.script.mtcs.check.mtptg is False

async def test_park_zenith(self):
async with self.make_dry_script():
await self.configure_script(position="ZENITH")
await self.run_script()
self.script.mtcs.park_mount.assert_called_with(
position=MTMount.ParkPosition.ZENITH
)

async def test_park_horizon(self):
async with self.make_dry_script():
await self.configure_script(position="HORIZON")
await self.run_script()
self.script.mtcs.park_mount.assert_called_with(
position=MTMount.ParkPosition.HORIZON
)
Loading

0 comments on commit a44918d

Please sign in to comment.