Skip to content
Snippets Groups Projects
Commit 3f258cbe authored by Stefano Di Frischia's avatar Stefano Di Frischia
Browse files

Merge branch 'master' into L2SS-937-restore-recv-cluster-integration-test

parents 658fda52 730e2ad8
Branches
Tags
1 merge request!424Resolve L2SS-937 "Restore recv cluster integration test"
Showing
with 359 additions and 10 deletions
......@@ -86,11 +86,13 @@ docker_build_image_all:
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh grafana latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh jupyter latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh apsct-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh ccd-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh apspu-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh recv-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh sdptr-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh unb2-sim latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apsct latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-ccd latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-apspu latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-tilebeam latest
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-beamlet latest
......@@ -191,6 +193,17 @@ docker_build_image_apsct_sim:
script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh apsct-sim $tag
docker_build_image_ccd_sim:
extends: .base_docker_images_except
only:
refs:
- merge_requests
changes:
- docker-compose/ccd-sim.yml
- docker-compose/pypcc-sim-base/*
script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh ccd-sim $tag
docker_build_image_apspu_sim:
extends: .base_docker_images_except
only:
......@@ -246,6 +259,17 @@ docker_build_image_device_apsct:
script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-aspct $tag
docker_build_image_device_ccd:
extends: .base_docker_images_except
only:
refs:
- merge_requests
changes:
- docker-compose/device-ccd.yml
- docker-compose/lofar-device-base/*
script:
# Do not remove 'bash' or statement will be ignored by primitive docker shell
- bash $CI_PROJECT_DIR/sbin/tag_and_push_docker_image.sh device-ccd $tag
docker_build_image_device_apspu:
extends: .base_docker_images_except
only:
......
......@@ -169,6 +169,16 @@
}
}
},
"CCD": {
"STAT": {
"CCD": {
"STAT/CCD/1": {
"properties": {
}
}
}
}
},
"APSPU": {
"STAT": {
"APSPU": {
......
......@@ -24,6 +24,7 @@
"STAT/PCON/1",
"STAT/APSPU/1",
"STAT/APSCT/1",
"STAT/CCD/1",
"STAT/RECV/1",
"STAT/UNB2/1",
"STAT/SDP/1",
......@@ -60,6 +61,25 @@
}
}
},
"CCD": {
"STAT": {
"CCD": {
"STAT/CCD/1": {
"properties": {
"OPC_Server_Name": [
"10.87.6.67 "
],
"OPC_Server_Port": [
"4843"
],
"OPC_Time_Out": [
"5.0"
]
}
}
}
}
},
"APSPU": {
"STAT": {
"APSPU": {
......
......@@ -32,6 +32,25 @@
}
}
},
"CCD": {
"STAT": {
"CCD": {
"STAT/CCD/1": {
"properties": {
"OPC_Server_Name": [
"ccd-sim"
],
"OPC_Server_Port": [
"4843"
],
"OPC_Time_Out": [
"5.0"
]
}
}
}
}
},
"APSPU": {
"STAT": {
"APSPU": {
......@@ -125,7 +144,7 @@
"RECV, HBAT_LED_on_RW"
],
"Shutdown_Device_List":[
"STAT/SDP/1", "STAT/UNB2/1", "STAT/RECV/1", "STAT/APSCT/1", "STAT/APSPU/1"
"STAT/SDP/1", "STAT/UNB2/1", "STAT/RECV/1", "STAT/APSCT/1", "STAT/CCD/1","STAT/APSPU/1"
]
}
}
......
......@@ -37,6 +37,8 @@ else
rm -rf /tmp/tangostationcontrol
cp -R /opt/lofar/tango/tangostationcontrol /tmp/
cd /tmp/tangostationcontrol || exit 1
# Remove the build directory if copied from the source
rm -rf build
pip -vvv install --upgrade --force-reinstall ./
fi
......
#
# Docker compose file that launches an APSCT simulator
#
# Defines:
# - apsct-sim
#
version: '2.1'
services:
ccd-sim:
build:
context: pypcc-sim-base
args:
- LOCAL_DOCKER_REGISTRY_HOST=${LOCAL_DOCKER_REGISTRY_HOST}
- LOCAL_DOCKER_REGISTRY_LOFAR=${LOCAL_DOCKER_REGISTRY_LOFAR}
container_name: ${CONTAINER_NAME_PREFIX}ccd-sim
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
networks:
- control
entrypoint: hwtr --simulator --port 4843 --config CCDTR
restart: on-failure
#
# Docker compose file that launches an interactive iTango session.
#
# Connect to the interactive session with 'docker attach itango'.
# Disconnect with the Docker deattach sequence: <CTRL>+<P> <CTRL>+<Q>
#
# Defines:
# - itango: iTango interactive session
#
# Requires:
# - lofar-device-base.yml
#
version: '2.1'
services:
device-ccd:
image: device-ccd
# build explicitly, as docker-compose does not understand a local image
# being shared among services.
build:
context: .
dockerfile: lofar-device-base/Dockerfile
args:
SOURCE_IMAGE: ${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/tango-itango:${TANGO_ITANGO_VERSION}
container_name: ${CONTAINER_NAME_PREFIX}device-ccd
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
networks:
- control
ports:
- "5721:5721" # unique port for this DS
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ..:/opt/lofar/tango:rw
environment:
- TANGO_HOST=${TANGO_HOST}
working_dir: /opt/lofar/tango
entrypoint:
- bin/start-ds.sh
# configure CORBA to _listen_ on 0:port, but tell others we're _reachable_ through ${HOSTNAME}:port, since CORBA
# can't know about our Docker port forwarding
- l2ss-ccd Ccd STAT -v -ORBendPoint giop:tcp:device-ccd:5721 -ORBendPointPublish giop:tcp:${HOSTNAME}:5721
restart: on-failure
# Create shortcuts for our devices
apsct = DeviceProxy("STAT/APSCT/1")
ccd = DeviceProxy("STAT/CCD/1")
apspu = DeviceProxy("STAT/APSPU/1")
recv = DeviceProxy("STAT/RECV/1")
sdp = DeviceProxy("STAT/SDP/1")
......@@ -17,4 +18,4 @@ docker = DeviceProxy("STAT/Docker/1")
temperaturemanager = DeviceProxy("STAT/TemperatureManager/1")
# Put them in a list in case one wants to iterate
devices = [apsct, apspu, recv, sdp, bst, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker]
devices = [apsct, ccd, apspu, recv, sdp, bst, sst, xst, unb2, boot, tilebeam, beamlet, digitalbeam, antennafield, temperaturemanager, docker]
......@@ -15,6 +15,8 @@
},
"stat/apsct/1": {
},
"stat/ccd/1": {
},
"stat/apspu/1": {
},
"stat/beamlet/1": {
......
......@@ -73,9 +73,9 @@ sleep 1 # dsconfig container must be up and running...
# shellcheck disable=SC2016
echo '/usr/local/bin/wait-for-it.sh ${TANGO_HOST} --strict --timeout=300 -- true' | make run dsconfig bash -
DEVICES="device-boot device-apsct device-apspu device-sdp device-recv device-bst device-sst device-unb2 device-xst device-beamlet device-digitalbeam device-tilebeam device-psoc device-pcon device-antennafield device-temperature-manager device-observation device-observation-control"
DEVICES="device-boot device-apsct device-ccd device-apspu device-sdp device-recv device-bst device-sst device-unb2 device-xst device-beamlet device-digitalbeam device-tilebeam device-psoc device-pcon device-antennafield device-temperature-manager device-observation device-observation-control"
SIMULATORS="sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim"
SIMULATORS="sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim ccd-sim"
# Build only the required images, please do not build everything that makes CI
# take really long to finish, especially grafana / jupyter / prometheus.
......
......@@ -64,11 +64,13 @@ LOCAL_IMAGES=(
"lofar-device-base lofar-device-base y"
"apsct-sim docker-compose_apsct-sim y" "apspu-sim docker-compose_apspu-sim y"
"ccd-sim docker-compose_ccd-sim y"
"recv-sim docker-compose_recv-sim y" "sdptr-sim docker-compose_sdptr-sim y"
"unb2-sim docker-compose_unb2-sim y"
"unb2-sim docker-compose_unb2-sim y"
"device-antennafield device-antennafield y"
"device-apsct device-apsct y" "device-apspu device-apspu y"
"device-ccd device-ccd y"
"device-boot device-boot y" "device-docker device-docker y"
"device-observation device-observation y"
"device-observation-control device-observation-control y"
......@@ -159,13 +161,13 @@ if [ ! -z "${1+x}" ] && [ "${1}" != "pull" ]; then
local_url="${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/${2}"
# If tag is not latest, than it is not a tagged master build and we can
# pull the latest image as cache.
# pull the latest image as cache (if it already exists).
if [ "${tag}" != "latest" ]; then
docker pull "${local_url}:latest"
docker pull "${local_url}:latest" || true
fi
make build "${1}"
docker tag "${2}" "${local_url}:${tag}"
docker tag "${2}" "${local_url}:${tag}" || docker tag "${2/_/-}" "${local_url}:${tag}"
docker push "${local_url}:${tag}"
fi
done
......
.. _ccd:
CCD
--------------------
The ``ccd == DeviceProxy("STAT/CCD/1")`` Clock Control Device controls the clock
......@@ -29,6 +29,7 @@ Even without having access to any LOFAR2.0 hardware, you can install the full st
devices/boot
devices/docker
devices/psoc
devices/ccd
devices/temperature-manager
devices/configure
configure_station
......
......@@ -35,6 +35,7 @@ where=.
[options.entry_points]
console_scripts =
l2ss-apsct = tangostationcontrol.devices.apsct:main
l2ss-ccd = tangostationcontrol.devices.ccd:main
l2ss-apspu = tangostationcontrol.devices.apspu:main
l2ss-psoc = tangostationcontrol.devices.psoc:main
l2ss-pcon = tangostationcontrol.devices.pcon:main
......
......@@ -18,4 +18,4 @@ If a new device is added, it will (likely) need to be referenced in several plac
- Add to `sbin/tag_and_push_docker_image.sh` the LOCAL_IMAGES device name, imagine name and build for integration boolean triple,
- Add to `tangostationcontrol/docs/source/devices/` to mention the device in the end-user documentation.
- Adjust `tangostationcontrol/docs/source/index.rst` to include the newly created file in `docs/source/devices/`.
- Adjust `docker-compose/tango-prometheus-exporter/lofar2-policy.json` to include this device in the prometheus exporter
......@@ -90,7 +90,8 @@ class AntennaField(lofar_device):
Antenna_Names = device_property(
doc="Name of each antenna",
dtype='DevVarStringArray',
mandatory=False
mandatory=False,
default_value = [f'Antenna{n+1}' for n in range(MAX_NUMBER_OF_HBAT)]
)
# ----- Antenna states
......
......@@ -238,6 +238,7 @@ class Boot(lofar_device):
"STAT/PCON/1", # PCON boot early because it is responsible for power delivery.
"STAT/APSPU/1", # APS Power Units control other hardware we want to initialise
"STAT/APSCT/1",
"STAT/CCD/1",
"STAT/RECV/1", # RCUs are input for SDP, so initialise them first
"STAT/UNB2/1", # Uniboards host SDP, so initialise them first
"STAT/SDP/1", # SDP controls the mask for SST/XST/BST/Beamlet, so initialise it first
......
# -*- coding: utf-8 -*-
#
# This file is part of the RECV project
#
#
#
# Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info.
""" CCD Device Server for LOFAR2.0
"""
# PyTango imports
from tango import DebugIt
from tango.server import command, attribute, device_property
from tango import AttrWriteType
import numpy
# Additional import
from tangostationcontrol.clients.attribute_wrapper import attribute_wrapper
from tangostationcontrol.common.entrypoint import entry
from tangostationcontrol.common.lofar_logging import device_logging_to_python
from tangostationcontrol.common.states import DEFAULT_COMMAND_STATES
from tangostationcontrol.devices.device_decorators import only_in_states
from tangostationcontrol.devices.opcua_device import opcua_device
import logging
logger = logging.getLogger()
__all__ = ["CCD", "main"]
@device_logging_to_python()
class CCD(opcua_device):
# -----------------
# Device Properties
# -----------------
CCDTR_monitor_rate_RW_default = device_property(
dtype='DevLong64',
mandatory=False,
default_value=1
)
# ----- Timing values
CCD_On_Off_timeout = device_property(
doc='Maximum amount of time to wait after turning CCD on or off',
dtype='DevFloat',
mandatory=False,
default_value=10.0
)
# ----------
# Attributes
# ----------
CCDTR_I2C_error_R = attribute_wrapper(comms_annotation=["CCDTR_I2C_error_R" ], datatype=numpy.int64)
CCDTR_monitor_rate_RW = attribute_wrapper(comms_annotation=["CCDTR_monitor_rate_RW" ], datatype=numpy.int64, access=AttrWriteType.READ_WRITE)
CCDTR_translator_busy_R = attribute_wrapper(comms_annotation=["CCDTR_translator_busy_R" ], datatype=bool)
CCD_clear_lock_R = attribute_wrapper(comms_annotation=["CCD_clear_lock_R" ], datatype=bool)
CCD_clear_lock_RW = attribute_wrapper(comms_annotation=["CCD_clear_lock_RW" ], datatype=bool, access=AttrWriteType.READ_WRITE)
CCD_FAN_RPM_R = attribute_wrapper(comms_annotation=["CCD_FAN_RPM_R" ], datatype=numpy.float64)
CCD_INPUT_10MHz_good_R = attribute_wrapper(comms_annotation=["CCD_INPUT_10MHz_good_R" ], datatype=bool)
CCD_INPUT_PPS_good_R = attribute_wrapper(comms_annotation=["CCD_INPUT_PPS_good_R" ], datatype=bool)
CCD_loss_lock_R = attribute_wrapper(comms_annotation=["CCD_loss_lock_R" ], datatype=bool)
CCD_PCB_ID_R = attribute_wrapper(comms_annotation=["CCD_PCB_ID_R" ], datatype=numpy.int64)
CCD_PCB_number_R = attribute_wrapper(comms_annotation=["CCD_PCB_number_R" ], datatype=str)
CCD_PCB_version_R = attribute_wrapper(comms_annotation=["CCD_PCB_version_R" ], datatype=str)
CCD_PLL_locked_R = attribute_wrapper(comms_annotation=["CCD_PLL_locked_R" ], datatype=bool)
CCD_PWR_CLK_DIST_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_CLK_DIST_3V3_R" ], datatype=numpy.float64)
CCD_PWR_CLK_INPUT_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_CLK_INPUT_3V3_R" ], datatype=numpy.float64)
CCD_PWR_CTRL_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_CTRL_3V3_R" ], datatype=numpy.float64)
CCD_PWR_OCXO_INPUT_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_OCXO_INPUT_3V3_R" ], datatype=numpy.float64)
CCD_PWR_on_R = attribute_wrapper(comms_annotation=["CCD_PWR_on_R" ], datatype=bool)
CCD_PWR_PLL_INPUT_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_PLL_INPUT_3V3_R" ], datatype=numpy.float64)
CCD_PWR_PPS_INPUT_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_PPS_INPUT_3V3_R" ], datatype=numpy.float64)
CCD_PWR_PPS_OUTPUT_3V3_R = attribute_wrapper(comms_annotation=["CCD_PWR_PPS_OUTPUT_3V3_R" ], datatype=numpy.float64)
CCD_TEMP_R = attribute_wrapper(comms_annotation=["CCD_TEMP_R" ], datatype=numpy.float64)
# ----------
# Summarising Attributes
# ----------
CCD_error_R = attribute(dtype=bool, fisallowed="is_attribute_access_allowed")
def read_CCD_error_R(self):
errors = [self.read_attribute("CCDTR_I2C_error_R") > 0,
self.alarm_val("CCD_loss_lock_R"),
self.read_attribute("CCD_INPUT_10MHz_good_R"),
not self.read_attribute("CCD_INPUT_10MHz_good_R"),
not self.read_attribute("CCD_INPUT_PPS_good_R") and not self.read_attribute("CCD_clear_lock_R"),
not self.read_attribute("CCD_PLL_locked_R")]
return any(errors)
CCD_TEMP_error_R = attribute(dtype=bool, fisallowed="is_attribute_access_allowed", polling_period=1000)
CCD_VOUT_error_R = attribute(dtype=bool, fisallowed="is_attribute_access_allowed")
def read_CCD_TEMP_error_R(self):
return (self.alarm_val("CCD_TEMP_R"))
def read_CCD_VOUT_error_R(self):
return ( self.alarm_val("CCD_PWR_CLK_DIST_3V3_R")
or self.alarm_val("CCD_PWR_CLK_INPUT_3V3_R")
or self.alarm_val("CCD_PWR_CTRL_3V3_R")
or self.alarm_val("CCD_PWR_OCXO_INPUT_3V3_R")
or self.alarm_val("CCD_PWR_PLL_INPUT_3V3_R")
or self.alarm_val("CCD_PWR_PPS_INPUT_3V3_R")
or self.alarm_val("CCD_PWR_PPS_OUTPUT_3V3_R")
or (not self.read_attribute("CCD_PWR_on_R"))
)
# --------
# overloaded functions
# --------
@command()
@DebugIt()
@only_in_states(DEFAULT_COMMAND_STATES)
def reset_hardware(self):
""" Initialise the CCD hardware. """
# Cycle clock
self.CCD_off()
self.wait_attribute("CCDTR_translator_busy_R", False, self.CCD_On_Off_timeout)
self.CCD_on()
self.wait_attribute("CCDTR_translator_busy_R", False, self.CCD_On_Off_timeout)
if not self.read_attribute("CCD_PLL_locked_R"):
if self.read_attribute("CCDTR_I2C_error_R"):
raise Exception("I2C is not working. Maybe power cycle subrack to restart CLK board and translator?")
else:
raise Exception("CCD clock is not locked")
def _disable_hardware(self):
""" Disable the CCD hardware. """
# Turn off the CCD
self.CCD_off()
self.wait_attribute("CCDTR_translator_busy_R", False, self.CCD_On_Off_timeout)
# --------
# Commands
# --------
@command()
@DebugIt()
@only_in_states(DEFAULT_COMMAND_STATES)
def CCD_off(self):
"""
:return:None
"""
self.opcua_connection.call_method(["CCD_off"])
@command()
@DebugIt()
@only_in_states(DEFAULT_COMMAND_STATES)
def CCD_on(self):
"""
:return:None
"""
self.opcua_connection.call_method(["CCD_on"])
# ----------
# Run server
# ----------
def main(**kwargs):
"""Main function of the ObservationControl module."""
return entry(CCD, **kwargs)
# -*- coding: utf-8 -*-
#
# This file is part of the LOFAR 2.0 Station Software
#
#
#
# Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info.
from .base import AbstractTestBases
class TestDeviceCCD(AbstractTestBases.TestDeviceBase):
def setUp(self):
super().setUp("STAT/CCD/1")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment