From c1d4fa88f033a7735c6f087d3a0b6d951a4d887b Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:09:02 +0100 Subject: [PATCH 01/23] Creating template file structure in support submodule --- .gitattributes | 29 +++++++++++++ .gitignore | 21 ++++++++++ LICENCE | 30 ++++++++++++++ Makefile | 37 +++++++++++++++++ configure/CONFIG | 29 +++++++++++++ configure/CONFIG_SITE | 43 +++++++++++++++++++ configure/Makefile | 8 ++++ configure/RELEASE | 5 +++ configure/RULES | 6 +++ configure/RULES_DIRS | 2 + configure/RULES_TOP | 3 ++ documentation/devrknmntr.html | 78 +++++++++++++++++++++++++++++++++++ rknmntrSup/Makefile | 10 +++++ rknmntrSup/rknmntr.db | 19 +++++++++ rknmntrSup/rknmntr.proto | 18 ++++++++ 15 files changed, 338 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENCE create mode 100644 Makefile create mode 100644 configure/CONFIG create mode 100644 configure/CONFIG_SITE create mode 100644 configure/Makefile create mode 100644 configure/RELEASE create mode 100644 configure/RULES create mode 100644 configure/RULES_DIRS create mode 100644 configure/RULES_TOP create mode 100644 documentation/devrknmntr.html create mode 100644 rknmntrSup/Makefile create mode 100644 rknmntrSup/rknmntr.db create mode 100644 rknmntrSup/rknmntr.proto diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9585212 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,29 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.cpp text +*.h text +*.hpp text +*.java text +*.sh text eol=lf +*.bat text +*.cmd text +*.db text +*.dbd text +*.template text +*.substitutions text +*.py text +*.rst text +*.uxf text + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.class binary +*.vi binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43df806 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +O.*/ +/db +/bin +/dbd +/include +/lib +/templates +test-reports +envPaths +cdCommands +dllPath.bat +runIOC.bat +runIOC.sh +relPaths.sh +*.tag +/data/ +/doc/ +*_info_positions.req +*_info_settings.req +*.py[cod] +__pycache__/ diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..45589b4 --- /dev/null +++ b/LICENCE @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2023, Science and Technology Facilities Council +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..12a7415 --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +# Makefile for Asyn rknmntr support +# +# Created by wtn43451 on Wed Sep 27 14:08:57 2023 +# Based on the Asyn streamSCPI template + +TOP = . +include $(TOP)/configure/CONFIG + +DIRS += configure +DIRS += $(wildcard *Sup) +DIRS += $(wildcard *App) +DIRS += $(wildcard *Top) +DIRS += $(wildcard iocBoot) + +# The build order is controlled by these dependency rules: + +# All dirs except configure depend on configure +$(foreach dir, $(filter-out configure, $(DIRS)), \ + $(eval $(dir)_DEPEND_DIRS += configure)) + +# Any *App dirs depend on all *Sup dirs +$(foreach dir, $(filter %App, $(DIRS)), \ + $(eval $(dir)_DEPEND_DIRS += $(filter %Sup, $(DIRS)))) + +# Any *Top dirs depend on all *Sup and *App dirs +$(foreach dir, $(filter %Top, $(DIRS)), \ + $(eval $(dir)_DEPEND_DIRS += $(filter %Sup %App, $(DIRS)))) + +# iocBoot depends on all *App dirs +iocBoot_DEPEND_DIRS += $(filter %App,$(DIRS)) + +# Add any additional dependency rules here: + +include $(TOP)/configure/RULES_TOP + +ioctests: + .\system_tests\run_tests.bat diff --git a/configure/CONFIG b/configure/CONFIG new file mode 100644 index 0000000..c1a4703 --- /dev/null +++ b/configure/CONFIG @@ -0,0 +1,29 @@ +# CONFIG - Load build configuration data +# +# Do not make changes to this file! + +# Allow user to override where the build rules come from +RULES = $(EPICS_BASE) + +# RELEASE files point to other application tops +include $(TOP)/configure/RELEASE +-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common +ifdef T_A +-include $(TOP)/configure/RELEASE.Common.$(T_A) +-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A) +endif + +CONFIG = $(RULES)/configure +include $(CONFIG)/CONFIG + +# Override the Base definition: +INSTALL_LOCATION = $(TOP) + +# CONFIG_SITE files contain other build configuration settings +include $(TOP)/configure/CONFIG_SITE +-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common +ifdef T_A + -include $(TOP)/configure/CONFIG_SITE.Common.$(T_A) + -include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) +endif + diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE new file mode 100644 index 0000000..212485e --- /dev/null +++ b/configure/CONFIG_SITE @@ -0,0 +1,43 @@ +# CONFIG_SITE + +# Make any application-specific changes to the EPICS build +# configuration variables in this file. +# +# Host/target specific settings can be specified in files named +# CONFIG_SITE.$(EPICS_HOST_ARCH).Common +# CONFIG_SITE.Common.$(T_A) +# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) + +# CHECK_RELEASE controls the consistency checking of the support +# applications pointed to by the RELEASE* files. +# Normally CHECK_RELEASE should be set to YES. +# Set CHECK_RELEASE to NO to disable checking completely. +# Set CHECK_RELEASE to WARN to perform consistency checking but +# continue building even if conflicts are found. +CHECK_RELEASE = YES + +# Set this when you only want to compile this application +# for a subset of the cross-compiled target architectures +# that Base is built for. +#CROSS_COMPILER_TARGET_ARCHS = vxWorks-ppc32 + +# To install files into a location other than $(TOP) define +# INSTALL_LOCATION here. +#INSTALL_LOCATION= + +# Set this when the IOC and build host use different paths +# to the install location. This may be needed to boot from +# a Microsoft FTP server say, or on some NFS configurations. +#IOCS_APPL_TOP = + +# For application debugging purposes, override the HOST_OPT and/ +# or CROSS_OPT settings from base/configure/CONFIG_SITE +#HOST_OPT = NO +#CROSS_OPT = NO + +# These allow developers to override the CONFIG_SITE variable +# settings without having to modify the configure/CONFIG_SITE +# file itself. +-include $(TOP)/../CONFIG_SITE.local +-include $(TOP)/configure/CONFIG_SITE.local + diff --git a/configure/Makefile b/configure/Makefile new file mode 100644 index 0000000..9254309 --- /dev/null +++ b/configure/Makefile @@ -0,0 +1,8 @@ +TOP=.. + +include $(TOP)/configure/CONFIG + +TARGETS = $(CONFIG_TARGETS) +CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS))) + +include $(TOP)/configure/RULES diff --git a/configure/RELEASE b/configure/RELEASE new file mode 100644 index 0000000..7fc8365 --- /dev/null +++ b/configure/RELEASE @@ -0,0 +1,5 @@ +# optional extra local definitions here +-include $(TOP)/configure/RELEASE.private + +include $(TOP)/../../../ISIS_CONFIG +-include $(TOP)/../../../ISIS_CONFIG.$(EPICS_HOST_ARCH) diff --git a/configure/RULES b/configure/RULES new file mode 100644 index 0000000..6d56e14 --- /dev/null +++ b/configure/RULES @@ -0,0 +1,6 @@ +# RULES + +include $(CONFIG)/RULES + +# Library should be rebuilt because LIBOBJS may have changed. +$(LIBNAME): ../Makefile diff --git a/configure/RULES_DIRS b/configure/RULES_DIRS new file mode 100644 index 0000000..3ba269d --- /dev/null +++ b/configure/RULES_DIRS @@ -0,0 +1,2 @@ +#RULES_DIRS +include $(CONFIG)/RULES_DIRS diff --git a/configure/RULES_TOP b/configure/RULES_TOP new file mode 100644 index 0000000..d09d668 --- /dev/null +++ b/configure/RULES_TOP @@ -0,0 +1,3 @@ +#RULES_TOP +include $(CONFIG)/RULES_TOP + diff --git a/documentation/devrknmntr.html b/documentation/devrknmntr.html new file mode 100644 index 0000000..8640236 --- /dev/null +++ b/documentation/devrknmntr.html @@ -0,0 +1,78 @@ + + + + + + rknmntr Instrument Support + + + + +

Using rknmntr instrument support in an application

+ +

Several files need minor modifications to use rknmntr instrument support in +an application.

+
    +
  1. Add the full path to the rknmntr support directory to the + application configure/RELEASE file:
    + rknmntr=xxxx/modules/instrument/rknmntr/<release>
    +Where <release> is the release number of of the rknmntr support.
  2. +
  3. Add stream and asyn support to application database definition file
    + The application database definition file must include the database + definition files for the stream package and for any needed ASYN + drivers. There are two ways that this can be done: + +
  4. +
  5. Add the stream and asyn support libraries to the application
    + You must link the stream support library and the ASYN support library + with the application. Add the following lines:
    + xxx_LIBS += stream
    + xxx_LIBS += asyn
    + before the
    + xxx_LIBS += $(EPICS_BASE_IOC_LIBS)
    + in the application Makefile.
  6. +
  7. Load the rknmntr support database records in the application startup script:
    + cd $(rknmntr)      (cd rknmntr if using the vxWorks shell)
    + dbLoadRecords("db/devrknmntr.db,"P=<P>,R=<R>,PORT=<PORT>,A=<A>")
    + You'll have to provide appropriate values for the PV name prefixes + (<P> and <R>), the port name (<PORT>) and the device address + (<A>). The port name must match the value specified in + an ASYN drvxxxxxConfigure command. +
  8. +
+

Installation and Building

+After obtaining a copy of the distribution, it must be installed and built +for use at your site. +
    +
  1. Create an installation directory for the module. The path name + of this directory should end with modules/instrument/rknmntr.
  2. +
  3. Place the distribution file into this directory.
  4. +
  5. Execute the following commands:
    + cd modules/instrument/rknmntr
    + gunzip rknmntr<release>.tar.gz
    + tar xvf rknmntr<release>.tar
    + cd <release>
    +Where <release> is the release number of of the rknmntr support. +
  6. +
  7. Edit the configure/RELEASE file and set the paths to your + installation of EPICS base, stream and ASYN support modules.
  8. +
  9. Execute make in the top level directory.
  10. +
+ + + + diff --git a/rknmntrSup/Makefile b/rknmntrSup/Makefile new file mode 100644 index 0000000..e54f982 --- /dev/null +++ b/rknmntrSup/Makefile @@ -0,0 +1,10 @@ +TOP=.. +include $(TOP)/configure/CONFIG +#======================================= + +# Install .dbd and .db files +DB += rknmntr.db +DATA += rknmntr.proto + +#======================================= +include $(TOP)/configure/RULES diff --git a/rknmntrSup/rknmntr.db b/rknmntrSup/rknmntr.db new file mode 100644 index 0000000..4c7f7b3 --- /dev/null +++ b/rknmntrSup/rknmntr.db @@ -0,0 +1,19 @@ +record(bo, "$(P)SIM") +{ + field(SCAN, "Passive") + field(DTYP, "Soft Channel") + field(ZNAM, "NO") + field(ONAM, "YES") + field(VAL, "$(RECSIM=0)") + field(PINI, "YES") +} + +record(bo, "$(P)DISABLE") +{ + field(DESC, "Disable comms") + field(PINI, "YES") + field(VAL, "$(DISABLE=0)") + field(OMSL, "supervisory") + field(ZNAM, "COMMS ENABLED") + field(ONAM, "COMMS DISABLED") +} diff --git a/rknmntrSup/rknmntr.proto b/rknmntrSup/rknmntr.proto new file mode 100644 index 0000000..3326465 --- /dev/null +++ b/rknmntrSup/rknmntr.proto @@ -0,0 +1,18 @@ +getIDN { + out "*IDN?"; + in "%\$1[^\r\n]"; + ExtraInput = Ignore; +} + +cmd { + out "\$1"; +} + +setD { + out "\$1 %d"; +} +getD { + out "\$1?"; + in "%d"; + ExtraInput = Ignore; +} From 222671805bf2914adad01bfeda8a658fb52fd4a8 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:09:34 +0100 Subject: [PATCH 02/23] Add device to test framework --- system_tests/run_tests.bat | 13 +++++++++++++ system_tests/tests/__init__.py | 0 system_tests/tests/rknmntr.py | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 system_tests/run_tests.bat create mode 100644 system_tests/tests/__init__.py create mode 100644 system_tests/tests/rknmntr.py diff --git a/system_tests/run_tests.bat b/system_tests/run_tests.bat new file mode 100644 index 0000000..56f9c25 --- /dev/null +++ b/system_tests/run_tests.bat @@ -0,0 +1,13 @@ +@echo off +REM Run this directory's tests using the IOC Testing Framework + +SET CurrentDir=%~dp0 + +call "%~dp0..\..\..\..\config_env.bat" + +set "PYTHONUNBUFFERED=1" + +REM Command line arguments always passed to the test script +SET ARGS=--test_and_emulator %~dp0 +call %PYTHON3% "%EPICS_KIT_ROOT%\support\IocTestFramework\master\run_tests.py" %ARGS% %* +IF %ERRORLEVEL% NEQ 0 EXIT /b %errorlevel% diff --git a/system_tests/tests/__init__.py b/system_tests/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/system_tests/tests/rknmntr.py b/system_tests/tests/rknmntr.py new file mode 100644 index 0000000..9c3b167 --- /dev/null +++ b/system_tests/tests/rknmntr.py @@ -0,0 +1,34 @@ +import unittest + +from utils.channel_access import ChannelAccess +from utils.ioc_launcher import get_default_ioc_dir +from utils.test_modes import TestModes +from utils.testing import get_running_lewis_and_ioc, skip_if_recsim + + +DEVICE_PREFIX = "RKNMNTR_01" + + +IOCS = [ + { + "name": DEVICE_PREFIX, + "directory": get_default_ioc_dir("RKNMNTR"), + "macros": {}, + "emulator": "Rknmntr", + }, +] + + +TEST_MODES = [TestModes.RECSIM, TestModes.DEVSIM] + + +class RknmntrTests(unittest.TestCase): + """ + Tests for the Rknmntr IOC. + """ + def setUp(self): + self._lewis, self._ioc = get_running_lewis_and_ioc("Rknmntr", DEVICE_PREFIX) + self.ca = ChannelAccess(device_prefix=DEVICE_PREFIX) + + def test_that_fails(self): + self.fail("You haven't implemented any tests!") From 5761cf31a924b4dc642c647d5a42c1d173726cc3 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:09:47 +0100 Subject: [PATCH 03/23] Add template emulator --- .../lewis_emulators/Rknmntr/__init__.py | 5 +++ .../lewis_emulators/Rknmntr/device.py | 25 +++++++++++++++ .../Rknmntr/interfaces/__init__.py | 3 ++ .../Rknmntr/interfaces/stream_interface.py | 32 +++++++++++++++++++ .../lewis_emulators/Rknmntr/states.py | 5 +++ system_tests/lewis_emulators/__init__.py | 0 .../lewis_emulators/lewis_versions.py | 2 ++ 7 files changed, 72 insertions(+) create mode 100644 system_tests/lewis_emulators/Rknmntr/__init__.py create mode 100644 system_tests/lewis_emulators/Rknmntr/device.py create mode 100644 system_tests/lewis_emulators/Rknmntr/interfaces/__init__.py create mode 100644 system_tests/lewis_emulators/Rknmntr/interfaces/stream_interface.py create mode 100644 system_tests/lewis_emulators/Rknmntr/states.py create mode 100644 system_tests/lewis_emulators/__init__.py create mode 100644 system_tests/lewis_emulators/lewis_versions.py diff --git a/system_tests/lewis_emulators/Rknmntr/__init__.py b/system_tests/lewis_emulators/Rknmntr/__init__.py new file mode 100644 index 0000000..ab27daf --- /dev/null +++ b/system_tests/lewis_emulators/Rknmntr/__init__.py @@ -0,0 +1,5 @@ +from .device import SimulatedRknmntr +from ..lewis_versions import LEWIS_LATEST + +framework_version = LEWIS_LATEST +__all__ = ['SimulatedRknmntr'] diff --git a/system_tests/lewis_emulators/Rknmntr/device.py b/system_tests/lewis_emulators/Rknmntr/device.py new file mode 100644 index 0000000..62060ed --- /dev/null +++ b/system_tests/lewis_emulators/Rknmntr/device.py @@ -0,0 +1,25 @@ +from collections import OrderedDict +from .states import DefaultState +from lewis.devices import StateMachineDevice + + +class SimulatedRknmntr(StateMachineDevice): + + def _initialize_data(self): + """ + Initialize all of the device's attributes. + """ + pass + + def _get_state_handlers(self): + return { + 'default': DefaultState(), + } + + def _get_initial_state(self): + return 'default' + + def _get_transition_handlers(self): + return OrderedDict([ + ]) + diff --git a/system_tests/lewis_emulators/Rknmntr/interfaces/__init__.py b/system_tests/lewis_emulators/Rknmntr/interfaces/__init__.py new file mode 100644 index 0000000..2425422 --- /dev/null +++ b/system_tests/lewis_emulators/Rknmntr/interfaces/__init__.py @@ -0,0 +1,3 @@ +from .stream_interface import RknmntrStreamInterface + +__all__ = ['RknmntrStreamInterface'] diff --git a/system_tests/lewis_emulators/Rknmntr/interfaces/stream_interface.py b/system_tests/lewis_emulators/Rknmntr/interfaces/stream_interface.py new file mode 100644 index 0000000..a5676f2 --- /dev/null +++ b/system_tests/lewis_emulators/Rknmntr/interfaces/stream_interface.py @@ -0,0 +1,32 @@ +from lewis.adapters.stream import StreamInterface, Cmd +from lewis.utils.command_builder import CmdBuilder +from lewis.core.logging import has_log +from lewis.utils.replies import conditional_reply + + +@has_log +class RknmntrStreamInterface(StreamInterface): + + in_terminator = "\r\n" + out_terminator = "\r\n" + + def __init__(self): + super(RknmntrStreamInterface, self).__init__() + # Commands that we expect via serial during normal operation + self.commands = { + CmdBuilder(self.catch_all).arg("^#9.*$").build() # Catch-all command for debugging + } + + def handle_error(self, request, error): + """ + If command is not recognised print and error + + Args: + request: requested string + error: problem + + """ + self.log.error("An error occurred at request " + repr(request) + ": " + repr(error)) + + def catch_all(self, command): + pass diff --git a/system_tests/lewis_emulators/Rknmntr/states.py b/system_tests/lewis_emulators/Rknmntr/states.py new file mode 100644 index 0000000..e4ca48e --- /dev/null +++ b/system_tests/lewis_emulators/Rknmntr/states.py @@ -0,0 +1,5 @@ +from lewis.core.statemachine import State + + +class DefaultState(State): + pass diff --git a/system_tests/lewis_emulators/__init__.py b/system_tests/lewis_emulators/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/system_tests/lewis_emulators/lewis_versions.py b/system_tests/lewis_emulators/lewis_versions.py new file mode 100644 index 0000000..0f6c45a --- /dev/null +++ b/system_tests/lewis_emulators/lewis_versions.py @@ -0,0 +1,2 @@ +LEWIS_1_3_0 = "1.3.0" +LEWIS_LATEST = LEWIS_1_3_0 From 8f3d1b1fdafeee8ace2e735d9a4bba4b9addf8e7 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:43:31 +0100 Subject: [PATCH 04/23] First draft Communication works Still need to use macros --- rknmntrSup/Makefile | 5 +- rknmntrSup/RIKEN_TEMP_CALC.substitutions | 5 ++ rknmntrSup/RIKEN_TEMP_CALC.template | 58 ++++++++++++++++++++++++ rknmntrSup/rknmntr.proto | 18 -------- 4 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 rknmntrSup/RIKEN_TEMP_CALC.substitutions create mode 100644 rknmntrSup/RIKEN_TEMP_CALC.template delete mode 100644 rknmntrSup/rknmntr.proto diff --git a/rknmntrSup/Makefile b/rknmntrSup/Makefile index e54f982..2607764 100644 --- a/rknmntrSup/Makefile +++ b/rknmntrSup/Makefile @@ -3,8 +3,7 @@ include $(TOP)/configure/CONFIG #======================================= # Install .dbd and .db files -DB += rknmntr.db -DATA += rknmntr.proto - +DB += RIKEN_TEMP_CALC.db +#TODO add sim and disable records #======================================= include $(TOP)/configure/RULES diff --git a/rknmntrSup/RIKEN_TEMP_CALC.substitutions b/rknmntrSup/RIKEN_TEMP_CALC.substitutions new file mode 100644 index 0000000..c8fabdc --- /dev/null +++ b/rknmntrSup/RIKEN_TEMP_CALC.substitutions @@ -0,0 +1,5 @@ +file RIKEN_TEMP_CALC.template { + pattern { MAGNET, TAP, GAIN, MAGNET_PSU_IOC, INITIAL_RES } + + { "RQ1", "TAP01", "2" "$(RQ1_PSU_IOC)", "5.5" } +} diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template new file mode 100644 index 0000000..0fdf7c3 --- /dev/null +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -0,0 +1,58 @@ +# P +# MAG +# TAP +# GAIN +# MAGNET_PSU_IOC +# INITIAL_RES + +record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:RAW") { + # field(DESC, "Raw Voltage readback for $(MAGNET) magnet at $(TAP)") + field(INPA, "IN:RIKENFE:SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") #TODO use macro on instrument (on riken P will work) + field(CALC, "A") + field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") +} + +record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") { + # field(DESC, "The digital Voltage a the $(MAGNET) magnet at $(TAP)") + + field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:RAW") + + # The tap value is a signed 12-bit integer measured by the PLC ADC which has a 10V reference. This needs to be converted back to a voltage + field(CALC, "((A/((2**12)-1))*10)") + + field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") +} + +record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") { + # field(DESC, "The actual Voltage a the $(MAGNET) magnet at $(TAP)") + + field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") + field(INPB, "$(GAIN)") + + # The PLC measures the signal conditioned voltage and so needs to be divided by a gain to get the actual voltage at the magnet terminals + field(CALC, "A/B") + + field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") +} + +record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") { + # field(DESC, "The resistance a the $(MAGNET) magnet at $(TAP)") + + field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") + # field(INPB, "$(P):CURR") + # TODO fix use macro above + field(INPB, "IN:RIKENFE:DFKPS_01:CURR") + + field(CALC, "A/B") + + field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") +} + +record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") { + # field(DESC, "The temperature of the $(MAGNET) magnet at $(TAP)") + + field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") + field(INPB, "$(INITIAL_RES)") + + field(CALC, "(((A/B)-1)/0.004041)+23") +} \ No newline at end of file diff --git a/rknmntrSup/rknmntr.proto b/rknmntrSup/rknmntr.proto deleted file mode 100644 index 3326465..0000000 --- a/rknmntrSup/rknmntr.proto +++ /dev/null @@ -1,18 +0,0 @@ -getIDN { - out "*IDN?"; - in "%\$1[^\r\n]"; - ExtraInput = Ignore; -} - -cmd { - out "\$1"; -} - -setD { - out "\$1 %d"; -} -getD { - out "\$1?"; - in "%d"; - ExtraInput = Ignore; -} From 094d9efc19e7dcc3cfa9f069ab603ba9d8081e34 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:53:37 +0100 Subject: [PATCH 05/23] Use block to get PSU current Some code reformatting No need to pass through macros for magnet PSU IOCs this way --- rknmntrSup/RIKEN_TEMP_CALC.substitutions | 4 +-- rknmntrSup/RIKEN_TEMP_CALC.template | 44 +++++++++--------------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.substitutions b/rknmntrSup/RIKEN_TEMP_CALC.substitutions index c8fabdc..c3c9e9d 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.substitutions +++ b/rknmntrSup/RIKEN_TEMP_CALC.substitutions @@ -1,5 +1,5 @@ file RIKEN_TEMP_CALC.template { - pattern { MAGNET, TAP, GAIN, MAGNET_PSU_IOC, INITIAL_RES } + pattern { MAGNET, TAP, GAIN, INITIAL_RES } - { "RQ1", "TAP01", "2" "$(RQ1_PSU_IOC)", "5.5" } + { "RQ1", "TAP01", "2", "5.5" } } diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 0fdf7c3..040c7d1 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -1,58 +1,48 @@ -# P -# MAG -# TAP -# GAIN -# MAGNET_PSU_IOC -# INITIAL_RES +# Macros: +# +# P - instrument prefix +# MAG - magnet name +# TAP - tap name +# GAIN - gain for the tap (needed for calculations) +# INITIAL_RES - initial resistance (needed for the calculations) record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:RAW") { - # field(DESC, "Raw Voltage readback for $(MAGNET) magnet at $(TAP)") + field(DESC, "Raw Voltage at magnet $(MAGNET) at $(TAP)") field(INPA, "IN:RIKENFE:SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") #TODO use macro on instrument (on riken P will work) field(CALC, "A") field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") } record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") { - # field(DESC, "The digital Voltage a the $(MAGNET) magnet at $(TAP)") - + field(DESC, "Digital Voltage at magnet $(MAGNET) at $(TAP)") field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:RAW") - - # The tap value is a signed 12-bit integer measured by the PLC ADC which has a 10V reference. This needs to be converted back to a voltage + # The tap value is a signed 12-bit integer measured by the PLC ADC which + # has a 10V reference. This needs to be converted back to a voltage field(CALC, "((A/((2**12)-1))*10)") - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") } record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") { - # field(DESC, "The actual Voltage a the $(MAGNET) magnet at $(TAP)") - + field(DESC, "Actual Voltage at magnet $(MAGNET) at $(TAP)") field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") field(INPB, "$(GAIN)") - - # The PLC measures the signal conditioned voltage and so needs to be divided by a gain to get the actual voltage at the magnet terminals + # The PLC measures the signal conditioned voltage and so needs to be divided + # by a gain to get the actual voltage at the magnet terminals field(CALC, "A/B") - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") } record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") { - # field(DESC, "The resistance a the $(MAGNET) magnet at $(TAP)") - + field(DESC, "Resistance at magnet $(MAGNET) at $(TAP)") field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") - # field(INPB, "$(P):CURR") - # TODO fix use macro above - field(INPB, "IN:RIKENFE:DFKPS_01:CURR") - + field(INPB, "IN:RIKENFE:CS:SB:$(MAGNET)_CURR") field(CALC, "A/B") - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") } record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") { - # field(DESC, "The temperature of the $(MAGNET) magnet at $(TAP)") - + field(DESC, "Temperature of magnet $(MAGNET) at $(TAP)") field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") field(INPB, "$(INITIAL_RES)") - field(CALC, "(((A/B)-1)/0.004041)+23") } \ No newline at end of file From d3594e784b15abb04292bf9bd54202e5e35964a0 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:03:17 +0100 Subject: [PATCH 06/23] Fix initial resistance value --- rknmntrSup/RIKEN_TEMP_CALC.substitutions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.substitutions b/rknmntrSup/RIKEN_TEMP_CALC.substitutions index c3c9e9d..033046f 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.substitutions +++ b/rknmntrSup/RIKEN_TEMP_CALC.substitutions @@ -1,5 +1,5 @@ file RIKEN_TEMP_CALC.template { pattern { MAGNET, TAP, GAIN, INITIAL_RES } - { "RQ1", "TAP01", "2", "5.5" } + { "RQ1", "TAP01", "2", "7.7" } } From 5be8ea2a642c93634bdf9f7460c6040266ce5117 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:03:38 +0100 Subject: [PATCH 07/23] Convert resistance value from Ohms to Milliohms --- rknmntrSup/RIKEN_TEMP_CALC.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 040c7d1..5403fe1 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -36,7 +36,7 @@ record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") { field(DESC, "Resistance at magnet $(MAGNET) at $(TAP)") field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") field(INPB, "IN:RIKENFE:CS:SB:$(MAGNET)_CURR") - field(CALC, "A/B") + field(CALC, "(A/B)*1000") # Convert to milliohm field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") } From 288c019d255c0d90aa403dd6b720fe7f1ae24271 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Fri, 29 Sep 2023 10:43:52 +0100 Subject: [PATCH 08/23] Shorten PV names --- rknmntrSup/RIKEN_TEMP_CALC.template | 37 +++++++++++++---------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 5403fe1..2688c80 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -1,48 +1,43 @@ -# Macros: -# -# P - instrument prefix -# MAG - magnet name -# TAP - tap name -# GAIN - gain for the tap (needed for calculations) -# INITIAL_RES - initial resistance (needed for the calculations) -record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:RAW") { +# Calculations for $(MAGNET) $(TAP) + +record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { field(DESC, "Raw Voltage at magnet $(MAGNET) at $(TAP)") field(INPA, "IN:RIKENFE:SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") #TODO use macro on instrument (on riken P will work) field(CALC, "A") - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") + field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT:ADC") } -record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") { +record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { field(DESC, "Digital Voltage at magnet $(MAGNET) at $(TAP)") - field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:RAW") + field(INPA, "$(P)$(MAGNET):$(TAP):VOLT:RAW") # The tap value is a signed 12-bit integer measured by the PLC ADC which # has a 10V reference. This needs to be converted back to a voltage field(CALC, "((A/((2**12)-1))*10)") - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") + field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT") } -record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") { +record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { field(DESC, "Actual Voltage at magnet $(MAGNET) at $(TAP)") - field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT:ADC") + field(INPA, "$(P)$(MAGNET):$(TAP):VOLT:ADC") field(INPB, "$(GAIN)") # The PLC measures the signal conditioned voltage and so needs to be divided # by a gain to get the actual voltage at the magnet terminals field(CALC, "A/B") - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") + field(FLNK, "$(P)$(MAGNET):$(TAP):RES") } -record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") { +record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(DESC, "Resistance at magnet $(MAGNET) at $(TAP)") - field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):VOLT") + field(INPA, "$(P)$(MAGNET):$(TAP):VOLT") field(INPB, "IN:RIKENFE:CS:SB:$(MAGNET)_CURR") field(CALC, "(A/B)*1000") # Convert to milliohm - field(FLNK, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") + field(FLNK, "$(P)$(MAGNET):$(TAP):TEMP") } -record(calc, "$(P)$(MAGNET):TEMPMON:$(TAP):TEMP") { +record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(DESC, "Temperature of magnet $(MAGNET) at $(TAP)") - field(INPA, "$(P)$(MAGNET):TEMPMON:$(TAP):RES") + field(INPA, "$(P)$(MAGNET):$(TAP):RES") field(INPB, "$(INITIAL_RES)") field(CALC, "(((A/B)-1)/0.004041)+23") -} \ No newline at end of file +} From 4ac449d98ce2de940a2d8f6455c330812a12666d Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:48:56 +0100 Subject: [PATCH 09/23] Set 2 digit precision to PVs --- rknmntrSup/RIKEN_TEMP_CALC.template | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 2688c80..68612c0 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -5,6 +5,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { field(DESC, "Raw Voltage at magnet $(MAGNET) at $(TAP)") field(INPA, "IN:RIKENFE:SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") #TODO use macro on instrument (on riken P will work) field(CALC, "A") + field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT:ADC") } @@ -14,6 +15,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { # The tap value is a signed 12-bit integer measured by the PLC ADC which # has a 10V reference. This needs to be converted back to a voltage field(CALC, "((A/((2**12)-1))*10)") + field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT") } @@ -24,6 +26,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { # The PLC measures the signal conditioned voltage and so needs to be divided # by a gain to get the actual voltage at the magnet terminals field(CALC, "A/B") + field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):RES") } @@ -32,6 +35,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(INPA, "$(P)$(MAGNET):$(TAP):VOLT") field(INPB, "IN:RIKENFE:CS:SB:$(MAGNET)_CURR") field(CALC, "(A/B)*1000") # Convert to milliohm + field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):TEMP") } @@ -40,4 +44,5 @@ record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(INPA, "$(P)$(MAGNET):$(TAP):RES") field(INPB, "$(INITIAL_RES)") field(CALC, "(((A/B)-1)/0.004041)+23") + field(PREC, "2") } From 449fdc4eb2d4830c18f07a4d3af85751aa8a1dd5 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:49:16 +0100 Subject: [PATCH 10/23] Substitute more magnets and taps --- rknmntrSup/RIKEN_TEMP_CALC.substitutions | 81 ++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.substitutions b/rknmntrSup/RIKEN_TEMP_CALC.substitutions index 033046f..e2a0f56 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.substitutions +++ b/rknmntrSup/RIKEN_TEMP_CALC.substitutions @@ -1,5 +1,86 @@ +# Macros: +# +# MAG - magnet name +# TAP - tap name +# GAIN - gain for the tap (needed for calculations) +# INITIAL_RES - initial resistance (needed for the calculations) + file RIKEN_TEMP_CALC.template { pattern { MAGNET, TAP, GAIN, INITIAL_RES } { "RQ1", "TAP01", "2", "7.7" } + { "RQ1", "TAP02", "2", "7.2" } + { "RQ1", "TAP03", "2", "7.1" } + { "RQ1", "TAP04", "2", "5.9" } + { "RQ1", "TAP05", "2", "6.0" } + { "RQ1", "TAP06", "2", "6.4" } + { "RQ1", "TAP07", "2", "6.5" } + { "RQ1", "TAP08", "2", "6.2" } + { "RQ1", "TAP09", "2", "5.8" } + { "RQ1", "TAP10", "2", "7.6" } + { "RQ1", "TAP11", "2", "7.0" } + { "RQ1", "TAP12", "2", "7.8" } + + { "RQ1", "TAP13", "2", "8.0" } + { "RQ1", "TAP14", "2", "6.9" } + { "RQ1", "TAP15", "2", "6.8" } + { "RQ1", "TAP16", "2", "6.5" } + { "RQ1", "TAP17", "2", "6.2" } + { "RQ1", "TAP18", "2", "6.1" } + { "RQ1", "TAP19", "2", "6.0" } + { "RQ1", "TAP20", "2", "6.4" } + { "RQ1", "TAP21", "2", "6.3" } + { "RQ1", "TAP22", "2", "6.8" } + { "RQ1", "TAP23", "2", "7.5" } + { "RQ1", "TAP24", "2", "7.5" } + + + { "RQ2", "TAP01", "5", "5.5" } + { "RQ2", "TAP02", "5", "3.7" } + { "RQ2", "TAP03", "5", "5.3" } + { "RQ2", "TAP04", "5", "3.8" } + { "RQ2", "TAP05", "5", "5.2" } + { "RQ2", "TAP06", "5", "4.8" } + { "RQ2", "TAP07", "5", "5.1" } + { "RQ2", "TAP08", "5", "4.9" } + { "RQ2", "TAP09", "5", "5.5" } + { "RQ2", "TAP10", "5", "5.1" } + { "RQ2", "TAP11", "5", "4.8" } + { "RQ2", "TAP12", "5", "5.3" } + + { "RQ2", "TAP13", "5", "3.8" } + { "RQ2", "TAP14", "5", "5.3" } + { "RQ2", "TAP15", "5", "3.7" } + { "RQ2", "TAP16", "5", "5.4" } + { "RQ2", "TAP17", "5", "6.1" } + { "RQ2", "TAP18", "5", "3.7" } + { "RQ2", "TAP19", "5", "5.3" } + { "RQ2", "TAP20", "5", "3.8" } + { "RQ2", "TAP21", "5", "5.2" } + { "RQ2", "TAP22", "5", "4.9" } + { "RQ2", "TAP23", "5", "5.0" } + { "RQ2", "TAP24", "5", "5.0" } + + { "RQ2", "TAP25", "5", "5.8" } + { "RQ2", "TAP26", "5", "5.0" } + { "RQ2", "TAP27", "5", "4.8" } + { "RQ2", "TAP28", "5", "5.2" } + { "RQ2", "TAP29", "5", "3.8" } + { "RQ2", "TAP30", "5", "5.4" } + { "RQ2", "TAP31", "5", "3.7" } + { "RQ2", "TAP32", "5", "5.4" } + + + { "RB1", "TAP01", "1.25", "16.0"} + { "RB1", "TAP02", "1.25", "16.0"} + { "RB1", "TAP03", "1.25", "16.1"} + { "RB1", "TAP04", "1.25", "16.0"} + { "RB1", "TAP05", "1.25", "16.1"} + { "RB1", "TAP06", "1.25", "16.0"} + { "RB1", "TAP07", "1.25", "16.0"} + { "RB1", "TAP08", "1.25", "16.1"} + { "RB1", "TAP09", "1.25", "16.0"} + { "RB1", "TAP10", "1.25", "16.1"} + { "RB1", "TAP11", "1.25", "16.0"} + { "RB1", "TAP12", "1.25", "16.0"} } From b0026dba5c79a92ac980f601b53c0861fc402fd5 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:55:24 +0100 Subject: [PATCH 11/23] Archive temperature PV value --- rknmntrSup/RIKEN_TEMP_CALC.template | 1 + 1 file changed, 1 insertion(+) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 68612c0..3ab042a 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -45,4 +45,5 @@ record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(INPB, "$(INITIAL_RES)") field(CALC, "(((A/B)-1)/0.004041)+23") field(PREC, "2") + info(archive, "VAL") } From 98dbb459785be50eb6bdd3ccf1ffbbdc53f9e6d6 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:59:37 +0100 Subject: [PATCH 12/23] Add units to PVs --- rknmntrSup/RIKEN_TEMP_CALC.template | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 3ab042a..5e4f032 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -16,6 +16,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { # has a 10V reference. This needs to be converted back to a voltage field(CALC, "((A/((2**12)-1))*10)") field(PREC, "2") + field(EGU, "V") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT") } @@ -27,6 +28,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { # by a gain to get the actual voltage at the magnet terminals field(CALC, "A/B") field(PREC, "2") + field(EGU, "V") field(FLNK, "$(P)$(MAGNET):$(TAP):RES") } @@ -36,6 +38,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(INPB, "IN:RIKENFE:CS:SB:$(MAGNET)_CURR") field(CALC, "(A/B)*1000") # Convert to milliohm field(PREC, "2") + field(EGU, "mOhm") field(FLNK, "$(P)$(MAGNET):$(TAP):TEMP") } @@ -45,5 +48,6 @@ record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(INPB, "$(INITIAL_RES)") field(CALC, "(((A/B)-1)/0.004041)+23") field(PREC, "2") + field(EGU, "C") info(archive, "VAL") } From 64fb6f2d9055b765c2cd55daa8c4f3bfc20c9629 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:47:00 +0100 Subject: [PATCH 13/23] Add disable to records --- rknmntrSup/Makefile | 3 ++- rknmntrSup/RIKEN_TEMP_CALC.template | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/rknmntrSup/Makefile b/rknmntrSup/Makefile index 2607764..d88ca66 100644 --- a/rknmntrSup/Makefile +++ b/rknmntrSup/Makefile @@ -3,7 +3,8 @@ include $(TOP)/configure/CONFIG #======================================= # Install .dbd and .db files +DB += rknmntr.db DB += RIKEN_TEMP_CALC.db -#TODO add sim and disable records + #======================================= include $(TOP)/configure/RULES diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 5e4f032..20adbd8 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -7,6 +7,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { field(CALC, "A") field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT:ADC") + field(SDIS, "$(P)DISABLE") } record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { @@ -18,6 +19,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { field(PREC, "2") field(EGU, "V") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT") + field(SDIS, "$(P)DISABLE") } record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { @@ -30,6 +32,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { field(PREC, "2") field(EGU, "V") field(FLNK, "$(P)$(MAGNET):$(TAP):RES") + field(SDIS, "$(P)DISABLE") } record(calc, "$(P)$(MAGNET):$(TAP):RES") { @@ -40,6 +43,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(PREC, "2") field(EGU, "mOhm") field(FLNK, "$(P)$(MAGNET):$(TAP):TEMP") + field(SDIS, "$(P)DISABLE") } record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { @@ -50,4 +54,5 @@ record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(PREC, "2") field(EGU, "C") info(archive, "VAL") + field(SDIS, "$(P)DISABLE") } From d2decb0e2a2c93d27dc6bfe068a49e05dd5d778c Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:47:16 +0100 Subject: [PATCH 14/23] Remove SIM record --- rknmntrSup/rknmntr.db | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/rknmntrSup/rknmntr.db b/rknmntrSup/rknmntr.db index 4c7f7b3..a737e7f 100644 --- a/rknmntrSup/rknmntr.db +++ b/rknmntrSup/rknmntr.db @@ -1,13 +1,3 @@ -record(bo, "$(P)SIM") -{ - field(SCAN, "Passive") - field(DTYP, "Soft Channel") - field(ZNAM, "NO") - field(ONAM, "YES") - field(VAL, "$(RECSIM=0)") - field(PINI, "YES") -} - record(bo, "$(P)DISABLE") { field(DESC, "Disable comms") From 282bcd7006ef54ee3e0ab27bea0d3d7455cbd28f Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 2 Oct 2023 16:13:27 +0100 Subject: [PATCH 15/23] Use P macro instead of hardcoded machine prefix --- rknmntrSup/RIKEN_TEMP_CALC.template | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 20adbd8..f9a0f39 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -3,7 +3,8 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { field(DESC, "Raw Voltage at magnet $(MAGNET) at $(TAP)") - field(INPA, "IN:RIKENFE:SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") #TODO use macro on instrument (on riken P will work) + # This below only works if P prefix is the same machine as the one running SCHNDR IOC (must be RIKENFE) + field(INPA, "$(P)SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") field(CALC, "A") field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT:ADC") @@ -38,7 +39,8 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(DESC, "Resistance at magnet $(MAGNET) at $(TAP)") field(INPA, "$(P)$(MAGNET):$(TAP):VOLT") - field(INPB, "IN:RIKENFE:CS:SB:$(MAGNET)_CURR") + # This PV below references the block corresponding to magnet so it depends on correct block configuration + field(INPB, "$(P)CS:SB:$(MAGNET)_CURR") field(CALC, "(A/B)*1000") # Convert to milliohm field(PREC, "2") field(EGU, "mOhm") From 2cbf96363f6dae59683222b96ffb83732e31dc85 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Tue, 3 Oct 2023 15:43:45 +0100 Subject: [PATCH 16/23] Add simple tests --- system_tests/tests/rknmntr.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/system_tests/tests/rknmntr.py b/system_tests/tests/rknmntr.py index 9c3b167..1ff4575 100644 --- a/system_tests/tests/rknmntr.py +++ b/system_tests/tests/rknmntr.py @@ -19,8 +19,13 @@ ] -TEST_MODES = [TestModes.RECSIM, TestModes.DEVSIM] +TEST_MODES = [TestModes.RECSIM] +MAGNET_TAP_PAIRS = { + "RQ1": [i for i in range(1, 25)], + "RQ2": [i for i in range(1, 25)], + "RB1": [i for i in range(1, 13)], +} class RknmntrTests(unittest.TestCase): """ @@ -30,5 +35,15 @@ def setUp(self): self._lewis, self._ioc = get_running_lewis_and_ioc("Rknmntr", DEVICE_PREFIX) self.ca = ChannelAccess(device_prefix=DEVICE_PREFIX) - def test_that_fails(self): - self.fail("You haven't implemented any tests!") + def _get_pv_for_magnet_tap(self, magnet, tap): + return f"{magnet}:TAP{tap:02d}:" + + def test_GIVEN_ioc_running_THEN_all_pvs_exist(self): + for magnet in MAGNET_TAP_PAIRS: + for tap in MAGNET_TAP_PAIRS[magnet]: + pv_magnet_tap = self._get_pv_for_magnet_tap(magnet, tap) + self.ca.assert_that_pv_exists(f"{pv_magnet_tap}VOLT:RAW") + self.ca.assert_that_pv_exists(f"{pv_magnet_tap}VOLT:ADC") + self.ca.assert_that_pv_exists(f"{pv_magnet_tap}VOLT") + self.ca.assert_that_pv_exists(f"{pv_magnet_tap}RES") + self.ca.assert_that_pv_exists(f"{pv_magnet_tap}TEMP") From 169fff3889655042634b44ee245ccccb88780633 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Tue, 3 Oct 2023 15:44:41 +0100 Subject: [PATCH 17/23] Add deault value 0 to all calculations --- rknmntrSup/RIKEN_TEMP_CALC.template | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index f9a0f39..24016af 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -3,6 +3,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { field(DESC, "Raw Voltage at magnet $(MAGNET) at $(TAP)") + field(VAL, 0) # This below only works if P prefix is the same machine as the one running SCHNDR IOC (must be RIKENFE) field(INPA, "$(P)SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") field(CALC, "A") @@ -13,6 +14,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { field(DESC, "Digital Voltage at magnet $(MAGNET) at $(TAP)") + field(VAL, 0) field(INPA, "$(P)$(MAGNET):$(TAP):VOLT:RAW") # The tap value is a signed 12-bit integer measured by the PLC ADC which # has a 10V reference. This needs to be converted back to a voltage @@ -25,6 +27,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:ADC") { record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { field(DESC, "Actual Voltage at magnet $(MAGNET) at $(TAP)") + field(VAL, 0) field(INPA, "$(P)$(MAGNET):$(TAP):VOLT:ADC") field(INPB, "$(GAIN)") # The PLC measures the signal conditioned voltage and so needs to be divided @@ -38,6 +41,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(DESC, "Resistance at magnet $(MAGNET) at $(TAP)") + field(VAL, 0) field(INPA, "$(P)$(MAGNET):$(TAP):VOLT") # This PV below references the block corresponding to magnet so it depends on correct block configuration field(INPB, "$(P)CS:SB:$(MAGNET)_CURR") @@ -50,6 +54,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):RES") { record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(DESC, "Temperature of magnet $(MAGNET) at $(TAP)") + field(VAL, 0) field(INPA, "$(P)$(MAGNET):$(TAP):RES") field(INPB, "$(INITIAL_RES)") field(CALC, "(((A/B)-1)/0.004041)+23") From f98e0510d18c4cd93a1bf71237596857e81972ac Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Tue, 3 Oct 2023 15:45:24 +0100 Subject: [PATCH 18/23] Safeguard against dividing by 0 --- rknmntrSup/RIKEN_TEMP_CALC.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index 24016af..a3b7a2e 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -32,7 +32,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT") { field(INPB, "$(GAIN)") # The PLC measures the signal conditioned voltage and so needs to be divided # by a gain to get the actual voltage at the magnet terminals - field(CALC, "A/B") + field(CALC, "(B#0)?A/B:0") field(PREC, "2") field(EGU, "V") field(FLNK, "$(P)$(MAGNET):$(TAP):RES") @@ -45,7 +45,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(INPA, "$(P)$(MAGNET):$(TAP):VOLT") # This PV below references the block corresponding to magnet so it depends on correct block configuration field(INPB, "$(P)CS:SB:$(MAGNET)_CURR") - field(CALC, "(A/B)*1000") # Convert to milliohm + field(CALC, "(B#0)?(A/B)*1000:0") # Convert to milliohm field(PREC, "2") field(EGU, "mOhm") field(FLNK, "$(P)$(MAGNET):$(TAP):TEMP") @@ -57,7 +57,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):TEMP") { field(VAL, 0) field(INPA, "$(P)$(MAGNET):$(TAP):RES") field(INPB, "$(INITIAL_RES)") - field(CALC, "(((A/B)-1)/0.004041)+23") + field(CALC, "(A#0&&B#0)?(((A/B)-1)/0.004041)+23:0") field(PREC, "2") field(EGU, "C") info(archive, "VAL") From 732b410dd06b5d6b29a9d2eb1a8f2a136adddd3e Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:37:03 +0100 Subject: [PATCH 19/23] correct prefix for other ioc access --- rknmntrSup/RIKEN_TEMP_CALC.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rknmntrSup/RIKEN_TEMP_CALC.template b/rknmntrSup/RIKEN_TEMP_CALC.template index a3b7a2e..bb73b6e 100644 --- a/rknmntrSup/RIKEN_TEMP_CALC.template +++ b/rknmntrSup/RIKEN_TEMP_CALC.template @@ -5,7 +5,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):VOLT:RAW") { field(DESC, "Raw Voltage at magnet $(MAGNET) at $(TAP)") field(VAL, 0) # This below only works if P prefix is the same machine as the one running SCHNDR IOC (must be RIKENFE) - field(INPA, "$(P)SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") + field(INPA, "$(HOST)SCHNDR_01:$(MAGNET):TEMPMON:$(TAP) CP") field(CALC, "A") field(PREC, "2") field(FLNK, "$(P)$(MAGNET):$(TAP):VOLT:ADC") @@ -44,7 +44,7 @@ record(calc, "$(P)$(MAGNET):$(TAP):RES") { field(VAL, 0) field(INPA, "$(P)$(MAGNET):$(TAP):VOLT") # This PV below references the block corresponding to magnet so it depends on correct block configuration - field(INPB, "$(P)CS:SB:$(MAGNET)_CURR") + field(INPB, "$(HOST)CS:SB:$(MAGNET)_CURR") field(CALC, "(B#0)?(A/B)*1000:0") # Convert to milliohm field(PREC, "2") field(EGU, "mOhm") From 1898f613af0208e91d70a65a74cfd8dbdd1d09ae Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:39:28 +0100 Subject: [PATCH 20/23] add tests and fallback pvs --- rknmntrSup/Makefile | 2 + rknmntrSup/test_PSU_PVs.substitutions | 79 ++++++++++++++++++++ rknmntrSup/test_PSU_PVs.template | 6 ++ rknmntrSup/test_block_curr_PVs.substitutions | 7 ++ rknmntrSup/test_block_curr_PVs.template | 4 + system_tests/tests/rknmntr.py | 54 ++++++++++++- 6 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 rknmntrSup/test_PSU_PVs.substitutions create mode 100644 rknmntrSup/test_PSU_PVs.template create mode 100644 rknmntrSup/test_block_curr_PVs.substitutions create mode 100644 rknmntrSup/test_block_curr_PVs.template diff --git a/rknmntrSup/Makefile b/rknmntrSup/Makefile index d88ca66..11d94da 100644 --- a/rknmntrSup/Makefile +++ b/rknmntrSup/Makefile @@ -5,6 +5,8 @@ include $(TOP)/configure/CONFIG # Install .dbd and .db files DB += rknmntr.db DB += RIKEN_TEMP_CALC.db +DB += test_PSU_PVs.db +DB += test_block_curr_PVs.db #======================================= include $(TOP)/configure/RULES diff --git a/rknmntrSup/test_PSU_PVs.substitutions b/rknmntrSup/test_PSU_PVs.substitutions new file mode 100644 index 0000000..39e1964 --- /dev/null +++ b/rknmntrSup/test_PSU_PVs.substitutions @@ -0,0 +1,79 @@ +file test_PSU_PVs.template { + pattern { MAGNET, TAP } + + { "RQ1", "TAP01" } + { "RQ1", "TAP02" } + { "RQ1", "TAP03" } + { "RQ1", "TAP04" } + { "RQ1", "TAP05" } + { "RQ1", "TAP06" } + { "RQ1", "TAP07" } + { "RQ1", "TAP08" } + { "RQ1", "TAP09" } + { "RQ1", "TAP10" } + { "RQ1", "TAP11" } + { "RQ1", "TAP12" } + + { "RQ1", "TAP13" } + { "RQ1", "TAP14" } + { "RQ1", "TAP15" } + { "RQ1", "TAP16" } + { "RQ1", "TAP17" } + { "RQ1", "TAP18" } + { "RQ1", "TAP19" } + { "RQ1", "TAP20" } + { "RQ1", "TAP21" } + { "RQ1", "TAP22" } + { "RQ1", "TAP23" } + { "RQ1", "TAP24" } + + + { "RQ2", "TAP01" } + { "RQ2", "TAP02" } + { "RQ2", "TAP03" } + { "RQ2", "TAP04" } + { "RQ2", "TAP05" } + { "RQ2", "TAP06" } + { "RQ2", "TAP07" } + { "RQ2", "TAP08" } + { "RQ2", "TAP09" } + { "RQ2", "TAP10" } + { "RQ2", "TAP11" } + { "RQ2", "TAP12" } + + { "RQ2", "TAP13" } + { "RQ2", "TAP14" } + { "RQ2", "TAP15" } + { "RQ2", "TAP16" } + { "RQ2", "TAP17" } + { "RQ2", "TAP18" } + { "RQ2", "TAP19" } + { "RQ2", "TAP20" } + { "RQ2", "TAP21" } + { "RQ2", "TAP22" } + { "RQ2", "TAP23" } + { "RQ2", "TAP24" } + + { "RQ2", "TAP25" } + { "RQ2", "TAP26" } + { "RQ2", "TAP27" } + { "RQ2", "TAP28" } + { "RQ2", "TAP29" } + { "RQ2", "TAP30" } + { "RQ2", "TAP31" } + { "RQ2", "TAP32" } + + + { "RB1", "TAP01" } + { "RB1", "TAP02" } + { "RB1", "TAP03" } + { "RB1", "TAP04" } + { "RB1", "TAP05" } + { "RB1", "TAP06" } + { "RB1", "TAP07" } + { "RB1", "TAP08" } + { "RB1", "TAP09" } + { "RB1", "TAP10" } + { "RB1", "TAP11" } + { "RB1", "TAP12" } +} diff --git a/rknmntrSup/test_PSU_PVs.template b/rknmntrSup/test_PSU_PVs.template new file mode 100644 index 0000000..459358e --- /dev/null +++ b/rknmntrSup/test_PSU_PVs.template @@ -0,0 +1,6 @@ +# Dummy records for testing $(MAGNET), $(TAP) + +record(ai, "$(P)SCHNDR_01:$(MAGNET):TEMPMON:$(TAP)") { + field(DESC, "Dummy PV for testing") +} + diff --git a/rknmntrSup/test_block_curr_PVs.substitutions b/rknmntrSup/test_block_curr_PVs.substitutions new file mode 100644 index 0000000..185ff1c --- /dev/null +++ b/rknmntrSup/test_block_curr_PVs.substitutions @@ -0,0 +1,7 @@ +file test_block_curr_PVs.template { + pattern { MAGNET } + + { "RQ1" } + { "RQ2" } + { "RB1" } +} diff --git a/rknmntrSup/test_block_curr_PVs.template b/rknmntrSup/test_block_curr_PVs.template new file mode 100644 index 0000000..4921518 --- /dev/null +++ b/rknmntrSup/test_block_curr_PVs.template @@ -0,0 +1,4 @@ + +record(ai, "$(P)CS:SB:$(MAGNET)_CURR") { + field(DESC, "Dummy PV for testing") +} diff --git a/system_tests/tests/rknmntr.py b/system_tests/tests/rknmntr.py index 1ff4575..c2c49eb 100644 --- a/system_tests/tests/rknmntr.py +++ b/system_tests/tests/rknmntr.py @@ -3,8 +3,10 @@ from utils.channel_access import ChannelAccess from utils.ioc_launcher import get_default_ioc_dir from utils.test_modes import TestModes -from utils.testing import get_running_lewis_and_ioc, skip_if_recsim +from utils.testing import get_running_lewis_and_ioc, parameterized_list +from parameterized import parameterized +import random DEVICE_PREFIX = "RKNMNTR_01" @@ -22,9 +24,9 @@ TEST_MODES = [TestModes.RECSIM] MAGNET_TAP_PAIRS = { - "RQ1": [i for i in range(1, 25)], - "RQ2": [i for i in range(1, 25)], - "RB1": [i for i in range(1, 13)], + "RQ1": [f"TAP{i:02d}" for i in range(1, 25)], + "RQ2": [f"TAP{i:02d}" for i in range(1, 25)], + "RB1": [f"TAP{i:02d}" for i in range(1, 13)], } class RknmntrTests(unittest.TestCase): @@ -37,6 +39,7 @@ def setUp(self): def _get_pv_for_magnet_tap(self, magnet, tap): return f"{magnet}:TAP{tap:02d}:" + def test_GIVEN_ioc_running_THEN_all_pvs_exist(self): for magnet in MAGNET_TAP_PAIRS: @@ -47,3 +50,46 @@ def test_GIVEN_ioc_running_THEN_all_pvs_exist(self): self.ca.assert_that_pv_exists(f"{pv_magnet_tap}VOLT") self.ca.assert_that_pv_exists(f"{pv_magnet_tap}RES") self.ca.assert_that_pv_exists(f"{pv_magnet_tap}TEMP") + + @parameterized.expand(parameterized_list([ + # Magnet, gain, volt_raw + ("RQ1", 10), + # ("RQ2", 10), + # ("RB1", 10), + ])) + def test_WHEN_voltage_changes_THEN_values_recalculated(self, _, magnet, volt_raw): + self.ca.prefix = self.ca.host_prefix + + pv_magnet_curr = f"CS:SB:{magnet}_CURR" + self.ca.set_pv_value(pv_magnet_curr, 1) + + for tap in MAGNET_TAP_PAIRS[magnet]: + volt_raw = random.randrange(10, 100) + + # WHEN + # Simulate a change in tap voltage + pv = f"SCHNDR_01:{magnet}:TEMPMON:{tap}" + self.ca.set_pv_value(pv, volt_raw) + + pv_magnet_tap = f"RKNMNTR_01:{magnet}:{tap}:" + pv_raw = f"{pv_magnet_tap}VOLT:RAW" + pv_volt_adc = f"{pv_magnet_tap}VOLT:ADC" + pv_volt = f"{pv_magnet_tap}VOLT" + pv_res = f"{pv_magnet_tap}RES" + pv_temp = f"{pv_magnet_tap}TEMP" + + gain = self.ca.get_pv_value(f"{pv_volt}.B") # Retrieve gain for magnet from calc record B field (loaded in there from macro) + curr = self.ca.get_pv_value(pv_magnet_curr) + initial_res = self.ca.get_pv_value(f"{pv_temp}.B") # Retrieve initial resistance for magnet from calc record B field (loaded in there from macro) + + expected_volt_adc = volt_raw / ((2**12)-1)*10 + expected_volt = expected_volt_adc / gain + expected_res = expected_volt / curr * 1000 + expected_temp = (((expected_res / initial_res) - 1) / 0.004041) + 23 + + # ASSERT + self.ca.assert_that_pv_is(pv_raw, volt_raw) + self.ca.assert_that_pv_is(pv_volt_adc, expected_volt_adc) + self.ca.assert_that_pv_is(pv_volt, expected_volt) + self.ca.assert_that_pv_is(pv_res, expected_res) + self.ca.assert_that_pv_is(pv_temp, expected_temp) From 4b4cd33cf5362151ac26473b398c345591c62e62 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:19:53 +0100 Subject: [PATCH 21/23] Refine randomised voltage test --- system_tests/tests/rknmntr.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/system_tests/tests/rknmntr.py b/system_tests/tests/rknmntr.py index c2c49eb..73f2616 100644 --- a/system_tests/tests/rknmntr.py +++ b/system_tests/tests/rknmntr.py @@ -52,22 +52,20 @@ def test_GIVEN_ioc_running_THEN_all_pvs_exist(self): self.ca.assert_that_pv_exists(f"{pv_magnet_tap}TEMP") @parameterized.expand(parameterized_list([ - # Magnet, gain, volt_raw - ("RQ1", 10), - # ("RQ2", 10), - # ("RB1", 10), + "RQ1", "RQ2", "RB1" ])) - def test_WHEN_voltage_changes_THEN_values_recalculated(self, _, magnet, volt_raw): + def test_WHEN_raw_voltage_THEN_values_calculated(self, _, magnet): + # Remove IOC prefix from prefix, leaving only the host machine prefix self.ca.prefix = self.ca.host_prefix + # Set magnet current to a non-zero value pv_magnet_curr = f"CS:SB:{magnet}_CURR" self.ca.set_pv_value(pv_magnet_curr, 1) for tap in MAGNET_TAP_PAIRS[magnet]: - volt_raw = random.randrange(10, 100) - # WHEN - # Simulate a change in tap voltage + # Simulate a raw voltage on each tap + volt_raw = random.randrange(10, 1000) pv = f"SCHNDR_01:{magnet}:TEMPMON:{tap}" self.ca.set_pv_value(pv, volt_raw) @@ -88,6 +86,7 @@ def test_WHEN_voltage_changes_THEN_values_recalculated(self, _, magnet, volt_raw expected_temp = (((expected_res / initial_res) - 1) / 0.004041) + 23 # ASSERT + # That calculations all happen self.ca.assert_that_pv_is(pv_raw, volt_raw) self.ca.assert_that_pv_is(pv_volt_adc, expected_volt_adc) self.ca.assert_that_pv_is(pv_volt, expected_volt) From bd184b0b19c1f8f36acc2685e45706e81ea03987 Mon Sep 17 00:00:00 2001 From: Zsolt Kebel <25386639+zsoltkebel@users.noreply.github.com> Date: Tue, 10 Oct 2023 14:20:30 +0100 Subject: [PATCH 22/23] Fix magnet tap pv method --- system_tests/tests/rknmntr.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/system_tests/tests/rknmntr.py b/system_tests/tests/rknmntr.py index 73f2616..5b145e6 100644 --- a/system_tests/tests/rknmntr.py +++ b/system_tests/tests/rknmntr.py @@ -38,9 +38,8 @@ def setUp(self): self.ca = ChannelAccess(device_prefix=DEVICE_PREFIX) def _get_pv_for_magnet_tap(self, magnet, tap): - return f"{magnet}:TAP{tap:02d}:" + return f"{magnet}:{tap}:" - def test_GIVEN_ioc_running_THEN_all_pvs_exist(self): for magnet in MAGNET_TAP_PAIRS: for tap in MAGNET_TAP_PAIRS[magnet]: From 40ae575fe47c8c8161b6bc7e69afbb4ee6952194 Mon Sep 17 00:00:00 2001 From: esmith1729 <131008854+esmith1729@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:24:38 +0100 Subject: [PATCH 23/23] Add comment to explain magic numbers in rknmntr.py --- system_tests/tests/rknmntr.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system_tests/tests/rknmntr.py b/system_tests/tests/rknmntr.py index 5b145e6..764407e 100644 --- a/system_tests/tests/rknmntr.py +++ b/system_tests/tests/rknmntr.py @@ -79,6 +79,8 @@ def test_WHEN_raw_voltage_THEN_values_calculated(self, _, magnet): curr = self.ca.get_pv_value(pv_magnet_curr) initial_res = self.ca.get_pv_value(f"{pv_temp}.B") # Retrieve initial resistance for magnet from calc record B field (loaded in there from macro) + #These calculations convert raw/analogue voltages into digital. The conversion calculations were provided by instrument scientists, + #and can be found here: https://github.com/ISISComputingGroup/IBEX/issues/7975 expected_volt_adc = volt_raw / ((2**12)-1)*10 expected_volt = expected_volt_adc / gain expected_res = expected_volt / curr * 1000