diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0371a7f7f806a9a6e9ac5c22d8c5562c6880a4eb..14ee77667f38df99badcb69c35a823b7ca62a283 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,7 @@ # images is in place. image: artefact.skao.int/ska-tango-images-tango-itango:9.3.5 variables: + GIT_SUBMODULE_STRATEGY: recursive PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" # The PBR dependency requires a set version, not actually used # Instead `util/lofar_git.py:get_version()` is used. @@ -16,11 +17,12 @@ stages: - unit-tests - integration-tests newline_at_eof: - stage: linting - before_script: - - pip3 install -r devices/test-requirements.txt - script: - - flake8 --filename *.sh,*.conf,*.md,*.yml --select=W292 --exclude .tox,.egg-info,docker + stage: linting + before_script: + - pip3 install -r devices/test-requirements.txt + script: +# TODO(Corne): Ignore shell files in submodules more cleanly + - flake8 --filename *.sh,*.conf,*.md,*.yml --select=W292 --exclude docker-compose/tango-prometheus-exporter,.tox,.egg-info,docker python_linting: stage: linting script: @@ -37,6 +39,7 @@ shellcheck: - sudo apt-get update - sudo apt-get install -y shellcheck script: +# TODO(Corne): Ignore shell files in submodules - shellcheck **/*.sh unit_test: stage: unit-tests @@ -45,28 +48,33 @@ unit_test: - sudo apt-get install -y git script: - cd devices - - tox --recreate -e py37 -integration_test: + - tox -e py37 +integration_test_docker: stage: integration-tests - allow_failure: true + image: docker:latest tags: - privileged services: - - name: docker:20.10.8-dind + - name: docker:dind variables: DOCKER_TLS_CERTDIR: "/certs" -# Everything below does not work currently, we need a privileged container -# that can run the dind service before_script: - - sudo apt update - - sudo apt install -y docker.io - - export USER=$(id | awk -F'=' '{print $2}' | awk -F'(' '{print $2}' | awk -F')' '{print $1}') - - echo $USER -# - sudo usermod -aG docker $USER - - sudo docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - apk add --update make bash docker-compose + - apk add --update bind-tools + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - - touch /home/$USER/.Xauthority - - source bootstrap/etc/lofar20rc.sh - - export HOSTNAME=$(cat /run/systemd/netif/leases/2 | grep ^ADDRESS= | awk -F'=' '{print $2}') - - echo $HOSTNAME - - sudo $CI_PROJECT_DIR/sbin/run_integration_test.sh + - touch /root/.Xauthority +# Hack BASH_SOURCE into sourced files, docker its sh shell won't set this + - export BASH_SOURCE=$(pwd)/bootstrap/etc/lofar20rc.sh +# Hack HOSTNAME env variable into host.docker.internal, set in docker-compose + - export HOSTNAME=host.docker.internal +# - export HOSTNAME=$(hostname -i) +# - export HOSTNAME=$(cat /run/systemd/netif/leases/2 | grep ^ADDRESS= | awk -F'=' '{print $2}') +# source the lofarrc file and mask its non zero exit code + - . bootstrap/etc/lofar20rc.sh || true +# TANGO_HOST must be unset our databaseds will be unreachable + - unset TANGO_HOST +# Allow integration test to execute + - chmod u+x $CI_PROJECT_DIR/sbin/run_integration_test.sh +# Do not remove 'bash' or statement will be ignored by primitive docker shell + - bash $CI_PROJECT_DIR/sbin/run_integration_test.sh diff --git a/CDB/stations/DTS_ConfigDb.json b/CDB/stations/DTS_ConfigDb.json index 685a3d62da82e40aa05ea409c20f2475e3472ea5..48f333e2b01a05a9b2ae700cedee61e5fb396579 100644 --- a/CDB/stations/DTS_ConfigDb.json +++ b/CDB/stations/DTS_ConfigDb.json @@ -63,7 +63,7 @@ "LTS/SDP/1": { "properties": { "OPC_Server_Name": [ - "dop36.astron.nl" + "10.99.0.252" ], "OPC_Server_Port": [ "4840" @@ -100,7 +100,7 @@ "LTS/SST/1": { "properties": { "OPC_Server_Name": [ - "dop36.astron.nl" + "10.99.0.252" ], "OPC_Server_Port": [ "4840" @@ -127,22 +127,22 @@ "0c:c4:7a:c0:30:f1" ], "FPGA_sst_offload_hdr_ip_destination_address_RW_default": [ - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1" + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250" ] } } @@ -155,7 +155,7 @@ "LTS/XST/1": { "properties": { "OPC_Server_Name": [ - "dop36.astron.nl" + "10.99.0.252" ], "OPC_Server_Port": [ "4840" @@ -182,22 +182,22 @@ "0c:c4:7a:c0:30:f1" ], "FPGA_xst_offload_hdr_ip_destination_address_RW_default": [ - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1", - "10.99.0.1" + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250", + "10.99.250.250" ] } } diff --git a/CDB/stations/LTS_ConfigDb.json b/CDB/stations/LTS_ConfigDb.json index 672ff0210a9bad8ed6c48db2f648393b8cee0069..ae87cfeaf8a1ceda043ecc3f130776fa73e944bc 100644 --- a/CDB/stations/LTS_ConfigDb.json +++ b/CDB/stations/LTS_ConfigDb.json @@ -72,7 +72,7 @@ "LTS/SDP/1": { "properties": { "OPC_Server_Name": [ - "dop36.astron.nl" + "dop369.astron.nl" ], "OPC_Server_Port": [ "4840" @@ -115,7 +115,7 @@ "5101" ], "OPC_Server_Name": [ - "dop36.astron.nl" + "dop369.astron.nl" ], "OPC_Server_Port": [ "4840" @@ -194,7 +194,7 @@ "5102" ], "OPC_Server_Name": [ - "dop36.astron.nl" + "dop369.astron.nl" ], "OPC_Server_Port": [ "4840" diff --git a/CDB/stations/simulators_configDb.json b/CDB/stations/simulators_ConfigDb.json similarity index 100% rename from CDB/stations/simulators_configDb.json rename to CDB/stations/simulators_ConfigDb.json diff --git a/bin/dump_ConfigDb.sh b/bin/dump_ConfigDb.sh index 7745c18482000fe2e7a726e27b6fa5eeae57e88e..0dc634c458b76cd5d3c13e2d7dab6e905f66248a 100755 --- a/bin/dump_ConfigDb.sh +++ b/bin/dump_ConfigDb.sh @@ -1,4 +1,4 @@ #!/bin/bash -# writes the JSON dump to stdout -docker exec -it dsconfig python -m dsconfig.dump +# writes the JSON dump to stdout, Do not change -i into -it incompatible with gitlab ci! +docker exec -i "${CONTAINER_NAME_PREFIX}"dsconfig python -m dsconfig. diff --git a/bin/itango_console.sh b/bin/itango_console.sh index fb4c9b8a285adca3211633fb89e6e9e59bd01087..c2474781787257c6ab3ee0656659415f09380b29 100755 --- a/bin/itango_console.sh +++ b/bin/itango_console.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec docker exec -it itango itango3 +exec docker exec -it "${CONTAINER_NAME_PREFIX}"itango itango3 diff --git a/bin/itango_shell.sh b/bin/itango_shell.sh index abab9ef8515fd5ce1a1bf2d6d452a538426a499a..334953de3cca29ff459f6c861637c0859b1da97b 100755 --- a/bin/itango_shell.sh +++ b/bin/itango_shell.sh @@ -1,2 +1,2 @@ #!/bin/bash -exec docker exec -it itango /bin/bash +exec docker exec -it "${CONTAINER_NAME_PREFIX}"itango /bin/bash diff --git a/bin/start-DS.sh b/bin/start-DS.sh deleted file mode 100755 index 83a6eec6dd30f2e496fa03ffc6f7351d8e9a664d..0000000000000000000000000000000000000000 --- a/bin/start-DS.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -function help() -{ - why="${1}" - echo -e "*** Cannot start the Python device server.\\n${why}\\n\\n* The Python file for the device server must be the 1st parameter that is provided.\\n* The instance of this device server must be the 2nd parameter that is provided." - exit -1 -} - -# Check if the mandatory parameters are present: -# ${1}: device server's Python file -# ${2}: instance of the device server's executable in the configDB -case ${#} in - 0) - help "The device server's Python file and the instance are missing." - ;; - 1) - help "The device server's instance is missing." - ;; - *) - deviceServer="${1}" - shift - instance="${1}" - shift - ;; -esac - -# Find the path to the device server's Python file that is -# relative to the /hosthome directory (in Docker the user's -# mounted ${HOME}). -# ATTENTION -# This is assuming that the device server's Python file exists -# on the Docker's host in the user's ${HOME} directory. -runThis=$(basename "${deviceServer}") -runThis=${runThis//.sh/.py} -if [ -f "${runThis}" ]; then - myDir=${PWD} -else - myDir=${PWD}/$(dirname "${deviceServer}") -fi -deviceServerPath=${myDir/${HOME}/\/hosthome} - -# Tango log lines start with a UNIX timestamp. Replace them with the UTC time. -docker exec -it itango python3 "${deviceServerPath}/${runThis}" "${instance}" "${@}" | perl -ne 'use Time::Piece; s/^([0-9]+)/gmtime($1)->strftime("%F %T")/e; print;' diff --git a/bootstrap/etc/lofar20rc.sh b/bootstrap/etc/lofar20rc.sh index 9a9dd658b56f5d30bb1ff8c5de692bd8fe2164de..6e4a5c9bc8d6a78c1b61cca02159ee01291d3805 100755 --- a/bootstrap/etc/lofar20rc.sh +++ b/bootstrap/etc/lofar20rc.sh @@ -16,6 +16,14 @@ if [ ! -f "${LOFAR20_DIR}/.git/hooks/post-checkout" ]; then alias git="cp ${LOFAR20_DIR}/bin/update_submodules.sh ${LOFAR20_DIR}/.git/hooks/post-checkout; cp ${LOFAR20_DIR}/bin/update_submodules.sh ${LOFAR20_DIR}/.git/hooks/post-merge; unalias git; git" fi +if [ ! -z ${CI_BUILD_ID+x} ]; then + export CONTAINER_NAME_PREFIX=${CI_BUILD_ID}- +elif [ ! -z ${CI_JOB_ID+x} ]; then + export CONTAINER_NAME_PREFIX=${CI_JOB_ID}- +else + unset CONTAINER_NAME_PREFIX +fi + # This needs to be modified for a development environment. # In case you run multiple Docker networks on the same host in parallel, you need to specify a unique # network name for each of them. @@ -26,7 +34,6 @@ export NETWORK_MODE=tangonet # Example: export TANGO_HOST=station-xk25.astron.nl:10000 export TANGO_HOST=$(hostname):10000 - # # NO MODIFICATION BEYOND THIS POINT! # diff --git a/devices/clients/attribute_wrapper.py b/devices/clients/attribute_wrapper.py index e55a662142cb89f62775fb7ac2189c063593df37..e025d56d3421144b0dfeb1457f417fd4946a2671 100644 --- a/devices/clients/attribute_wrapper.py +++ b/devices/clients/attribute_wrapper.py @@ -154,7 +154,7 @@ class attribute_wrapper(attribute): try: self.read_function, self.write_function = client.setup_attribute(self.comms_annotation, self) except Exception as e: - raise Exception("Exception while setting %s attribute with annotation: '%s'", client.__class__.__name__, self.comms_annotation) from e + raise Exception(f"Exception while setting {client.__class__.__name__} attribute with annotation: {self.comms_annotation}") from e async def async_set_comm_client(self, client): """ @@ -163,7 +163,7 @@ class attribute_wrapper(attribute): try: self.read_function, self.write_function = await client.setup_attribute(self.comms_annotation, self) except Exception as e: - raise Exception("Exception while setting %s attribute with annotation: '%s'", client.__class__.__name__, self.comms_annotation) from e + raise Exception(f"Exception while setting {client.__class__.__name__} attribute with annotation: {self.comms_annotation}") from e def set_pass_func(self): def pass_func(value=None): diff --git a/devices/clients/opcua_client.py b/devices/clients/opcua_client.py index bf68edd19318648f1c8313f349a63671000382c7..1c6ee35621dcc1ca5671ffbb31bbc71ddfa75faf 100644 --- a/devices/clients/opcua_client.py +++ b/devices/clients/opcua_client.py @@ -86,7 +86,9 @@ class OPCUAConnection(AsyncCommClient): ping the client to make sure the connection with the client is still functional. """ try: - await self.client.send_hello() + # do a cheap call. NOTE: send_hello is not allowed after establishing a connection, + # so cannot be used here. see https://reference.opcfoundation.org/v104/Core/docs/Part6/7.1.3/ + _ = await self.client.get_namespace_array() except Exception as e: raise IOError("Lost connection to server %s: %s", self._servername(), e) diff --git a/devices/devices/apsct.py b/devices/devices/apsct.py index c8b0cb0ad8843fc44fd6c3e298d3a6cfd15d6f5f..78a0626d8a12985d944c752e544aff93209373be 100644 --- a/devices/devices/apsct.py +++ b/devices/devices/apsct.py @@ -46,11 +46,14 @@ class APSCT(opcua_device): # Attributes # ---------- + APSCTTR_I2C_error_R = attribute_wrapper(comms_annotation=["APSCTTR_I2C_error_R" ],datatype=numpy.int64 ) + APSCTTR_monitor_rate_RW = attribute_wrapper(comms_annotation=["APSCTTR_monitor_rate_RW" ],datatype=numpy.int64 , access=AttrWriteType.READ_WRITE) APSCTTR_translator_busy_R = attribute_wrapper(comms_annotation=["APSCTTR_translator_busy_R" ],datatype=numpy.bool_ ) - APSCT_I2C_error_R = attribute_wrapper(comms_annotation=["APSCT_I2C_error_R" ],datatype=numpy.int64 ) - APSCT_ID_R = attribute_wrapper(comms_annotation=["APSCT_ID_R" ],datatype=numpy.int64 ) APSCT_INPUT_10MHz_good_R = attribute_wrapper(comms_annotation=["APSCT_INPUT_10MHz_good_R" ],datatype=numpy.bool_ ) APSCT_INPUT_PPS_good_R = attribute_wrapper(comms_annotation=["APSCT_INPUT_PPS_good_R" ],datatype=numpy.bool_ ) + APSCT_PCB_ID_R = attribute_wrapper(comms_annotation=["APSCT_PCB_ID_R" ],datatype=numpy.int64 ) + APSCT_PCB_number_R = attribute_wrapper(comms_annotation=["APSCT_PCB_number_R" ],datatype=numpy.str ) + APSCT_PCB_version_R = attribute_wrapper(comms_annotation=["APSCT_PCB_version_R" ],datatype=numpy.str ) APSCT_PLL_160MHz_error_R = attribute_wrapper(comms_annotation=["APSCT_PLL_160MHz_error_R" ],datatype=numpy.bool_ ) APSCT_PLL_160MHz_locked_R = attribute_wrapper(comms_annotation=["APSCT_PLL_160MHz_locked_R" ],datatype=numpy.bool_ ) APSCT_PLL_200MHz_error_R = attribute_wrapper(comms_annotation=["APSCT_PLL_200MHz_error_R" ],datatype=numpy.bool_ ) @@ -67,8 +70,7 @@ class APSCT(opcua_device): APSCT_PWR_PLL_200MHz_3V3_R = attribute_wrapper(comms_annotation=["APSCT_PWR_PLL_200MHz_3V3_R"],datatype=numpy.float64) APSCT_PWR_PLL_200MHz_on_R = attribute_wrapper(comms_annotation=["APSCT_PWR_PLL_200MHz_on_R" ],datatype=numpy.bool_ ) APSCT_PWR_PPSDIST_3V3_R = attribute_wrapper(comms_annotation=["APSCT_PWR_PPSDIST_3V3_R" ],datatype=numpy.float64) - APSCT_temperature_R = attribute_wrapper(comms_annotation=["APSCT_temperature_R" ],datatype=numpy.float64) - APSCT_version_R = attribute_wrapper(comms_annotation=["APSCT_version_R" ],datatype=numpy.str ) + APSCT_TEMP_R = attribute_wrapper(comms_annotation=["APSCT_TEMP_R" ],datatype=numpy.float64) # -------- # overloaded functions diff --git a/devices/devices/apspu.py b/devices/devices/apspu.py index cec9e56364a7c78d8938d0fb9241a840d1e0f95e..3daab9c071a73b75a4d28def984d4794d4aa7aef 100644 --- a/devices/devices/apspu.py +++ b/devices/devices/apspu.py @@ -43,22 +43,24 @@ class APSPU(opcua_device): # Attributes # ---------- + APSPUTR_I2C_error_R = attribute_wrapper(comms_annotation=["APSPUTR_I2C_error_R" ],datatype=numpy.int64 ) + APSPUTR_monitor_rate_RW = attribute_wrapper(comms_annotation=["APSPUTR_monitor_rate_RW" ],datatype=numpy.int64 , access=AttrWriteType.READ_WRITE) APSPUTR_translator_busy_R = attribute_wrapper(comms_annotation=["APSPUTR_translator_busy_R" ],datatype=numpy.bool_ ) - APSPU_FAN1_RMS_R = attribute_wrapper(comms_annotation=["APSPU_FAN1_RMS_R" ],datatype=numpy.float64) - APSPU_FAN2_RMS_R = attribute_wrapper(comms_annotation=["APSPU_FAN2_RMS_R" ],datatype=numpy.float64) - APSPU_FAN3_RMS_R = attribute_wrapper(comms_annotation=["APSPU_FAN3_RMS_R" ],datatype=numpy.float64) - APSPU_I2C_error_R = attribute_wrapper(comms_annotation=["APSPU_I2C_error_R" ],datatype=numpy.int64 ) - APSPU_ID_R = attribute_wrapper(comms_annotation=["APSPU_ID_R" ],datatype=numpy.int64 ) + APSPU_FAN1_RPM_R = attribute_wrapper(comms_annotation=["APSPU_FAN1_RPM_R" ],datatype=numpy.float64) + APSPU_FAN2_RPM_R = attribute_wrapper(comms_annotation=["APSPU_FAN2_RPM_R" ],datatype=numpy.float64) + APSPU_FAN3_RPM_R = attribute_wrapper(comms_annotation=["APSPU_FAN3_RPM_R" ],datatype=numpy.float64) APSPU_LBA_IOUT_R = attribute_wrapper(comms_annotation=["APSPU_LBA_IOUT_R" ],datatype=numpy.float64) APSPU_LBA_TEMP_R = attribute_wrapper(comms_annotation=["APSPU_LBA_TEMP_R" ],datatype=numpy.float64) APSPU_LBA_VOUT_R = attribute_wrapper(comms_annotation=["APSPU_LBA_VOUT_R" ],datatype=numpy.float64) + APSPU_PCB_ID_R = attribute_wrapper(comms_annotation=["APSPU_PCB_ID_R" ],datatype=numpy.int64 ) + APSPU_PCB_number_R = attribute_wrapper(comms_annotation=["APSPU_PCB_number_R" ],datatype=numpy.str ) + APSPU_PCB_version_R = attribute_wrapper(comms_annotation=["APSPU_PCB_version_R" ],datatype=numpy.str ) APSPU_RCU2A_IOUT_R = attribute_wrapper(comms_annotation=["APSPU_RCU2A_IOUT_R" ],datatype=numpy.float64) APSPU_RCU2A_TEMP_R = attribute_wrapper(comms_annotation=["APSPU_RCU2A_TEMP_R" ],datatype=numpy.float64) APSPU_RCU2A_VOUT_R = attribute_wrapper(comms_annotation=["APSPU_RCU2A_VOUT_R" ],datatype=numpy.float64) APSPU_RCU2D_IOUT_R = attribute_wrapper(comms_annotation=["APSPU_RCU2D_IOUT_R" ],datatype=numpy.float64) APSPU_RCU2D_TEMP_R = attribute_wrapper(comms_annotation=["APSPU_RCU2D_TEMP_R" ],datatype=numpy.float64) APSPU_RCU2D_VOUT_R = attribute_wrapper(comms_annotation=["APSPU_RCU2D_VOUT_R" ],datatype=numpy.float64) - APSPU_version_R = attribute_wrapper(comms_annotation=["APSPU_version_R" ],datatype=numpy.str ) # -------- # overloaded functions diff --git a/devices/devices/hardware_device.py b/devices/devices/hardware_device.py index 7c7e6663cff7a68f8b0340d59f076bb946ea9ec5..89cc9f58cbd592c5321302abfb184bfd4dc72067 100644 --- a/devices/devices/hardware_device.py +++ b/devices/devices/hardware_device.py @@ -102,7 +102,7 @@ class hardware_device(Device, metaclass=AbstractDeviceMetas): # -------- @command() - @only_in_states([DevState.FAULT, DevState.OFF]) + @only_in_states([DevState.OFF]) @DebugIt() @fault_on_error() @log_exceptions() diff --git a/devices/devices/observation.py b/devices/devices/observation.py index 0ac9cbc1837fdd8e7ded14bb6c8459226c223866..fc69158c7215b29c3fd05c204032a15661ec3e15 100644 --- a/devices/devices/observation.py +++ b/devices/devices/observation.py @@ -62,7 +62,7 @@ class Observation(Device): # Lifecycle functions @command(dtype_in = DevString) - @only_in_states([DevState.FAULT, DevState.OFF]) + @only_in_states([DevState.OFF]) @log_exceptions() def Initialise(self, parameters: DevString = None): self.set_state(DevState.INIT) diff --git a/devices/devices/observation_control.py b/devices/devices/observation_control.py index 9b60f86bb983057d023483ebaa61164bdfba5bee..42a8c5d8298df0ec215f862598fd8dc71fb9eaff 100644 --- a/devices/devices/observation_control.py +++ b/devices/devices/observation_control.py @@ -123,7 +123,7 @@ class ObservationControl(Device): # Lifecycle functions @command() - @only_in_states([DevState.FAULT, DevState.OFF]) + @only_in_states([DevState.OFF]) @log_exceptions() @DebugIt() def Initialise(self): diff --git a/devices/devices/recv.py b/devices/devices/recv.py index d180e955a56ee583a7a2fbc1a732d933c27acced..b5cc7f6e7cd6031d290f0d2509ec651dc181765a 100644 --- a/devices/devices/recv.py +++ b/devices/devices/recv.py @@ -63,11 +63,12 @@ class RECV(opcua_device): # ---------- # Attributes # ---------- - Ant_status_R = attribute(dtype=str, max_dim_x=3, max_dim_y=32) + ANT_status_R = attribute(dtype=str, max_dim_x=3, max_dim_y=32) + RCU_LED_colour_R = attribute(dtype=numpy.uint32, max_dim_x=32, fget=lambda self: (2 * self.RCU_LED_green_on_R + 4 * self.RCU_LED_red_on_R).astype(numpy.uint32)) ANT_mask_RW = attribute_wrapper(comms_annotation=["ANT_mask_RW" ],datatype=numpy.bool_ , dims=(3,32), access=AttrWriteType.READ_WRITE) - HBAT_beamformer_delays_R = attribute_wrapper(comms_annotation=["HBAT_beamformer_delays_R" ],datatype=numpy.int64 , dims=(32,96)) - HBAT_beamformer_delays_RW = attribute_wrapper(comms_annotation=["HBAT_beamformer_delays_RW" ],datatype=numpy.int64 , dims=(32,96), access=AttrWriteType.READ_WRITE) + HBAT_BF_delays_R = attribute_wrapper(comms_annotation=["HBAT_BF_delays_R" ],datatype=numpy.int64 , dims=(32,96)) + HBAT_BF_delays_RW = attribute_wrapper(comms_annotation=["HBAT_BF_delays_RW" ],datatype=numpy.int64 , dims=(32,96), access=AttrWriteType.READ_WRITE) HBAT_LED_on_R = attribute_wrapper(comms_annotation=["HBAT_LED_on_R" ],datatype=numpy.bool_ , dims=(32,96)) HBAT_LED_on_RW = attribute_wrapper(comms_annotation=["HBAT_LED_on_RW" ],datatype=numpy.bool_ , dims=(32,96), access=AttrWriteType.READ_WRITE) HBAT_PWR_LNA_on_R = attribute_wrapper(comms_annotation=["HBAT_PWR_LNA_on_R" ],datatype=numpy.bool_ , dims=(32,96)) @@ -82,14 +83,14 @@ class RECV(opcua_device): RCU_DTH_freq_R = attribute_wrapper(comms_annotation=["RCU_DTH_freq_R" ],datatype=numpy.int64 , dims=(3,32)) RCU_DTH_freq_RW = attribute_wrapper(comms_annotation=["RCU_DTH_freq_RW" ],datatype=numpy.int64 , dims=(3,32), access=AttrWriteType.READ_WRITE) RCU_DTH_on_R = attribute_wrapper(comms_annotation=["RCU_DTH_on_R" ],datatype=numpy.bool_ , dims=(3,32)) - RCU_DTH_shutdown_R = attribute_wrapper(comms_annotation=["RCU_DTH_shutdown_R" ],datatype=numpy.bool_ , dims=(3,32)) - RCU_I2C_error_R = attribute_wrapper(comms_annotation=["RCU_I2C_error_R" ],datatype=numpy.int64 , dims=(32,)) - RCU_ID_R = attribute_wrapper(comms_annotation=["RCU_ID_R" ],datatype=numpy.int64 , dims=(32,)) - RCU_LED_green_off_R = attribute_wrapper(comms_annotation=["RCU_LED_green_off_R" ],datatype=numpy.bool_ , dims=(32,)) - RCU_LED_green_off_RW = attribute_wrapper(comms_annotation=["RCU_LED_green_off_RW" ],datatype=numpy.bool_ , dims=(32,), access=AttrWriteType.READ_WRITE) - RCU_LED_red_off_R = attribute_wrapper(comms_annotation=["RCU_LED_red_off_R" ],datatype=numpy.bool_ , dims=(32,)) - RCU_LED_red_off_RW = attribute_wrapper(comms_annotation=["RCU_LED_red_off_RW" ],datatype=numpy.bool_ , dims=(32,), access=AttrWriteType.READ_WRITE) + RCU_LED_green_on_R = attribute_wrapper(comms_annotation=["RCU_LED_green_on_R" ],datatype=numpy.bool_ , dims=(32,)) + RCU_LED_green_on_RW = attribute_wrapper(comms_annotation=["RCU_LED_green_on_RW" ],datatype=numpy.bool_ , dims=(32,), access=AttrWriteType.READ_WRITE) + RCU_LED_red_on_R = attribute_wrapper(comms_annotation=["RCU_LED_red_on_R" ],datatype=numpy.bool_ , dims=(32,)) + RCU_LED_red_on_RW = attribute_wrapper(comms_annotation=["RCU_LED_red_on_RW" ],datatype=numpy.bool_ , dims=(32,), access=AttrWriteType.READ_WRITE) RCU_mask_RW = attribute_wrapper(comms_annotation=["RCU_mask_RW" ],datatype=numpy.bool_ , dims=(32,), access=AttrWriteType.READ_WRITE) + RCU_PCB_ID_R = attribute_wrapper(comms_annotation=["RCU_PCB_ID_R" ],datatype=numpy.int64 , dims=(32,)) + RCU_PCB_number_R = attribute_wrapper(comms_annotation=["RCU_PCB_number_R" ],datatype=numpy.str , dims=(32,)) + RCU_PCB_version_R = attribute_wrapper(comms_annotation=["RCU_PCB_version_R" ],datatype=numpy.str , dims=(32,)) RCU_PWR_1V8_R = attribute_wrapper(comms_annotation=["RCU_PWR_1V8_R" ],datatype=numpy.float64, dims=(32,)) RCU_PWR_2V5_R = attribute_wrapper(comms_annotation=["RCU_PWR_2V5_R" ],datatype=numpy.float64, dims=(32,)) RCU_PWR_3V3_R = attribute_wrapper(comms_annotation=["RCU_PWR_3V3_R" ],datatype=numpy.float64, dims=(32,)) @@ -101,8 +102,9 @@ class RECV(opcua_device): RCU_PWR_ANT_VOUT_R = attribute_wrapper(comms_annotation=["RCU_PWR_ANT_VOUT_R" ],datatype=numpy.float64, dims=(3,32)) RCU_PWR_DIGITAL_on_R = attribute_wrapper(comms_annotation=["RCU_PWR_DIGITAL_on_R" ],datatype=numpy.bool_ , dims=(32,)) RCU_PWR_good_R = attribute_wrapper(comms_annotation=["RCU_PWR_good_R" ],datatype=numpy.bool_ , dims=(32,)) - RCU_temperature_R = attribute_wrapper(comms_annotation=["RCU_temperature_R" ],datatype=numpy.float64, dims=(32,)) - RCU_version_R = attribute_wrapper(comms_annotation=["RCU_version_R" ],datatype=numpy.str , dims=(32,)) + RCU_TEMP_R = attribute_wrapper(comms_annotation=["RCU_TEMP_R" ],datatype=numpy.float64, dims=(32,)) + RECVTR_I2C_error_R = attribute_wrapper(comms_annotation=["RECVTR_I2C_error_R" ],datatype=numpy.int64 , dims=(32,)) + RECVTR_monitor_rate_RW = attribute_wrapper(comms_annotation=["RECVTR_monitor_rate_RW" ],datatype=numpy.int64 , access=AttrWriteType.READ_WRITE) RECVTR_translator_busy_R = attribute_wrapper(comms_annotation=["RECVTR_translator_busy_R" ],datatype=numpy.bool_ ) # -------- @@ -191,7 +193,7 @@ class RECV(opcua_device): return rcu_status - def read_Ant_status_R(self): + def read_ANT_status_R(self): """ Returns a set of strings denoting the status of each antenna. An empty string means no problems were detected. A non-empty @@ -199,9 +201,9 @@ class RECV(opcua_device): This function can be used as input to modify the Ant_mask_RW. """ - ant_mask = self.Ant_mask_RW + ant_mask = self.ANT_mask_RW rcu_mask = self.RCU_mask_RW - adc_lock = self.RCU_ADC_lock_R + adc_lock = self.RCU_ADC_locked_R i2c_errors = self.RCU_I2C_STATUS_R nr_rcus = len(ant_mask) diff --git a/devices/devices/sdp/sdp.py b/devices/devices/sdp/sdp.py index 6cdfe9a2b2788f1b3466bbdb38a4ca5c83e9780f..d41d50af989c47ec0ee2fac3f0349bf8f00a3d53 100644 --- a/devices/devices/sdp/sdp.py +++ b/devices/devices/sdp/sdp.py @@ -99,73 +99,73 @@ class SDP(opcua_device): # Attributes # ---------- - FPGA_beamlet_output_enable_R = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_enable_R"], datatype=numpy.bool_, dims=(16,)) - FPGA_beamlet_output_enable_RW = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_beamlet_output_hdr_eth_destination_mac_R = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,)) - FPGA_beamlet_output_hdr_eth_destination_mac_RW = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_beamlet_output_hdr_ip_destination_address_R = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,)) - FPGA_beamlet_output_hdr_ip_destination_address_RW = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_beamlet_output_hdr_udp_destination_port_R = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,)) - FPGA_beamlet_output_hdr_udp_destination_port_RW = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_beamlet_output_scale_R = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_scale_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_beamlet_output_scale_RW = attribute_wrapper(comms_annotation=["2:FPGA_beamlet_output_scale_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_firmware_version_R = attribute_wrapper(comms_annotation=["2:FPGA_firmware_version_R"], datatype=numpy.str, dims=(16,)) - FPGA_global_node_index_R = attribute_wrapper(comms_annotation=["2:FPGA_global_node_index_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_hardware_version_R = attribute_wrapper(comms_annotation=["2:FPGA_hardware_version_R"], datatype=numpy.str, dims=(16,)) - FPGA_processing_enable_R = attribute_wrapper(comms_annotation=["2:FPGA_processing_enable_R"], datatype=numpy.bool_, dims=(16,)) - FPGA_processing_enable_RW = attribute_wrapper(comms_annotation=["2:FPGA_processing_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_scrap_R = attribute_wrapper(comms_annotation=["2:FPGA_scrap_R"], datatype=numpy.int32, dims=(8192,)) - FPGA_scrap_RW = attribute_wrapper(comms_annotation=["2:FPGA_scrap_RW"], datatype=numpy.int32, dims=(8192,), access=AttrWriteType.READ_WRITE) - FPGA_sdp_info_antenna_band_index_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_antenna_band_index_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_block_period_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_block_period_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_f_adc_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_f_adc_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_fsub_type_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_fsub_type_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_nyquist_sampling_zone_index_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_nyquist_sampling_zone_index_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_nyquist_sampling_zone_index_RW = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_nyquist_sampling_zone_index_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sdp_info_observation_id_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_observation_id_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_observation_id_RW = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_observation_id_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sdp_info_station_id_R = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_station_id_R"], datatype=numpy.uint32, dims=(16,)) - FPGA_sdp_info_station_id_RW = attribute_wrapper(comms_annotation=["2:FPGA_sdp_info_station_id_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_subband_weights_R = attribute_wrapper(comms_annotation=["2:FPGA_subband_weights_R"], datatype=numpy.uint32, dims=(12 * 512, 16)) - FPGA_subband_weights_RW = attribute_wrapper(comms_annotation=["2:FPGA_subband_weights_RW"], datatype=numpy.uint32, dims=(12 * 512, 16), access=AttrWriteType.READ_WRITE) - FPGA_temp_R = attribute_wrapper(comms_annotation=["2:FPGA_temp_R"], datatype=numpy.float_, dims=(16,)) - FPGA_weights_R = attribute_wrapper(comms_annotation=["2:FPGA_weights_R"], datatype=numpy.int16, dims=(12 * 488 * 2, 16)) - FPGA_weights_RW = attribute_wrapper(comms_annotation=["2:FPGA_weights_RW"], datatype=numpy.int16, dims=(12 * 488 * 2, 16), access=AttrWriteType.READ_WRITE) - FPGA_wg_amplitude_R = attribute_wrapper(comms_annotation=["2:FPGA_wg_amplitude_R"], datatype=numpy.float_, dims=(12, 16)) - FPGA_wg_amplitude_RW = attribute_wrapper(comms_annotation=["2:FPGA_wg_amplitude_RW"], datatype=numpy.float_, dims=(12, 16), access=AttrWriteType.READ_WRITE) - FPGA_wg_enable_R = attribute_wrapper(comms_annotation=["2:FPGA_wg_enable_R"], datatype=numpy.bool_, dims=(12, 16)) - FPGA_wg_enable_RW = attribute_wrapper(comms_annotation=["2:FPGA_wg_enable_RW"], datatype=numpy.bool_, dims=(12, 16), access=AttrWriteType.READ_WRITE) - FPGA_wg_frequency_R = attribute_wrapper(comms_annotation=["2:FPGA_wg_frequency_R"], datatype=numpy.float_, dims=(12, 16)) - FPGA_wg_frequency_RW = attribute_wrapper(comms_annotation=["2:FPGA_wg_frequency_RW"], datatype=numpy.float_, dims=(12, 16), access=AttrWriteType.READ_WRITE) - FPGA_wg_phase_R = attribute_wrapper(comms_annotation=["2:FPGA_wg_phase_R"], datatype=numpy.float_, dims=(12, 16)) - FPGA_wg_phase_RW = attribute_wrapper(comms_annotation=["2:FPGA_wg_phase_RW"], datatype=numpy.float_, dims=(12, 16), access=AttrWriteType.READ_WRITE) - TR_fpga_mask_R = attribute_wrapper(comms_annotation=["2:TR_fpga_mask_R"], datatype=numpy.bool_, dims=(16,)) - TR_fpga_mask_RW = attribute_wrapper(comms_annotation=["2:TR_fpga_mask_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - TR_fpga_communication_error_R = attribute_wrapper(comms_annotation=["2:TR_fpga_communication_error_R"], datatype=numpy.bool_, dims=(16,)) - TR_sdp_config_first_fpga_nr_R = attribute_wrapper(comms_annotation=["2:TR_sdp_config_first_fpga_nr_R"], datatype=numpy.uint32) - TR_sdp_config_nof_beamsets_R = attribute_wrapper(comms_annotation=["2:TR_sdp_config_nof_beamsets_R"], datatype=numpy.uint32) - TR_sdp_config_nof_fpgas_R = attribute_wrapper(comms_annotation=["2:TR_sdp_config_nof_fpgas_R"], datatype=numpy.uint32) - TR_software_version_R = attribute_wrapper(comms_annotation=["2:TR_software_version_R"], datatype=numpy.str) - TR_start_time_R = attribute_wrapper(comms_annotation=["2:TR_start_time_R"], datatype=numpy.int64) - TR_tod_R = attribute_wrapper(comms_annotation=["2:TR_tod_R"], datatype=numpy.int64, dims=(2,)) - TR_tod_pps_delta_R = attribute_wrapper(comms_annotation=["2:TR_tod_pps_delta_R"], datatype=numpy.double) + FPGA_beamlet_output_enable_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_enable_R"], datatype=numpy.bool_, dims=(16,)) + FPGA_beamlet_output_enable_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_beamlet_output_hdr_eth_destination_mac_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,)) + FPGA_beamlet_output_hdr_eth_destination_mac_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_beamlet_output_hdr_ip_destination_address_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,)) + FPGA_beamlet_output_hdr_ip_destination_address_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_beamlet_output_hdr_udp_destination_port_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,)) + FPGA_beamlet_output_hdr_udp_destination_port_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_beamlet_output_scale_R = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_scale_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_beamlet_output_scale_RW = attribute_wrapper(comms_annotation=["FPGA_beamlet_output_scale_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_firmware_version_R = attribute_wrapper(comms_annotation=["FPGA_firmware_version_R"], datatype=numpy.str, dims=(16,)) + FPGA_global_node_index_R = attribute_wrapper(comms_annotation=["FPGA_global_node_index_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_hardware_version_R = attribute_wrapper(comms_annotation=["FPGA_hardware_version_R"], datatype=numpy.str, dims=(16,)) + FPGA_processing_enable_R = attribute_wrapper(comms_annotation=["FPGA_processing_enable_R"], datatype=numpy.bool_, dims=(16,)) + FPGA_processing_enable_RW = attribute_wrapper(comms_annotation=["FPGA_processing_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_scrap_R = attribute_wrapper(comms_annotation=["FPGA_scrap_R"], datatype=numpy.int32, dims=(8192,)) + FPGA_scrap_RW = attribute_wrapper(comms_annotation=["FPGA_scrap_RW"], datatype=numpy.int32, dims=(8192,), access=AttrWriteType.READ_WRITE) + FPGA_sdp_info_antenna_band_index_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_antenna_band_index_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_block_period_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_block_period_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_f_adc_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_f_adc_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_fsub_type_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_fsub_type_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_nyquist_sampling_zone_index_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_nyquist_sampling_zone_index_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_nyquist_sampling_zone_index_RW = attribute_wrapper(comms_annotation=["FPGA_sdp_info_nyquist_sampling_zone_index_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sdp_info_observation_id_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_observation_id_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_observation_id_RW = attribute_wrapper(comms_annotation=["FPGA_sdp_info_observation_id_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sdp_info_station_id_R = attribute_wrapper(comms_annotation=["FPGA_sdp_info_station_id_R"], datatype=numpy.uint32, dims=(16,)) + FPGA_sdp_info_station_id_RW = attribute_wrapper(comms_annotation=["FPGA_sdp_info_station_id_RW"], datatype=numpy.uint32, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_subband_weights_R = attribute_wrapper(comms_annotation=["FPGA_subband_weights_R"], datatype=numpy.uint32, dims=(12 * 512, 16)) + FPGA_subband_weights_RW = attribute_wrapper(comms_annotation=["FPGA_subband_weights_RW"], datatype=numpy.uint32, dims=(12 * 512, 16), access=AttrWriteType.READ_WRITE) + FPGA_temp_R = attribute_wrapper(comms_annotation=["FPGA_temp_R"], datatype=numpy.float_, dims=(16,)) + FPGA_weights_R = attribute_wrapper(comms_annotation=["FPGA_weights_R"], datatype=numpy.int16, dims=(12 * 488 * 2, 16)) + FPGA_weights_RW = attribute_wrapper(comms_annotation=["FPGA_weights_RW"], datatype=numpy.int16, dims=(12 * 488 * 2, 16), access=AttrWriteType.READ_WRITE) + FPGA_wg_amplitude_R = attribute_wrapper(comms_annotation=["FPGA_wg_amplitude_R"], datatype=numpy.float_, dims=(12, 16)) + FPGA_wg_amplitude_RW = attribute_wrapper(comms_annotation=["FPGA_wg_amplitude_RW"], datatype=numpy.float_, dims=(12, 16), access=AttrWriteType.READ_WRITE) + FPGA_wg_enable_R = attribute_wrapper(comms_annotation=["FPGA_wg_enable_R"], datatype=numpy.bool_, dims=(12, 16)) + FPGA_wg_enable_RW = attribute_wrapper(comms_annotation=["FPGA_wg_enable_RW"], datatype=numpy.bool_, dims=(12, 16), access=AttrWriteType.READ_WRITE) + FPGA_wg_frequency_R = attribute_wrapper(comms_annotation=["FPGA_wg_frequency_R"], datatype=numpy.float_, dims=(12, 16)) + FPGA_wg_frequency_RW = attribute_wrapper(comms_annotation=["FPGA_wg_frequency_RW"], datatype=numpy.float_, dims=(12, 16), access=AttrWriteType.READ_WRITE) + FPGA_wg_phase_R = attribute_wrapper(comms_annotation=["FPGA_wg_phase_R"], datatype=numpy.float_, dims=(12, 16)) + FPGA_wg_phase_RW = attribute_wrapper(comms_annotation=["FPGA_wg_phase_RW"], datatype=numpy.float_, dims=(12, 16), access=AttrWriteType.READ_WRITE) + TR_fpga_mask_R = attribute_wrapper(comms_annotation=["TR_fpga_mask_R"], datatype=numpy.bool_, dims=(16,)) + TR_fpga_mask_RW = attribute_wrapper(comms_annotation=["TR_fpga_mask_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + TR_fpga_communication_error_R = attribute_wrapper(comms_annotation=["TR_fpga_communication_error_R"], datatype=numpy.bool_, dims=(16,)) + TR_sdp_config_first_fpga_nr_R = attribute_wrapper(comms_annotation=["TR_sdp_config_first_fpga_nr_R"], datatype=numpy.uint32) + TR_sdp_config_nof_beamsets_R = attribute_wrapper(comms_annotation=["TR_sdp_config_nof_beamsets_R"], datatype=numpy.uint32) + TR_sdp_config_nof_fpgas_R = attribute_wrapper(comms_annotation=["TR_sdp_config_nof_fpgas_R"], datatype=numpy.uint32) + TR_software_version_R = attribute_wrapper(comms_annotation=["TR_software_version_R"], datatype=numpy.str) + TR_start_time_R = attribute_wrapper(comms_annotation=["TR_start_time_R"], datatype=numpy.int64) + TR_tod_R = attribute_wrapper(comms_annotation=["TR_tod_R"], datatype=numpy.int64, dims=(2,)) + TR_tod_pps_delta_R = attribute_wrapper(comms_annotation=["TR_tod_pps_delta_R"], datatype=numpy.double) S_pn = 12 # Number of ADC signal inputs per Processing Node (PN) FPGA. N_pn = 16 # Number of FPGAs per antenna band that is controlled via the SC - SDP interface. # OPC-UA MP only points for AIT - FPGA_signal_input_mean_R = attribute_wrapper(comms_annotation=["2:FPGA_signal_input_mean_R"], datatype=numpy.double , dims=(S_pn, N_pn)) - FPGA_signal_input_rms_R = attribute_wrapper(comms_annotation=["2:FPGA_signal_input_rms_R"], datatype=numpy.double, dims=(S_pn, N_pn)) - - FPGA_jesd204b_csr_rbd_count_R = attribute_wrapper(comms_annotation=["2:FPGA_jesd204b_csr_rbd_count_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) - FPGA_jesd204b_csr_dev_syncn_R = attribute_wrapper(comms_annotation=["2:FPGA_jesd204b_csr_dev_syncn_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) - FPGA_jesd204b_rx_err0_R = attribute_wrapper(comms_annotation=["2:FPGA_jesd204b_rx_err0_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) - FPGA_jesd204b_rx_err1_R = attribute_wrapper(comms_annotation=["2:FPGA_jesd204b_rx_err1_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) - - FPGA_bsn_monitor_input_bsn_R = attribute_wrapper(comms_annotation=["2:FPGA_bsn_monitor_input_bsn_R"], datatype=numpy.int64, dims=(N_pn,)) - FPGA_bsn_monitor_input_nof_packets_R = attribute_wrapper(comms_annotation=["2:FPGA_bsn_monitor_input_nof_packets_R"], datatype=numpy.int32, dims=(N_pn,)) - FPGA_bsn_monitor_input_nof_valid_R = attribute_wrapper(comms_annotation=["2:FPGA_bsn_monitor_input_nof_valid_R"], datatype=numpy.int32, dims=(N_pn,)) - FPGA_bsn_monitor_input_nof_err_R = attribute_wrapper(comms_annotation=["2:FPGA_bsn_monitor_input_nof_err_R"], datatype=numpy.int32, dims=(N_pn,)) + FPGA_signal_input_mean_R = attribute_wrapper(comms_annotation=["FPGA_signal_input_mean_R"], datatype=numpy.double , dims=(S_pn, N_pn)) + FPGA_signal_input_rms_R = attribute_wrapper(comms_annotation=["FPGA_signal_input_rms_R"], datatype=numpy.double, dims=(S_pn, N_pn)) + + FPGA_jesd204b_csr_rbd_count_R = attribute_wrapper(comms_annotation=["FPGA_jesd204b_csr_rbd_count_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) + FPGA_jesd204b_csr_dev_syncn_R = attribute_wrapper(comms_annotation=["FPGA_jesd204b_csr_dev_syncn_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) + FPGA_jesd204b_rx_err0_R = attribute_wrapper(comms_annotation=["FPGA_jesd204b_rx_err0_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) + FPGA_jesd204b_rx_err1_R = attribute_wrapper(comms_annotation=["FPGA_jesd204b_rx_err1_R"], datatype=numpy.uint32, dims=(S_pn, N_pn)) + + FPGA_bsn_monitor_input_bsn_R = attribute_wrapper(comms_annotation=["FPGA_bsn_monitor_input_bsn_R"], datatype=numpy.int64, dims=(N_pn,)) + FPGA_bsn_monitor_input_nof_packets_R = attribute_wrapper(comms_annotation=["FPGA_bsn_monitor_input_nof_packets_R"], datatype=numpy.int32, dims=(N_pn,)) + FPGA_bsn_monitor_input_nof_valid_R = attribute_wrapper(comms_annotation=["FPGA_bsn_monitor_input_nof_valid_R"], datatype=numpy.int32, dims=(N_pn,)) + FPGA_bsn_monitor_input_nof_err_R = attribute_wrapper(comms_annotation=["FPGA_bsn_monitor_input_nof_err_R"], datatype=numpy.int32, dims=(N_pn,)) # -------- diff --git a/devices/devices/sdp/sst.py b/devices/devices/sdp/sst.py index 277714ab0b7ada6882a5ec1086690b3c29fb2382..d790170bb997f5e69044a2ef45754e04b9d62d1c 100644 --- a/devices/devices/sdp/sst.py +++ b/devices/devices/sdp/sst.py @@ -85,16 +85,16 @@ class SST(Statistics): # ---------- # FPGA control points for SSTs - FPGA_sst_offload_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sst_offload_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_enable_R"], datatype=numpy.bool_, dims=(16,)) - FPGA_sst_offload_hdr_eth_destination_mac_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sst_offload_hdr_eth_destination_mac_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,)) - FPGA_sst_offload_hdr_ip_destination_address_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sst_offload_hdr_ip_destination_address_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,)) - FPGA_sst_offload_hdr_udp_destination_port_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sst_offload_hdr_udp_destination_port_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,)) - FPGA_sst_offload_weighted_subbands_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_weighted_subbands_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_sst_offload_weighted_subbands_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_sst_offload_weighted_subbands_R"], datatype=numpy.bool_, dims=(16,)) + FPGA_sst_offload_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sst_offload_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_enable_R"], datatype=numpy.bool_, dims=(16,)) + FPGA_sst_offload_hdr_eth_destination_mac_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sst_offload_hdr_eth_destination_mac_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,)) + FPGA_sst_offload_hdr_ip_destination_address_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sst_offload_hdr_ip_destination_address_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,)) + FPGA_sst_offload_hdr_udp_destination_port_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sst_offload_hdr_udp_destination_port_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,)) + FPGA_sst_offload_weighted_subbands_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_weighted_subbands_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_sst_offload_weighted_subbands_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_sst_offload_weighted_subbands_R"], datatype=numpy.bool_, dims=(16,)) # number of packets with valid payloads nof_valid_payloads_R = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_valid_payloads"}, dims=(SSTCollector.MAX_FPGAS,), datatype=numpy.uint64) diff --git a/devices/devices/sdp/xst.py b/devices/devices/sdp/xst.py index c9883303b80425f0c142181994d43e477ec5431c..1740563c916115373d435896c075815a477795ea 100644 --- a/devices/devices/sdp/xst.py +++ b/devices/devices/sdp/xst.py @@ -101,20 +101,20 @@ class XST(Statistics): # ---------- # FPGA control points for XSTs - FPGA_xst_integration_interval_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_integration_interval_RW"], datatype=numpy.double, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_xst_integration_interval_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_integration_interval_R"], datatype=numpy.double, dims=(16,)) - FPGA_xst_offload_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_xst_offload_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_enable_R"], datatype=numpy.bool_, dims=(16,)) - FPGA_xst_offload_hdr_eth_destination_mac_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_xst_offload_hdr_eth_destination_mac_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,)) - FPGA_xst_offload_hdr_ip_destination_address_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_xst_offload_hdr_ip_destination_address_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,)) - FPGA_xst_offload_hdr_udp_destination_port_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_xst_offload_hdr_udp_destination_port_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_offload_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,)) - FPGA_xst_processing_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_processing_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) - FPGA_xst_processing_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_processing_enable_R"], datatype=numpy.bool_, dims=(16,)) - FPGA_xst_subband_select_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_subband_select_RW"], datatype=numpy.uint32, dims=(8,16), access=AttrWriteType.READ_WRITE) - FPGA_xst_subband_select_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["2:FPGA_xst_subband_select_R"], datatype=numpy.uint32, dims=(8,16)) + FPGA_xst_integration_interval_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_integration_interval_RW"], datatype=numpy.double, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_xst_integration_interval_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_integration_interval_R"], datatype=numpy.double, dims=(16,)) + FPGA_xst_offload_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_xst_offload_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_enable_R"], datatype=numpy.bool_, dims=(16,)) + FPGA_xst_offload_hdr_eth_destination_mac_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_hdr_eth_destination_mac_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_xst_offload_hdr_eth_destination_mac_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_hdr_eth_destination_mac_R"], datatype=numpy.str, dims=(16,)) + FPGA_xst_offload_hdr_ip_destination_address_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_hdr_ip_destination_address_RW"], datatype=numpy.str, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_xst_offload_hdr_ip_destination_address_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_hdr_ip_destination_address_R"], datatype=numpy.str, dims=(16,)) + FPGA_xst_offload_hdr_udp_destination_port_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_hdr_udp_destination_port_RW"], datatype=numpy.uint16, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_xst_offload_hdr_udp_destination_port_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_offload_hdr_udp_destination_port_R"], datatype=numpy.uint16, dims=(16,)) + FPGA_xst_processing_enable_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_processing_enable_RW"], datatype=numpy.bool_, dims=(16,), access=AttrWriteType.READ_WRITE) + FPGA_xst_processing_enable_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_processing_enable_R"], datatype=numpy.bool_, dims=(16,)) + FPGA_xst_subband_select_RW = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_subband_select_RW"], datatype=numpy.uint32, dims=(8,16), access=AttrWriteType.READ_WRITE) + FPGA_xst_subband_select_R = attribute_wrapper(comms_id=OPCUAConnection, comms_annotation=["FPGA_xst_subband_select_R"], datatype=numpy.uint32, dims=(8,16)) # number of packets with valid payloads nof_valid_payloads_R = attribute_wrapper(comms_id=StatisticsClient, comms_annotation={"type": "statistics", "parameter": "nof_valid_payloads"}, dims=(XSTCollector.MAX_FPGAS,), datatype=numpy.uint64) diff --git a/devices/devices/unb2.py b/devices/devices/unb2.py index bad1b1a324c9c838960d07cdfeb804b2789bbac6..0feb3e53d90e84a708aeaed9a511b86975801cfa 100644 --- a/devices/devices/unb2.py +++ b/devices/devices/unb2.py @@ -64,42 +64,44 @@ class UNB2(opcua_device): 'UNB2_mask_RW' ] + UNB2TR_I2C_bus_DDR4_error_R = attribute_wrapper(comms_annotation=["UNB2TR_I2C_bus_DDR4_error_R"],datatype=numpy.int64 , dims=(4,2)) + UNB2TR_I2C_bus_error_R = attribute_wrapper(comms_annotation=["UNB2TR_I2C_bus_error_R" ],datatype=numpy.int64 , dims=(2,)) + UNB2TR_I2C_bus_FPGA_PS_error_R = attribute_wrapper(comms_annotation=["UNB2TR_I2C_bus_FPGA_PS_error_R"],datatype=numpy.int64 , dims=(4,2)) + UNB2TR_I2C_bus_PS_error_R = attribute_wrapper(comms_annotation=["UNB2TR_I2C_bus_PS_error_R" ],datatype=numpy.int64 , dims=(2,)) + UNB2TR_I2C_bus_QSFP_error_R = attribute_wrapper(comms_annotation=["UNB2TR_I2C_bus_QSFP_error_R"],datatype=numpy.int64 , dims=(24,2)) + UNB2TR_monitor_rate_RW = attribute_wrapper(comms_annotation=["UNB2TR_monitor_rate_RW" ],datatype=numpy.int64 , access=AttrWriteType.READ_WRITE) UNB2TR_translator_busy_R = attribute_wrapper(comms_annotation=["UNB2TR_translator_busy_R" ],datatype=numpy.bool_ ) UNB2_DC_DC_48V_12V_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_DC_DC_48V_12V_IOUT_R" ],datatype=numpy.float64, dims=(2,)) UNB2_DC_DC_48V_12V_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_DC_DC_48V_12V_TEMP_R" ],datatype=numpy.float64, dims=(2,)) UNB2_DC_DC_48V_12V_VIN_R = attribute_wrapper(comms_annotation=["UNB2_DC_DC_48V_12V_VIN_R" ],datatype=numpy.float64, dims=(2,)) UNB2_DC_DC_48V_12V_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_DC_DC_48V_12V_VOUT_R" ],datatype=numpy.float64, dims=(2,)) - UNB2_EEPROM_Serial_Number_R = attribute_wrapper(comms_annotation=["UNB2_EEPROM_Serial_Number_R"],datatype=numpy.str , dims=(2,)) - UNB2_EEPROM_Unique_ID_R = attribute_wrapper(comms_annotation=["UNB2_EEPROM_Unique_ID_R" ],datatype=numpy.int64 , dims=(2,)) - UNB2_FPGA_DDR4_SLOT_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_DDR4_SLOT_TEMP_R"],datatype=numpy.float64, dims=(16,)) - UNB2_FPGA_POL_CORE_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_CORE_IOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_CORE_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_CORE_TEMP_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_CORE_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_CORE_VOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_ERAM_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_ERAM_IOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_ERAM_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_ERAM_TEMP_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_ERAM_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_ERAM_VOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_HGXB_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_HGXB_IOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_HGXB_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_HGXB_TEMP_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_HGXB_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_HGXB_VOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_PGM_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_PGM_IOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_PGM_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_PGM_TEMP_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_PGM_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_PGM_VOUT_R" ],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_RXGXB_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_RXGXB_IOUT_R"],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_RXGXB_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_RXGXB_TEMP_R"],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_RXGXB_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_RXGXB_VOUT_R"],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_TXGXB_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_TXGXB_IOUT_R"],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_TXGXB_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_TXGXB_TEMP_R"],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_POL_TXGXB_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_TXGXB_VOUT_R"],datatype=numpy.float64, dims=(8,)) - UNB2_FPGA_QSFP_CAGE_LOS_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_QSFP_CAGE_LOS_R" ],datatype=numpy.int64 , dims=(48,)) - UNB2_FPGA_QSFP_CAGE_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_QSFP_CAGE_TEMP_R"],datatype=numpy.float64, dims=(48,)) - UNB2_Front_Panel_LED_R = attribute_wrapper(comms_annotation=["UNB2_Front_Panel_LED_R" ],datatype=numpy.int64 , dims=(2,)) - UNB2_Front_Panel_LED_RW = attribute_wrapper(comms_annotation=["UNB2_Front_Panel_LED_RW" ],datatype=numpy.int64 , dims=(2,), access=AttrWriteType.READ_WRITE) - UNB2_I2C_bus_DDR4_error_R = attribute_wrapper(comms_annotation=["UNB2_I2C_bus_DDR4_error_R" ],datatype=numpy.int64 , dims=(8,)) - UNB2_I2C_bus_error_R = attribute_wrapper(comms_annotation=["UNB2_I2C_bus_error_R" ],datatype=numpy.int64 , dims=(2,)) - UNB2_I2C_bus_FPGA_PS_error_R = attribute_wrapper(comms_annotation=["UNB2_I2C_bus_FPGA_PS_error_R"],datatype=numpy.int64 , dims=(8,)) - UNB2_I2C_bus_PS_error_R = attribute_wrapper(comms_annotation=["UNB2_I2C_bus_PS_error_R" ],datatype=numpy.int64 , dims=(2,)) - UNB2_I2C_bus_QSFP_error_R = attribute_wrapper(comms_annotation=["UNB2_I2C_bus_QSFP_error_R" ],datatype=numpy.int64 , dims=(48,)) + UNB2_FPGA_DDR4_SLOT_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_DDR4_SLOT_TEMP_R"],datatype=numpy.float64, dims=(8,2)) + UNB2_FPGA_POL_CORE_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_CORE_IOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_CORE_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_CORE_TEMP_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_CORE_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_CORE_VOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_ERAM_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_ERAM_IOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_ERAM_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_ERAM_TEMP_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_ERAM_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_ERAM_VOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_HGXB_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_HGXB_IOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_HGXB_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_HGXB_TEMP_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_HGXB_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_HGXB_VOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_PGM_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_PGM_IOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_PGM_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_PGM_TEMP_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_PGM_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_PGM_VOUT_R" ],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_RXGXB_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_RXGXB_IOUT_R"],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_RXGXB_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_RXGXB_TEMP_R"],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_RXGXB_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_RXGXB_VOUT_R"],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_TXGXB_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_TXGXB_IOUT_R"],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_TXGXB_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_TXGXB_TEMP_R"],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_POL_TXGXB_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_POL_TXGXB_VOUT_R"],datatype=numpy.float64, dims=(4,2)) + UNB2_FPGA_QSFP_CAGE_LOS_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_QSFP_CAGE_LOS_R" ],datatype=numpy.int64 , dims=(24,2)) + UNB2_FPGA_QSFP_CAGE_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_FPGA_QSFP_CAGE_TEMP_R"],datatype=numpy.float64, dims=(24,2)) + UNB2_Front_Panel_LED_colour_R = attribute_wrapper(comms_annotation=["UNB2_Front_Panel_LED_colour_R"],datatype=numpy.int64 , dims=(2,)) + UNB2_Front_Panel_LED_colour_RW = attribute_wrapper(comms_annotation=["UNB2_Front_Panel_LED_colour_RW"],datatype=numpy.int64 , dims=(2,), access=AttrWriteType.READ_WRITE) UNB2_mask_RW = attribute_wrapper(comms_annotation=["UNB2_mask_RW" ],datatype=numpy.bool_ , dims=(2,), access=AttrWriteType.READ_WRITE) + UNB2_PCB_ID_R = attribute_wrapper(comms_annotation=["UNB2_PCB_ID_R" ],datatype=numpy.int64 , dims=(2,)) + UNB2_PCB_number_R = attribute_wrapper(comms_annotation=["UNB2_PCB_number_R" ],datatype=numpy.str , dims=(2,)) + UNB2_PCB_version_R = attribute_wrapper(comms_annotation=["UNB2_PCB_version_R" ],datatype=numpy.str , dims=(2,)) UNB2_POL_CLOCK_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_POL_CLOCK_IOUT_R" ],datatype=numpy.float64, dims=(2,)) UNB2_POL_CLOCK_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_POL_CLOCK_TEMP_R" ],datatype=numpy.float64, dims=(2,)) UNB2_POL_CLOCK_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_POL_CLOCK_VOUT_R" ],datatype=numpy.float64, dims=(2,)) @@ -115,8 +117,7 @@ class UNB2(opcua_device): UNB2_POL_SWITCH_PHY_IOUT_R = attribute_wrapper(comms_annotation=["UNB2_POL_SWITCH_PHY_IOUT_R"],datatype=numpy.float64, dims=(2,)) UNB2_POL_SWITCH_PHY_TEMP_R = attribute_wrapper(comms_annotation=["UNB2_POL_SWITCH_PHY_TEMP_R"],datatype=numpy.float64, dims=(2,)) UNB2_POL_SWITCH_PHY_VOUT_R = attribute_wrapper(comms_annotation=["UNB2_POL_SWITCH_PHY_VOUT_R"],datatype=numpy.float64, dims=(2,)) - UNB2_PWR_off_R = attribute_wrapper(comms_annotation=["UNB2_PWR_off_R" ],datatype=numpy.bool_ , dims=(2,)) - UNB2_PWR_off_RW = attribute_wrapper(comms_annotation=["UNB2_PWR_off_RW" ],datatype=numpy.bool_ , dims=(2,), access=AttrWriteType.READ_WRITE) + UNB2_PWR_on_R = attribute_wrapper(comms_annotation=["UNB2_PWR_on_R" ],datatype=numpy.bool_ , dims=(2,)) # -------- # overloaded functions diff --git a/devices/integration_test/devices/test_device_recv.py b/devices/integration_test/devices/test_device_recv.py index 138c08cd50be240fc48871caf2142774ebe48d5e..72199e292d9a8ce5ab90c69d764d03a342bb41c9 100644 --- a/devices/integration_test/devices/test_device_recv.py +++ b/devices/integration_test/devices/test_device_recv.py @@ -40,7 +40,7 @@ class TestDeviceRECV(base.IntegrationTestCase): d = TestDeviceProxy("LTS/RECV/1") - d.initialise() + d.Initialise() self.assertEqual(DevState.STANDBY, d.state()) @@ -49,7 +49,7 @@ class TestDeviceRECV(base.IntegrationTestCase): d = TestDeviceProxy("LTS/RECV/1") - d.initialise() + d.Initialise() d.on() diff --git a/devices/integration_test/devices/test_device_sdp.py b/devices/integration_test/devices/test_device_sdp.py index 65e96aef95e66ca384f7641d77b622ceb98df9cc..534d3e1039aa666b48f1c6df467c9356d0c2c702 100644 --- a/devices/integration_test/devices/test_device_sdp.py +++ b/devices/integration_test/devices/test_device_sdp.py @@ -36,12 +36,19 @@ class TestDeviceSDP(base.IntegrationTestCase): self.assertEqual(DevState.OFF, d.state()) + def test_device_sdp_ping(self): + """Test if we can successfully ping the device server""" + + d = DeviceProxy("LTS/SDP/1") + + self.assertGreater(d.ping(), 0) + def test_device_sdp_initialize(self): """Test if we can transition to standby""" d = TestDeviceProxy("LTS/SDP/1") - d.initialise() + d.Initialise() self.assertEqual(DevState.STANDBY, d.state()) @@ -50,7 +57,7 @@ class TestDeviceSDP(base.IntegrationTestCase): d = TestDeviceProxy("LTS/SDP/1") - d.initialise() + d.Initialise() d.on() diff --git a/devices/integration_test/devices/test_tango_database.py b/devices/integration_test/devices/test_tango_database.py new file mode 100644 index 0000000000000000000000000000000000000000..0ae65d5c51a98898e4016bbb231baa18b025dba9 --- /dev/null +++ b/devices/integration_test/devices/test_tango_database.py @@ -0,0 +1,34 @@ +# -*- 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. + +import time + +from tango import Database +from tango._tango import DevState + +from integration_test import base + + +class TestTangoDatabase(base.IntegrationTestCase): + + def setUp(self): + """Intentionally recreate the device object in each test""" + super(TestTangoDatabase, self).setUp() + + def test_database_servers(self): + """Connect to the database and find at least 3 servers + + One for SDP, RECV and the databaseds itself. + """ + + d = Database() + + # Ensure this value is close to actual amount of servers defined by + # integration_ConfigDb.json + self.assertGreater(len(d.get_server_list()), 16, msg=f"Servers: {d.get_server_list()}") diff --git a/docker-compose/Makefile b/docker-compose/Makefile index 649e63518d5f1276a2f1fb696d90a2b79fef0f24..d85ff1df88d91db097bdd22b060cfc03b681a04f 100644 --- a/docker-compose/Makefile +++ b/docker-compose/Makefile @@ -13,7 +13,8 @@ ATTACH_COMPOSE_FILE_ARGS := $(foreach yml,$(filter-out tango.yml,$(COMPOSE_FILES # But we allow to overwrite it. NETWORK_MODE ?= tangonet -# Host name through which others can reach our control interfaces +# Host name through which others can reach our control interfaces. +# Needs to be resolvable from the containers and clients. ifneq (,$(wildcard /run/WSL)) # Microsoft Windows Subsystem for Linux HOSTNAME ?= host.docker.internal @@ -21,6 +22,10 @@ else HOSTNAME ?= $(shell hostname -f) endif +# Host name to which to send our container logs. Needs to be resolvable from +# the host. +LOG_HOSTNAME ?= localhost + # If the first make argument is "start" or "stop"... ifeq (start,$(firstword $(MAKECMDGOALS))) SERVICE_TARGET = true @@ -113,6 +118,7 @@ DOCKER_COMPOSE_ARGS := DISPLAY=$(DISPLAY) \ TANGO_HOST=$(TANGO_HOST) \ MYSQL_HOST=$(MYSQL_HOST) \ HOSTNAME=$(HOSTNAME) \ + LOG_HOSTNAME=$(LOG_HOSTNAME) \ NETWORK_MODE=$(NETWORK_MODE) \ XAUTHORITY_MOUNT=$(XAUTHORITY_MOUNT) \ CONTAINER_NAME_PREFIX=$(CONTAINER_NAME_PREFIX) \ @@ -130,7 +136,7 @@ pull: ## pull the images from the Docker hub build: ## rebuild images # docker-compose does not support build dependencies, so manage those here $(DOCKER_COMPOSE_ARGS) docker-compose -f lofar-device-base.yml -f networks.yml build --progress=plain - $(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) build --progress=plain $(SERVICE) + $(DOCKER_COMPOSE_ARGS) docker-compose $(COMPOSE_FILE_ARGS) build --parallel --progress=plain $(SERVICE) build-nocache: ## rebuild images from scratch # docker-compose does not support build dependencies, so manage those here diff --git a/docker-compose/archiver.yml b/docker-compose/archiver.yml index 84dded354d22c97eeccd51ea97d8ff41b909f01e..1a56516c707ba965486432e753e45e24c14cbdc0 100644 --- a/docker-compose/archiver.yml +++ b/docker-compose/archiver.yml @@ -3,7 +3,7 @@ version: '2' services: archiver-maria-db: image: ${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/mariadb_hdbpp:2021-05-28 - container_name: archiver-maria-db + container_name: ${CONTAINER_NAME_PREFIX}archiver-maria-db networks: - control ports: @@ -17,13 +17,19 @@ services: - MYSQL_USER=tango - MYSQL_PASSWORD=tango - TANGO_HOST=${TANGO_HOST} + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped hdbpp-es: image: ${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/tango-archiver:2021-05-28 networks: - control - container_name: hdbpp-es + container_name: ${CONTAINER_NAME_PREFIX}hdbpp-es depends_on: - databaseds - dsconfig @@ -36,13 +42,19 @@ services: wait-for-it.sh archiver-maria-db:3306 --timeout=30 --strict -- wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- hdbppes-srv 01" + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped hdbpp-cm: image: ${LOCAL_DOCKER_REGISTRY_HOST}/${LOCAL_DOCKER_REGISTRY_USER}/tango-archiver:${TANGO_ARCHIVER_VERSION} networks: - control - container_name: hdbpp-cm + container_name: ${CONTAINER_NAME_PREFIX}hdbpp-cm depends_on: - databaseds - dsconfig @@ -55,10 +67,16 @@ services: wait-for-it.sh archiver-maria-db:3306 --timeout=30 --strict -- wait-for-it.sh ${TANGO_HOST} --timeout=30 --strict -- hdbppcm-srv 01" + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" dsconfig: image: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}-tango-dsconfig:${TANGO_DSCONFIG_VERSION} - container_name: dsconfig + container_name: ${CONTAINER_NAME_PREFIX}dsconfig networks: - control depends_on: @@ -73,5 +91,11 @@ services: - ..:/opt/lofar/tango:rw - ${HOME}:/hosthome - ../docker/tango/tango-archiver:/tango-archiver + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped diff --git a/docker-compose/device-apsct.yml b/docker-compose/device-apsct.yml index f17919a227a12b9846ba7a272254faaaee4d496a..36a21fb6c81bce72c0f708e5aca924eb0de9e14f 100644 --- a/docker-compose/device-apsct.yml +++ b/docker-compose/device-apsct.yml @@ -26,6 +26,8 @@ services: - control ports: - "5709:5709" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-apspu.yml b/docker-compose/device-apspu.yml index 30da5a6c2aba5daef2452f906693c41e7fece330..f1ea50c89d5194c6829fcf29446090edae33e686 100644 --- a/docker-compose/device-apspu.yml +++ b/docker-compose/device-apspu.yml @@ -26,6 +26,8 @@ services: - control ports: - "5710:5710" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-boot.yml b/docker-compose/device-boot.yml index 58a9aa7df81eab368464f4ca69ddab54129b7ace..d51f91614a483feb8c5956d3d35942843c4be3ce 100644 --- a/docker-compose/device-boot.yml +++ b/docker-compose/device-boot.yml @@ -25,6 +25,8 @@ services: - control ports: - "5708:5708" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-docker.yml b/docker-compose/device-docker.yml index d9e1e1e35233177ab271db395773538ed8c74ffa..49144b7bb61ed1ca30c83b26e0c5443761411c54 100644 --- a/docker-compose/device-docker.yml +++ b/docker-compose/device-docker.yml @@ -26,6 +26,8 @@ services: - control ports: - "5705:5705" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw - /var/run/docker.sock:/var/run/docker.sock:rw # we want to control our sibling containers, NOT do docker-in-docker (dind) diff --git a/docker-compose/device-observation_control.yml b/docker-compose/device-observation_control.yml index 827a558a10167d29f3e0bd3402f3f84debcd3c23..b057df808d9f7c0fc3a2e5fb8bb9a3f0504ff388 100644 --- a/docker-compose/device-observation_control.yml +++ b/docker-compose/device-observation_control.yml @@ -25,6 +25,8 @@ services: - control ports: - "5703:5703" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-recv.yml b/docker-compose/device-recv.yml index f3bc3eea12b51b44cacbeb790d0666ced24ae169..0b860949bb44cd8301986f732df99a8a3d58d8aa 100644 --- a/docker-compose/device-recv.yml +++ b/docker-compose/device-recv.yml @@ -26,6 +26,8 @@ services: - control ports: - "5707:5707" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-sdp.yml b/docker-compose/device-sdp.yml index 8fefa3f355eda485ea757f0859924e317b9245ee..c1685235467277ac60f781918aa98fde6394877d 100644 --- a/docker-compose/device-sdp.yml +++ b/docker-compose/device-sdp.yml @@ -26,6 +26,8 @@ services: - control ports: - "5701:5701" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-sst.yml b/docker-compose/device-sst.yml index 7d922a61badf6575d15c6f0a0489a6fac3683367..68164379ed1e7d3fa985cb9f3c5f620c09b71d50 100644 --- a/docker-compose/device-sst.yml +++ b/docker-compose/device-sst.yml @@ -29,6 +29,8 @@ services: - "5001:5001/udp" # port to receive SST UDP packets on - "5101:5101/tcp" # port to emit SST TCP packets on - "5702:5702" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-unb2.yml b/docker-compose/device-unb2.yml index 6844ee2b6994c11fb53469535925284be42410c0..bd9b6496332994171959967ff358115ac91e5ca7 100644 --- a/docker-compose/device-unb2.yml +++ b/docker-compose/device-unb2.yml @@ -26,6 +26,8 @@ services: - control ports: - "5704:5704" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/device-xst.yml b/docker-compose/device-xst.yml index c634e5d83fc7b28f2b8438ae59dffb7157a03f54..619b532e694f502b93638c2427bb7d9464138e82 100644 --- a/docker-compose/device-xst.yml +++ b/docker-compose/device-xst.yml @@ -29,6 +29,8 @@ services: - "5002:5002/udp" # port to receive XST UDP packets on - "5102:5102/tcp" # port to emit XST TCP packets on - "5706:5706" # unique port for this DS + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/elk.yml b/docker-compose/elk.yml index bf6e22e3de6ea82571acba0ac8e7c69f3eeb2941..67f13baee061a74ebd08320f1e9f2f9f3e72f646 100644 --- a/docker-compose/elk.yml +++ b/docker-compose/elk.yml @@ -34,7 +34,8 @@ services: - "5601:5601" # kibana - "9200:9200" # elasticsearch - "5044:5044" # logstash beats input - - "1514:1514" # logstash syslog input + - "1514:1514/tcp" # logstash syslog input + - "1514:1514/udp" # logstash syslog input - "5959:5959" # logstash tcp json input depends_on: - elk-configure-host diff --git a/docker-compose/elk/logstash/conf.d/20-parse-grafana.conf b/docker-compose/elk/logstash/conf.d/20-parse-grafana.conf new file mode 100644 index 0000000000000000000000000000000000000000..37db44fda67109d7ef8a6beac1193004968a2349 --- /dev/null +++ b/docker-compose/elk/logstash/conf.d/20-parse-grafana.conf @@ -0,0 +1,16 @@ +filter { + if [program] == "grafana" { + kv { } + mutate { + rename => { + "t" => "timestamp" + "lvl" => "level" + "msg" => "message" + } + uppercase => [ "level" ] + } + date { + match => [ "timestamp", "ISO8601" ] + } + } +} diff --git a/docker-compose/elk/logstash/conf.d/21-parse-prometheus.conf b/docker-compose/elk/logstash/conf.d/21-parse-prometheus.conf new file mode 100644 index 0000000000000000000000000000000000000000..b8323625f329af02f9ff33556e408b94ecf7e0b6 --- /dev/null +++ b/docker-compose/elk/logstash/conf.d/21-parse-prometheus.conf @@ -0,0 +1,15 @@ +filter { + if [program] == "prometheus" { + kv { } + mutate { + rename => { + "ts" => "timestamp" + "msg" => "message" + } + uppercase => [ "level" ] + } + date { + match => [ "timestamp", "ISO8601" ] + } + } +} diff --git a/docker-compose/elk/logstash/conf.d/22-parse-tango-rest.conf b/docker-compose/elk/logstash/conf.d/22-parse-tango-rest.conf new file mode 100644 index 0000000000000000000000000000000000000000..5df0cd92bd32625a1eb91220bf4e7a9827799523 --- /dev/null +++ b/docker-compose/elk/logstash/conf.d/22-parse-tango-rest.conf @@ -0,0 +1,14 @@ +filter { + if [program] == "tango-rest" { + grok { + match => { + "message" => "%{TIMESTAMP_ISO8601:timestamp} %{WORD:level} %{GREEDYDATA:message}" + } + "overwrite" => [ "timestamp", "level", "message" ] + } + date { + match => [ "timestamp", "YYYY-MM-dd HH:mm:ss,SSS" ] + timezone => "UTC" + } + } +} diff --git a/docker-compose/elk/logstash/conf.d/23-parse-maria-db.conf b/docker-compose/elk/logstash/conf.d/23-parse-maria-db.conf new file mode 100644 index 0000000000000000000000000000000000000000..0a23fddd078e5e967bc5f791e020faaa20ed632a --- /dev/null +++ b/docker-compose/elk/logstash/conf.d/23-parse-maria-db.conf @@ -0,0 +1,32 @@ +filter { + # mark all our mariadb instances + grok { + match => { + "program" => [ "archiver-maria-db", "tangodb" ] + } + add_tag => [ "mariadb" ] + } + + # parse mariadb output + if "mariadb" in [tags] { + grok { + match => { + "message" => [ + "%{TIMESTAMP_ISO8601:timestamp} .%{WORD:level}. %{GREEDYDATA:message}", + "%{TIMESTAMP_ISO8601:timestamp} 0 .%{WORD:level}. %{GREEDYDATA:message}" + ] + } + "overwrite" => [ "timestamp", "level", "message" ] + } + mutate { + gsub => [ + "level", "Note", "Info" + ] + uppercase => [ "level" ] + } + date { + match => [ "timestamp", "YYYY-MM-dd HH:mm:ssZZ", "YYYY-MM-dd HH:mm:ss", "YYYY-MM-dd H:mm:ss" ] + timezone => "UTC" + } + } +} diff --git a/docker-compose/grafana.yml b/docker-compose/grafana.yml index b9060c70a53ecfb4d4027ebe1e78d9fe658050f6..29c93c52c4dc05849aad10fabac12712c12dd4d7 100644 --- a/docker-compose/grafana.yml +++ b/docker-compose/grafana.yml @@ -23,4 +23,10 @@ services: # - grafana-configs:/etc/grafana ports: - "3000:3000" + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped diff --git a/docker-compose/grafana/Dockerfile b/docker-compose/grafana/Dockerfile index bc766bcd3b0d71f346fd70e34fa27dd91fc27b04..e51cce5eeaa0310c1ecd698d8d797e3163ce4457 100644 --- a/docker-compose/grafana/Dockerfile +++ b/docker-compose/grafana/Dockerfile @@ -1,5 +1,9 @@ FROM grafana/grafana +# Install some plugins +RUN grafana-cli plugins install briangann-datatable-panel +RUN grafana-cli plugins install ae3e-plotly-panel + COPY grafana.ini /etc/grafana/ # Add default configuration through provisioning (see https://grafana.com/docs/grafana/latest/administration/provisioning) diff --git a/docker-compose/grafana/dashboards/home.json b/docker-compose/grafana/dashboards/home.json index 6d4641a656c20b40ceaa8a18d2b02da47b0b55ba..f1b7a626e2ca470f513d22cadf240345cacf2f25 100644 --- a/docker-compose/grafana/dashboards/home.json +++ b/docker-compose/grafana/dashboards/home.json @@ -22,7 +22,7 @@ "fiscalYearStartMonth": 0, "gnetId": null, "graphTooltip": 0, - "id": 6, + "id": 5, "links": [], "liveNow": false, "panels": [ @@ -484,6 +484,196 @@ ], "type": "table" }, + { + "datasource": "ELK logs", + "description": "List of the errors in the selected timespan", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "displayMode": "auto", + "filterable": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "@timestamp" + }, + "properties": [ + { + "id": "custom.width", + "value": 149 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "level" + }, + "properties": [ + { + "id": "custom.width", + "value": 62 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "program" + }, + "properties": [ + { + "id": "custom.width", + "value": 287 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "extra.logger_name" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "extra.lofar_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 196 + } + ] + } + ] + }, + "gridPos": { + "h": 5, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 56, + "options": { + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "alias": "", + "bucketAggs": [], + "metrics": [ + { + "hide": false, + "id": "1", + "settings": { + "limit": "500" + }, + "type": "logs" + } + ], + "query": "level:(ERROR or CRIT or FATAL)", + "refId": "A", + "timeField": "@timestamp" + } + ], + "title": "Error Log", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "@version": true, + "_id": true, + "_index": true, + "_source": true, + "_type": true, + "extra.func_name": true, + "extra.interpreter": true, + "extra.interpreter_version": true, + "extra.line": true, + "extra.logger_name": true, + "extra.logstash_async_version": true, + "extra.path": true, + "extra.process_name": true, + "extra.software_version": true, + "extra.tango_device": true, + "extra.thread_name": true, + "highlight": true, + "host": true, + "logsource": true, + "pid": true, + "port": true, + "sort": true, + "tags": true, + "type": true + }, + "indexByName": { + "@timestamp": 0, + "@version": 5, + "_id": 6, + "_index": 7, + "_source": 8, + "_type": 9, + "extra.func_name": 10, + "extra.interpreter": 11, + "extra.interpreter_version": 12, + "extra.line": 13, + "extra.lofar_id": 4, + "extra.logger_name": 14, + "extra.logstash_async_version": 15, + "extra.path": 16, + "extra.process_name": 17, + "extra.software_version": 18, + "extra.tango_device": 19, + "extra.thread_name": 20, + "highlight": 21, + "host": 2, + "level": 1, + "logsource": 22, + "message": 23, + "pid": 24, + "port": 25, + "program": 3, + "sort": 26, + "tags": 27, + "type": 28 + }, + "renameByName": {} + } + } + ], + "type": "table" + }, { "collapsed": false, "datasource": null, @@ -491,7 +681,301 @@ "h": 1, "w": 24, "x": 0, - "y": 10 + "y": 15 + }, + "id": 49, + "panels": [], + "title": "APSCT & APSPU", + "type": "row" + }, + { + "datasource": "Prometheus", + "description": "State of APSCT", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 21, + "x": 0, + "y": 16 + }, + "id": 24, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "name" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "1-device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PWR_on_R\"}", + "interval": "", + "legendFormat": "Power", + "refId": "A" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/apsct/1\",name=\"APSCTTR_I2C_error_R\"}", + "hide": false, + "interval": "", + "legendFormat": "I2C", + "refId": "B" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PLL_200MHz_error_R\"}", + "hide": false, + "interval": "", + "legendFormat": "PLL", + "refId": "C" + }, + { + "exemplar": true, + "expr": "1-device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PLL_200MHz_locked_R\"}", + "hide": false, + "interval": "", + "legendFormat": "PLL Lock", + "refId": "D" + }, + { + "exemplar": true, + "expr": "1-device_attribute{device=\"lts/apsct/1\",name=\"APSCT_INPUT_10MHz_good_R\"}", + "hide": false, + "interval": "", + "legendFormat": "10MHz", + "refId": "E" + }, + { + "exemplar": true, + "expr": "1-device_attribute{device=\"lts/apsct/1\",name=\"APSCT_INPUT_PPS_good_R\"}", + "hide": false, + "interval": "", + "legendFormat": "PPS", + "refId": "F" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PPS_ignore_R\"}", + "hide": false, + "interval": "", + "legendFormat": "PPS used", + "refId": "G" + } + ], + "title": "APS Clock State", + "type": "stat" + }, + { + "datasource": "Prometheus", + "description": "State of APSPU", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 16 + }, + "id": 50, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "name" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/apspu/1\",name=\"APSPUTR_I2C_error_R\"}", + "hide": false, + "interval": "", + "legendFormat": "I2C", + "refId": "B" + } + ], + "title": "APS Power Unit State", + "type": "stat" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 53, + "panels": [], + "title": "UNB2", + "type": "row" + }, + { + "datasource": "Prometheus", + "description": "State of Unboard 2 I2C Bus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "transparent", + "value": null + }, + { + "color": "green", + "value": 1 + }, + { + "color": "red", + "value": 2 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 54, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "name" + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "exemplar": true, + "expr": "(1 + (device_attribute{device=\"lts/unb2/1\",name=\"UNB2TR_I2C_bus_error_R\"} != bool 0)) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "hide": false, + "interval": "", + "legendFormat": "I2C {{x}}", + "refId": "A" + }, + { + "exemplar": true, + "expr": "(1 + device_attribute{device=\"lts/unb2/1\",name=\"UNB2TR_I2C_bus_PS_error_R\"}) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "hide": false, + "interval": "", + "legendFormat": "PS {{x}}", + "refId": "B" + }, + { + "exemplar": true, + "expr": "(1 + sum by (x) (device_attribute{device=\"lts/unb2/1\",name=\"UNB2TR_I2C_bus_FPGA_PS_error_R\"})) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "hide": false, + "interval": "", + "legendFormat": "FPGA PS {{x}}", + "refId": "C" + }, + { + "exemplar": true, + "expr": "(1 + sum by (x) (device_attribute{device=\"lts/unb2/1\",name=\"UNB2TR_I2C_bus_DDR4_error_R\"})) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "hide": false, + "interval": "", + "legendFormat": "DDR {{x}}", + "refId": "D" + }, + { + "exemplar": true, + "expr": "(1 + sum by (x) (device_attribute{device=\"lts/unb2/1\",name=\"UNB2TR_I2C_bus_QSFP_error_R\"})) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "hide": false, + "interval": "", + "legendFormat": "QSFP {{x}}", + "refId": "E" + } + ], + "title": "UNB2 I2C State", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 23 }, "id": 17, "panels": [], @@ -530,12 +1014,12 @@ "h": 8, "w": 6, "x": 0, - "y": 11 + "y": 24 }, "id": 21, "options": { "colorMode": "background", - "graphMode": "area", + "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { @@ -552,13 +1036,14 @@ "targets": [ { "exemplar": true, - "expr": "sum by (x)(1 + (device_attribute{device=\"lts/recv/1\",name=\"RCU_ADC_lock_R\"} == bool 129)) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"} - 3", + "expr": "sum by (x)(1 + (device_attribute{device=\"lts/recv/1\",name=\"RCU_ADC_locked_R\"})) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"} - 3", + "instant": false, "interval": "", "legendFormat": "{{y}}", "refId": "A" } ], - "title": "RCU ADC lock", + "title": "RCU Clock Lock", "type": "stat" }, { @@ -593,12 +1078,12 @@ "h": 8, "w": 6, "x": 6, - "y": 11 + "y": 24 }, "id": 25, "options": { "colorMode": "background", - "graphMode": "area", + "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { @@ -615,17 +1100,20 @@ "targets": [ { "exemplar": true, - "expr": "(2 - device_attribute{device=\"lts/recv/1\",name=\"RCU_I2C_STATUS_R\"}) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "expr": "(1 + (device_attribute{device=\"lts/recv/1\",name=\"RECVTR_I2C_error_R\"} == bool 0)) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", + "hide": false, + "instant": false, "interval": "", "legendFormat": "{{y}}", "refId": "A" } ], - "title": "RCU I2C status", + "title": "RCU I2C State", "type": "stat" }, { "datasource": "Prometheus", + "description": "", "fieldConfig": { "defaults": { "color": { @@ -636,12 +1124,16 @@ "mode": "absolute", "steps": [ { - "color": "green", + "color": "transparent", "value": null }, { "color": "red", "value": 1 + }, + { + "color": "green", + "value": 2 } ] } @@ -649,12 +1141,12 @@ "overrides": [] }, "gridPos": { - "h": 5, - "w": 3, + "h": 8, + "w": 6, "x": 12, - "y": 11 + "y": 24 }, - "id": 24, + "id": 51, "options": { "colorMode": "background", "graphMode": "none", @@ -674,37 +1166,15 @@ "targets": [ { "exemplar": true, - "expr": "1-device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PWR_on_R\"}", - "interval": "", - "legendFormat": "Power", - "refId": "A" - }, - { - "exemplar": true, - "expr": "device_attribute{device=\"lts/apsct/1\",name=\"APSCT_I2C_error_R\"}", - "hide": false, - "interval": "", - "legendFormat": "I2C", - "refId": "B" - }, - { - "exemplar": true, - "expr": "device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PLL_200MHz_error_R\"}", - "hide": false, - "interval": "", - "legendFormat": "PLL", - "refId": "C" - }, - { - "exemplar": true, - "expr": "1-device_attribute{device=\"lts/apsct/1\",name=\"APSCT_PLL_200MHz_locked_R\"}", + "expr": "(1 + device_attribute{device=\"lts/recv/1\",name=\"RCU_PWR_good_R\"}) * on(x) device_attribute{device=\"lts/recv/1\",name=\"RCU_mask_RW\"}", "hide": false, + "instant": false, "interval": "", - "legendFormat": "PLL Lock", - "refId": "D" + "legendFormat": "{{y}}", + "refId": "A" } ], - "title": "Clock", + "title": "RCU Power good", "type": "stat" }, { @@ -714,7 +1184,7 @@ "h": 1, "w": 24, "x": 0, - "y": 19 + "y": 32 }, "id": 19, "panels": [], @@ -754,7 +1224,7 @@ "h": 8, "w": 5, "x": 0, - "y": 20 + "y": 33 }, "id": 11, "options": { @@ -822,7 +1292,7 @@ "h": 8, "w": 5, "x": 5, - "y": 20 + "y": 33 }, "id": 9, "options": { @@ -896,7 +1366,7 @@ "h": 4, "w": 3, "x": 10, - "y": 20 + "y": 33 }, "id": 12, "options": { @@ -938,7 +1408,7 @@ "h": 1, "w": 24, "x": 0, - "y": 28 + "y": 41 }, "id": 27, "panels": [], @@ -978,7 +1448,7 @@ "h": 8, "w": 5, "x": 0, - "y": 29 + "y": 42 }, "id": 28, "options": { @@ -1076,7 +1546,7 @@ "h": 8, "w": 5, "x": 5, - "y": 29 + "y": 42 }, "id": 29, "options": { @@ -1185,7 +1655,7 @@ "h": 8, "w": 5, "x": 10, - "y": 29 + "y": 42 }, "id": 30, "options": { @@ -1278,7 +1748,7 @@ "h": 8, "w": 5, "x": 15, - "y": 29 + "y": 42 }, "id": 33, "options": { @@ -1373,7 +1843,7 @@ "h": 8, "w": 3, "x": 20, - "y": 29 + "y": 42 }, "id": 34, "options": { @@ -1410,7 +1880,7 @@ "h": 1, "w": 24, "x": 0, - "y": 37 + "y": 50 }, "id": 36, "panels": [], @@ -1447,10 +1917,10 @@ "overrides": [] }, "gridPos": { - "h": 8, + "h": 4, "w": 5, "x": 0, - "y": 38 + "y": 51 }, "id": 37, "options": { @@ -1548,7 +2018,7 @@ "h": 8, "w": 5, "x": 5, - "y": 38 + "y": 51 }, "id": 38, "options": { @@ -1657,7 +2127,7 @@ "h": 8, "w": 5, "x": 10, - "y": 38 + "y": 51 }, "id": 39, "options": { @@ -1750,7 +2220,7 @@ "h": 8, "w": 5, "x": 15, - "y": 38 + "y": 51 }, "id": 40, "options": { @@ -1845,7 +2315,7 @@ "h": 8, "w": 3, "x": 20, - "y": 38 + "y": 51 }, "id": 41, "options": { @@ -1905,10 +2375,10 @@ "overrides": [] }, "gridPos": { - "h": 8, + "h": 4, "w": 5, "x": 0, - "y": 46 + "y": 55 }, "id": 45, "options": { @@ -1959,5 +2429,5 @@ "timezone": "", "title": "Home", "uid": "nC8N_kO7k", - "version": 5 + "version": 6 } diff --git a/docker-compose/grafana/dashboards/sensors.json b/docker-compose/grafana/dashboards/sensors.json index 95e39f60d024ea355119a24d72cbd9bdd9c178fe..43c85da09acc89c8ef487d60e8f46a5bd8605d3c 100644 --- a/docker-compose/grafana/dashboards/sensors.json +++ b/docker-compose/grafana/dashboards/sensors.json @@ -22,7 +22,6 @@ "fiscalYearStartMonth": 0, "gnetId": null, "graphTooltip": 0, - "id": 4, "links": [], "liveNow": false, "panels": [ @@ -75,7 +74,6 @@ } }, "mappings": [], - "min": 0, "thresholds": { "mode": "absolute", "steps": [ @@ -99,7 +97,7 @@ "x": 0, "y": 1 }, - "id": 2, + "id": 6, "options": { "legend": { "calcs": [], @@ -114,7 +112,7 @@ "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/recv/1\",name=\"RCU_temperature_R\"} - 273.15", + "expr": "device_attribute{device=\"lts/sdp/1\",name=\"FPGA_temp_R\"} != 0", "format": "time_series", "hide": false, "instant": false, @@ -123,13 +121,13 @@ "refId": "A" } ], - "title": "RCU temperatures", + "title": "FPGA Temperatures", "transformations": [], "type": "timeseries" }, { "datasource": "Prometheus", - "description": "Temperature sensors of each node on each board", + "description": "", "fieldConfig": { "defaults": { "color": { @@ -202,14 +200,14 @@ "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_CORE_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_CORE_TEMP_R\"} ", "interval": "", "legendFormat": "Core board {{x}} node {{y}}", "refId": "A" }, { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_ERAM_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_ERAM_TEMP_R\"} ", "hide": false, "interval": "", "legendFormat": "ERAM board {{x}} node {{y}}", @@ -217,7 +215,7 @@ }, { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_RXGXB_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_RXGXB_TEMP_R\"} ", "hide": false, "interval": "", "legendFormat": "TrRx board {{x}} node {{y}}", @@ -225,7 +223,7 @@ }, { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_TXGB_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_TXGB_TEMP_R\"} ", "hide": false, "interval": "", "legendFormat": "TrHx board {{x}} node {{y}}", @@ -233,23 +231,28 @@ }, { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_PGM_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_PGM_TEMP_R\"} ", "hide": false, "interval": "", "legendFormat": "IO board {{x}} node {{y}}", "refId": "E" }, { + "exemplar": true, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_POL_HGXB_TEMP_R\"} ", "hide": false, + "interval": "", + "legendFormat": "HGXB board {{x}} node {{y}}", "refId": "F" } ], - "title": "Uniboard2 Node Temperatures", + "title": "Uniboard2 FPGA POL Temperatures", + "transformations": [], "type": "timeseries" }, { "datasource": "Prometheus", - "description": "Temperature sensors of the power supply on each board", + "description": "", "fieldConfig": { "defaults": { "color": { @@ -308,7 +311,7 @@ "x": 10, "y": 1 }, - "id": 8, + "id": 22, "options": { "legend": { "calcs": [], @@ -322,62 +325,287 @@ "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_QSFP_N01_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_QSFP_CAGE_TEMP_R\"}", "interval": "", - "legendFormat": "QSFP N01 board {{x}} ", + "legendFormat": "FPGA QSFP Cage {{x}}, {{y}} ", "refId": "A" + } + ], + "title": "Uniboard2 QSFP Cage Temperatures", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "max" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 85 + } + ] + }, + "unit": "celsius" }, - { - "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_QSFP_N23_TEMP_R\"}", - "hide": false, - "interval": "", - "legendFormat": "QSFP N23 board {{x}}", - "refId": "B" + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 5, + "x": 15, + "y": 1 + }, + "id": 23, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_SWITCH_1V2_TEMP_R\"}", - "hide": false, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_FPGA_DDR4_SLOT_TEMP_R\"}", "interval": "", - "legendFormat": "Switch 1v2 board {{x}}", - "refId": "C" + "legendFormat": "FPGA QSFP Cage {{x}}, {{y}} ", + "refId": "A" + } + ], + "title": "Uniboard2 DDR4 Temperatures", + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "celsius" }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 5, + "x": 0, + "y": 9 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.1.2", + "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_SWITCH_PHY_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/recv/1\",name=\"RCU_TEMP_R\"}", + "format": "time_series", "hide": false, + "instant": false, "interval": "", - "legendFormat": "Switch PHY board {{x}}", - "refId": "D" + "legendFormat": "{{x}}", + "refId": "A" + } + ], + "title": "RCU Temperatures", + "transformations": [], + "type": "timeseries" + }, + { + "datasource": "Prometheus", + "description": "Temperatures reported by APSCT and APSPU", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic", + "seriesBy": "max" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 85 + } + ] + }, + "unit": "celsius" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 5, + "x": 5, + "y": 9 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "bottom" }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_CLOCK_TEMP_R\"}", - "hide": false, + "expr": "device_attribute{device=\"lts/apsct/1\",name=~\"APSCT_TEMP_R\"}", "interval": "", - "legendFormat": "Clock PWR board {{x}}", - "refId": "E" + "legendFormat": "{{name}}", + "refId": "A" }, { "exemplar": true, - "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_DC_DC_48V_12V_TEMP_R\"}", + "expr": "device_attribute{device=\"lts/apspu/1\",name=~\"APSPU_.*_TEMP_R\"}", "hide": false, "interval": "", - "legendFormat": "DC-DC board {{x}}", - "refId": "F" + "legendFormat": "{{name}}", + "refId": "B" } ], - "title": "Uniboard2 Power Supply Temperatures", + "title": "APS Temperatures", "type": "timeseries" }, { "datasource": "Prometheus", - "description": "", + "description": "Temperature sensors of the power supply on each board", "fieldConfig": { "defaults": { "color": { - "mode": "palette-classic" + "mode": "palette-classic", + "seriesBy": "max" }, "custom": { "axisLabel": "", @@ -397,14 +625,14 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "auto", + "showPoints": "never", "spanNulls": false, "stacking": { "group": "A", "mode": "none" }, "thresholdsStyle": { - "mode": "off" + "mode": "line" } }, "mappings": [], @@ -417,7 +645,7 @@ }, { "color": "red", - "value": 80 + "value": 85 } ] }, @@ -429,9 +657,9 @@ "h": 8, "w": 5, "x": 15, - "y": 1 + "y": 9 }, - "id": 6, + "id": 8, "options": { "legend": { "calcs": [], @@ -442,21 +670,56 @@ "mode": "single" } }, - "pluginVersion": "8.1.2", "targets": [ { "exemplar": true, - "expr": "device_attribute{device=\"lts/sdp/1\",name=\"FPGA_temp_R\"}", - "format": "time_series", - "hide": false, - "instant": false, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_QSFP_N01_TEMP_R\"} ", "interval": "", - "legendFormat": "{{x}}", + "legendFormat": "QSFP N01 board {{x}}", "refId": "A" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_QSFP_N23_TEMP_R\"} ", + "hide": false, + "interval": "", + "legendFormat": "QSFP N23 board {{x}}", + "refId": "B" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_SWITCH_1V2_TEMP_R\"} ", + "hide": false, + "interval": "", + "legendFormat": "Switch 1v2 board {{x}}", + "refId": "C" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_SWITCH_PHY_TEMP_R\"} ", + "hide": false, + "interval": "", + "legendFormat": "Switch PHY board {{x}}", + "refId": "D" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_POL_CLOCK_TEMP_R\"} ", + "hide": false, + "interval": "", + "legendFormat": "Clock PWR board {{x}}", + "refId": "E" + }, + { + "exemplar": true, + "expr": "device_attribute{device=\"lts/unb2/1\",name=\"UNB2_DC_DC_48V_12V_TEMP_R\"} ", + "hide": false, + "interval": "", + "legendFormat": "DC-DC board {{x}}", + "refId": "F" } ], - "title": "FPGA temperatures", - "transformations": [], + "title": "Uniboard2 Power Supply Temperatures", "type": "timeseries" }, { @@ -466,7 +729,7 @@ "h": 1, "w": 24, "x": 0, - "y": 9 + "y": 17 }, "id": 18, "panels": [], @@ -534,7 +797,7 @@ "h": 8, "w": 5, "x": 0, - "y": 10 + "y": 18 }, "id": 21, "options": { @@ -619,7 +882,7 @@ "h": 8, "w": 5, "x": 5, - "y": 10 + "y": 18 }, "id": 10, "options": { @@ -736,7 +999,7 @@ "h": 8, "w": 5, "x": 10, - "y": 10 + "y": 18 }, "id": 12, "options": { @@ -808,7 +1071,7 @@ "h": 1, "w": 24, "x": 0, - "y": 18 + "y": 26 }, "id": 20, "panels": [], @@ -878,7 +1141,7 @@ "h": 8, "w": 5, "x": 0, - "y": 19 + "y": 27 }, "id": 14, "options": { @@ -923,5 +1186,5 @@ "timezone": "", "title": "Sensors", "uid": "KMRmQzd7z", - "version": 3 + "version": 1 } diff --git a/docker-compose/integration-test.yml b/docker-compose/integration-test.yml index e0d1c6baf58948cdbee5a71ff2f859ab429dcd4b..1811645b06f4d576a71a66d2f36a475c976a2308 100644 --- a/docker-compose/integration-test.yml +++ b/docker-compose/integration-test.yml @@ -15,6 +15,8 @@ services: container_name: ${CONTAINER_NAME_PREFIX}integration-test networks: - control + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw environment: diff --git a/docker-compose/itango.yml b/docker-compose/itango.yml index 5b0874f2f3c936c1b57915580ac79be81b5edcb9..9b01c4ea25e2abc5849c9a98c29cc7601ba1115f 100644 --- a/docker-compose/itango.yml +++ b/docker-compose/itango.yml @@ -21,6 +21,8 @@ services: container_name: ${CONTAINER_NAME_PREFIX}itango networks: - control + extra_hosts: + - "host.docker.internal:host-gateway" volumes: - ..:/opt/lofar/tango:rw - ${HOME}:/hosthome diff --git a/docker-compose/jupyter/Dockerfile b/docker-compose/jupyter/Dockerfile index 8be3e9f3900b01e80893d38aedcb4f6397aa8fd0..5393cece6a74ff1de85e9c37ce6a8307e3a66cf5 100644 --- a/docker-compose/jupyter/Dockerfile +++ b/docker-compose/jupyter/Dockerfile @@ -25,6 +25,7 @@ RUN sudo pip3 install notebook-as-pdf # see https://github.com/jupyter/nbconvert/issues/1434 RUN sudo bash -c "echo DEFAULT_ARGS += [\\\"--no-sandbox\\\"] >> /usr/local/lib/python3.7/dist-packages/pyppeteer/launcher.py" +RUN sudo apt-get update -y RUN sudo apt-get install -y gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libcairo-gobject2 libxinerama1 libgtk2.0-0 libpangoft2-1.0-0 libthai0 libpixman-1-0 libxcb-render0 libharfbuzz0b libdatrie1 libgraphite2-3 libgbm1 # Allow Download as -> PDF via LaTeX diff --git a/docker-compose/lofar-device-base.yml b/docker-compose/lofar-device-base.yml index 22ecabca37c526867afe52461d7ce432964f8385..ce110ed85ba0cfb20b607ab7d08e70505d2392e8 100644 --- a/docker-compose/lofar-device-base.yml +++ b/docker-compose/lofar-device-base.yml @@ -20,5 +20,9 @@ services: args: SOURCE_IMAGE: ${DOCKER_REGISTRY_HOST}/${DOCKER_REGISTRY_USER}-tango-itango:${TANGO_ITANGO_VERSION} container_name: ${CONTAINER_NAME_PREFIX}lofar-device-base + # These parameters are just visual queues, you have to define them again + # in derived docker-compose files! networks: - control + extra_hosts: + - "host.docker.internal:host-gateway" diff --git a/docker-compose/prometheus.yml b/docker-compose/prometheus.yml index a0971c48fde4551809a936594aadcb6a79076712..604f4bf4bde93dd6d68aaf7f3b1da2fd3f884e83 100644 --- a/docker-compose/prometheus.yml +++ b/docker-compose/prometheus.yml @@ -16,4 +16,10 @@ services: - control ports: - "9090:9090" + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped diff --git a/docker-compose/rest.yml b/docker-compose/rest.yml index b76ed39c5319b10403a93db6736ce8d640380efc..467319399d6f3fec12a74068fea182195014b59e 100644 --- a/docker-compose/rest.yml +++ b/docker-compose/rest.yml @@ -33,3 +33,10 @@ services: - /usr/bin/supervisord - --configuration - /etc/supervisor/supervisord.conf + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" + restart: unless-stopped diff --git a/docker-compose/sdptr-sim/Dockerfile b/docker-compose/sdptr-sim/Dockerfile index fa23fe4d6458f4b7023c24b36774566cbac2163c..57fe98141f180a4d15a1e2d87c2c67be8f5894ff 100644 --- a/docker-compose/sdptr-sim/Dockerfile +++ b/docker-compose/sdptr-sim/Dockerfile @@ -16,5 +16,7 @@ RUN cd /sdptr && \ ./configure && \ bash -c "make -j `nproc` install" +COPY simulator.conf /sdptr/src/simulator.conf + WORKDIR /sdptr/src -CMD ["sdptr", "--type=LTS", "--configfile=uniboard.conf", "--nodaemon"] +CMD ["sdptr", "--type=simulator", "--configfile=simulator.conf", "--nodaemon"] diff --git a/docker-compose/sdptr-sim/simulator.conf b/docker-compose/sdptr-sim/simulator.conf new file mode 100644 index 0000000000000000000000000000000000000000..5ad69a8aed4807b815eeea18993d2b06e747b29f --- /dev/null +++ b/docker-compose/sdptr-sim/simulator.conf @@ -0,0 +1,19 @@ +# sdptr.conf +# configuration file for the SDP Translator. +# +# this config file holds settings for all [type]. +# +# # settings per type +# [LB_CORE] # [ant_band_station_type] +# n_fpgas = 16 # 8 or 16 +# first_pfga_nr = 0 # 0 for LB or 16 for HB +# ip_prefix = 10.99. # first part of ip (last part is hardware dependent) +# n_beamsets = 1 # 1 for 'LB', 'HB Remote' and 'HB International' and 2 for 'HB Core' + + +[simulator] +n_fpgas = 16 +first_fpga_nr = 0 +ip_prefix = 127.0. +n_beamsets = 1 + diff --git a/docker-compose/tango-prometheus-exporter/ska-tango-grafana-exporter b/docker-compose/tango-prometheus-exporter/ska-tango-grafana-exporter index 774d39a40ca19c9d979ad22565e57b4af3e9a831..dddb23ff587f6e9c837cdb77e7955e94272eca6f 160000 --- a/docker-compose/tango-prometheus-exporter/ska-tango-grafana-exporter +++ b/docker-compose/tango-prometheus-exporter/ska-tango-grafana-exporter @@ -1 +1 @@ -Subproject commit 774d39a40ca19c9d979ad22565e57b4af3e9a831 +Subproject commit dddb23ff587f6e9c837cdb77e7955e94272eca6f diff --git a/docker-compose/tango.yml b/docker-compose/tango.yml index 9fa0f5cde06f91b7cdc078f5c6481b013442e5ae..937cc5c8ecbe00b553d4692988e6cc2e5d7c51ef 100644 --- a/docker-compose/tango.yml +++ b/docker-compose/tango.yml @@ -28,6 +28,12 @@ services: - tangodb:/var/lib/mysql ports: - "3306:3306" + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped databaseds: @@ -55,4 +61,10 @@ services: - "2" - -ORBendPoint - giop:tcp::10000 + logging: + driver: syslog + options: + syslog-address: udp://${LOG_HOSTNAME}:1514 + syslog-format: rfc3164 + tag: "{{.Name}}" restart: unless-stopped diff --git a/docs/source/developer.rst b/docs/source/developer.rst index 517dfa324298e9451bfa5f9b25eef9726476686e..38b18bc5d199546d93e0387788b640350471b61d 100644 --- a/docs/source/developer.rst +++ b/docs/source/developer.rst @@ -59,3 +59,40 @@ For more information, see: - https://huihoo.org/ace_tao/ACE-5.2+TAO-1.2/TAO/docs/ORBEndpoint.html - http://omniorb.sourceforge.net/omni42/omniNames.html - https://sourceforge.net/p/omniorb/svn/HEAD/tree/trunk/omniORB/src/lib/omniORB/orbcore/tcp/tcpEndpoint.cc + +Logging +------------------------- + +The ELK stack collects the logs from the containers, as well as any external processes that send theirs. It is the *Logstash* part of ELK that is responsible for this. The following interfaces are available for this purpose: + ++-------------+------------+-------------------------------------------------------------------------------------------------------------+ +| Interface | Port | Note | ++=============+============+=============================================================================================================+ +| Syslog | 1514/udp | Recommended over TCP, as the ELK stack might be down. | ++-------------+------------+-------------------------------------------------------------------------------------------------------------+ +| Syslog | 1514/tcp | | ++-------------+------------+-------------------------------------------------------------------------------------------------------------+ +| JSON | 5959/tcp | From python, recommended is the `LogStash Async <https://pypi.org/project/python-logstash-async/>`_ module. | ++-------------+------------+-------------------------------------------------------------------------------------------------------------+ +| Beats | 5044/tcp | Use `FileBeat <https://www.elastic.co/beats/filebeat>`_ to watch logs locally, and forward them to ELK. | ++-------------+------------+-------------------------------------------------------------------------------------------------------------+ + +We recommend making sure the contents of your log lines are parsed correctly, especially if logs are routed to the *Syslog* input. These configurations are stored in ``docker-compose/elk/logstash/conf.d``. An example: + +.. literalinclude:: ../../docker-compose/elk/logstash/conf.d/22-parse-tango-rest.conf + +Log from Python +````````````````` + +The ``common.lofar_logging`` module provides an easy way to log to the ELK stack from a Python Tango device. + +Log from Docker +````````````````` + +Not all Docker containers run our Python programs, and can forward the logs themselves. For those, we use the ``syslog`` log driver in Docker. Extend the ``docker compose`` files with: + +.. literalinclude:: ../../docker-compose/rest.yml + :start-at: logging: + :end-before: restart: + +Logs forwarded in this way are provided with the container name, their timestamp, and a log level guessed by Docker. It is thus wise to parse the message content further in Logstash (see above). diff --git a/docs/source/interfaces/logs.rst b/docs/source/interfaces/logs.rst index 960efcd95b5306ab1904ffd8519e36af85099f0f..fa0d29765c5d228454222a8f4a8d3d8f935c46be 100644 --- a/docs/source/interfaces/logs.rst +++ b/docs/source/interfaces/logs.rst @@ -15,11 +15,11 @@ ELK To monitor the logs remotely, or to browse older logs, use the *ELK stack* that is included on the station, and served on http://localhost:5601. ELK, or ElasticSearch + Logstash + Kibana, is a popular log collection and querying system. Currently, the following logs are collected in our ELK installation: - Logs of all devices, -- Logs of the Jupyter notebook server. +- Logs of the Docker containers. If you browse to the ELK stack (actually, it is Kibana providing the GUI), your go-to is the *Discover* view at http://localhost:5601/app/discover. There, you can construct (and save, load) a dashboard that provides a custom view of the logs, based on the *index pattern* ``logstash-*``. There is a lot to take in, and there are excellent Kibana tutorials on the web. -To get going, use for example `this dashboard <http://localhost:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-60m,to:now))&_a=(columns:!(extra.lofar_id,level,message),filters:!(),index:'1e8ca200-1be0-11ec-a85f-b97e4206c18b',interval:auto,query:(language:kuery,query:''),sort:!())>`_, which shows the logs of the last hour, with some useful columns added to the default timestamp and message columns. Expand the time range if no logs appear, to look further back. You should see something like: +To get going, use for example `this dashboard <http://localhost:5601/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-1h,to:now))&_a=(columns:!(extra.lofar_id,program,level,message),filters:!(),index:'1e8ca200-1be0-11ec-a85f-b97e4206c18b',interval:auto,query:(language:kuery,query:'extra.lofar_id.keyword%20:%20*'),sort:!())>`_, which shows the logs of the last hour, with some useful columns added to the default timestamp and message columns. Expand the time range if no logs appear, to look further back. You should see something like: .. image:: elk_last_hour.png diff --git a/sbin/load_ConfigDb.sh b/sbin/load_ConfigDb.sh index 03ab449a026b5de41056f16de0d2e566a00adfbb..0fe57087a89dc08ebef51d4679a687ebbf6a144a 100755 --- a/sbin/load_ConfigDb.sh +++ b/sbin/load_ConfigDb.sh @@ -9,10 +9,10 @@ fi # copy file into container to read it from container, as the file's location # in the container won't be the same as on the host. -docker cp "${file}" dsconfig:/tmp/dsconfig-load-settings.json || exit 1 +docker cp "${file}" "${CONTAINER_NAME_PREFIX}"dsconfig:/tmp/dsconfig-update-settings.json || exit 1 -# write settings -docker exec -it dsconfig json2tango --write /tmp/dsconfig-load-settings.json +# update settings, Do not change -i into -it this will break integration tests in gitlab ci! +docker exec -i "${CONTAINER_NAME_PREFIX}"dsconfig json2tango --write /tmp/dsconfig-update-settings.json # somehow json2tango does not return 0 on success exit 0 diff --git a/sbin/run_integration_test.sh b/sbin/run_integration_test.sh index 2175f2774e771ac31e9dcd1cb1ade68da51f923e..4e988f7fce03eaf4142193c8156ddbcf60ace0bf 100755 --- a/sbin/run_integration_test.sh +++ b/sbin/run_integration_test.sh @@ -9,16 +9,22 @@ if [ -z "$LOFAR20_DIR" ]; then LOFAR20_DIR=$(readlink -f "${LOFAR20_DIR_RELATIVE}") fi -# Start and stop sequence cd "$LOFAR20_DIR/docker-compose" || exit 1 + +# Make sure builds are recent, and use our building parameters. +make build + +# Start and stop sequence make stop device-sdp device-recv device-sst device-unb2 device-xst sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim -make start databaseds dsconfig jupyter elk +make start databaseds dsconfig elk # Give dsconfig and databaseds time to start -sleep 15 +sleep 60 # Update the dsconfig -"${LOFAR20_DIR}"/sbin/update_ConfigDb.sh "${LOFAR20_DIR}"/CDB/integration_ConfigDb.json +# Do not remove `bash`, otherwise statement ignored by gitlab ci shell! +bash "${LOFAR20_DIR}"/sbin/update_ConfigDb.sh "${LOFAR20_DIR}"/CDB/LOFAR_ConfigDb.json +bash "${LOFAR20_DIR}"/sbin/update_ConfigDb.sh "${LOFAR20_DIR}"/CDB/stations/simulators_ConfigDb.json cd "$LOFAR20_DIR/docker-compose" || exit 1 make start sdptr-sim recv-sim unb2-sim apsct-sim apspu-sim @@ -28,12 +34,16 @@ sleep 5 make start device-sdp device-recv device-sst device-unb2 device-xst -# Give the devices time to start -sleep 5 +# Give devices time to restart +# TODO(Corne Lukken): Use a nicer more reliable mechanism +sleep 60 # Start the integration test cd "$LOFAR20_DIR/docker-compose" || exit 1 make start integration-test +# Give devices time to restart +sleep 60 + # Run the integration test with the output displayed on stdout -docker start -a integration-test +docker start -a "${CONTAINER_NAME_PREFIX}"integration-test diff --git a/sbin/update_ConfigDb.sh b/sbin/update_ConfigDb.sh index 8d71c312fc94ba4dba45b17c05a966f62fa9ff34..1255f1ea141a75940f2cd858dfc2b40818bd6ec2 100755 --- a/sbin/update_ConfigDb.sh +++ b/sbin/update_ConfigDb.sh @@ -9,10 +9,10 @@ fi # copy file into container to read it from container, as the file's location # in the container won't be the same as on the host. -docker cp "${file}" dsconfig:/tmp/dsconfig-update-settings.json || exit 1 +docker cp "${file}" "${CONTAINER_NAME_PREFIX}"dsconfig:/tmp/dsconfig-update-settings.json || exit 1 -# update settings -docker exec -it dsconfig json2tango --write --update /tmp/dsconfig-update-settings.json +# update settings, Do not change -i into -it this will break integration tests in gitlab ci! +docker exec -i "${CONTAINER_NAME_PREFIX}"dsconfig json2tango --write --update /tmp/dsconfig-update-settings.json # somehow json2tango does not return 0 on success exit 0