Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for FVC IEB #152

Merged
merged 8 commits into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

## 🚀 New

* Add commands 45, 104, and 105 for hall sensor calibration querying.
* [#152](https://github.com/sdss/jaeger/pull/152) FVC IEB support and actor commands.
* Add commands `GET_HALL_CALIB_ERROR`, `GET_ALPHA_HALL_CALIB`, and `GET_BETA_HALL_CALIB` for hall sensor calibration querying.

## ✨ Improved

Expand Down
1 change: 1 addition & 0 deletions python/jaeger/actor/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@


from .debug import *
from .fvc import *
from .ieb import *
from .pollers import *
from .positioner import *
Expand Down
124 changes: 124 additions & 0 deletions python/jaeger/actor/commands/fvc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# @Author: José Sánchez-Gallego (gallegoj@uw.edu)
# @Date: 2021-07-27
# @Filename: fvc.py
# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause)

from __future__ import annotations

from typing import cast

import click

from clu import Command
from drift import DriftError, Relay

from jaeger import FPS
from jaeger.ieb import FVC

from ..actor import JaegerActor
from . import jaeger_parser


__all__ = ["fvc"]


@jaeger_parser.group()
def fvc():
"""Commands to command the FVC."""

pass


@fvc.command()
async def status(command: Command[JaegerActor], fps: FPS):
"""Reports the status of the FVC."""

fvc_ieb = FVC.create()

try:
status = {}
categories = fvc_ieb.get_categories()
for category in sorted(categories):
cat_data = await fvc_ieb.read_category(category)
status[category] = []
for cd in cat_data:
value = cat_data[cd][0]
if value == "closed":
value = True
elif value == "open":
value = False
else:
value = round(value, 1)
status[category].append(value)

command.finish(status)

except DriftError:
return command.fail(error="FVC IEB is unavailable or failed to connect.")


async def _power_device(device: str, mode: str):
"""Power on/off the device."""

fvc_ieb = FVC.create()

dev: Relay = cast(Relay, fvc_ieb.get_device(device))
if mode == "on":
await dev.close()
else:
await dev.open()


async def _execute_on_off_command(
command: Command[JaegerActor], device: str, mode: str
):
"""Executes the on/off command."""

mode = mode.lower()

try:
await _power_device(device, mode)
command.info(text=f"{device} is now {mode}.")
except DriftError:
return command.fail(error=f"Failed to turn {device} {mode}.")

status_cmd = Command("fvc status", parent=command)
await status_cmd.parse()

return command.finish()


@fvc.command()
@click.argument("MODE", type=click.Choice(["on", "off"], case_sensitive=False))
async def camera(command: Command[JaegerActor], fps: FPS, mode: str):
"""Turns camera on/off."""

await _execute_on_off_command(command, "FVC", mode)


@fvc.command()
@click.argument("MODE", type=click.Choice(["on", "off"], case_sensitive=False))
async def NUC(command: Command[JaegerActor], fps: FPS, mode: str):
"""Turns NUC on/off."""

await _execute_on_off_command(command, "NUC", mode)


@fvc.command()
@click.argument("LEVEL", type=int)
async def led(command: Command[JaegerActor], fps: FPS, level: int):
"""Sets the level of the FVC LED."""

fvc_ieb = FVC.create()
led = fvc_ieb.get_device("LED1")

raw_value = 32 * int(1023 * (level / 100))
await led.write(raw_value)

status_cmd = Command("fvc status", parent=command)
await status_cmd.parse()

return command.finish()
59 changes: 59 additions & 0 deletions python/jaeger/etc/fvc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
address: sdss-fvc-wago
port: 502
modules:
ANALOG1:
model: 750-450
mode: input_register
channels: 4
description: Pt RTD sensors
devices:
RTD1:
address: 40005
category: fvc_temperature
adaptor: rtd
units: degC
description: IEB inside air temperature
RTD2:
address: 40006
category: fvc_temperature
adaptor: rtd
units: degC
description:
RTD3:
address: 40007
category: fvc_temperature
adaptor: rtd
units: degC
description:
ANALOG_OUTPUT1:
model: 750-511
mode: holding_register
channels: 2
description: Pulse Width Modulator (PWM) output module for LED control
devices:
LED1:
address: 40514
category: fvc_led
adaptor: pwd
units: percent
description: Red LED
DO1:
model: 750-530
mode: holding_register
channels: 8
description: Relays for AC power switching
devices:
NUC:
address: 40517
channel: 0
type: relay
category: fvc_power_nuc
relay_type: NC
description: FVC NUC
FVC:
address: 40517
channel: 1
type: relay
category: fvc_power_camera
relay_type: NO
description: FVC camera power
1 change: 1 addition & 0 deletions python/jaeger/etc/jaeger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ positioner:
files:
log_dir: /data/logs/jaeger
ieb_config: etc/ieb.yaml
fvc_config: etc/fvc.yaml

low_temperature:
sensor: RTD2
Expand Down
24 changes: 24 additions & 0 deletions python/jaeger/etc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@
{ "title": "NUC6", "type": "boolean" }
]
},
"fvc_temperature": {
"type": "array",
"description": "FVC temperature measurements",
"items": [
{ "title": "RTD1", "type": "number" },
{ "title": "RTD2", "type": "number" },
{ "title": "RTD3", "type": "number" }
]
},
"fvc_power_nuc": {
"type": "array",
"description": "FVC NUC power",
"items": [{ "title": "NUC", "type": "boolean" }]
},
"fvc_power_camera": {
"type": "array",
"description": "FVC camera power",
"items": [{ "title": "FVC", "type": "boolean" }]
},
"fvc_led": {
"type": "array",
"description": "FVC LED power",
"items": [{ "title": "LED1", "type": "number" }]
},
"move_time": { "type": "number" },
"locked": { "type": "boolean" },
"n_positioners": { "type": "integer" },
Expand Down
18 changes: 15 additions & 3 deletions python/jaeger/ieb.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from jaeger import config


__all__ = ["IEB"]
__all__ = ["IEB", "FVC"]


class IEB(Drift):
Expand All @@ -34,10 +34,10 @@ def __init__(self, *args, **kwargs):
self._categories = None

@classmethod
def create(cls):
def create(cls, path=None):
"""Creates an `.IEB` instance with the default configuration."""

default_ieb_path = config["files"]["ieb_config"]
default_ieb_path = path or config["files"]["ieb_config"]

default_ieb_path = os.path.expanduser(os.path.expandvars(default_ieb_path))
if not os.path.isabs(default_ieb_path):
Expand Down Expand Up @@ -88,3 +88,15 @@ async def get_status(self) -> Dict[str, Any]:
status[device] = value

return status


class FVC(IEB):
"""Connects to the FVC IEB."""

@classmethod
def create(cls, path=None):
"""Creates an `.FVC` instance with the default configuration."""

default_ieb_path = config["files"]["fvc_config"]

return super().create(default_ieb_path)