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.
+
+ - 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.
+ - 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:
+
+ - If you are building your application database definition file from
+ an xxxInclude.dbd file you include the additional database
+ definitions in that file:
+ include "base.dbd"
+ include "stream.dbd"
+ include "drvAsynIPPort.dbd"
+ - If you are building your application database definition file from
+ the application Makefile you specify the aditional database
+ definitions there:
+ xxx_DBD += base.dbd
+ xxx_DBD += stream.dbd
+ xxx_DBD += drvAsynIPPort.dbd
+
+
+ - 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.
+ - 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.
+
+
+Installation and Building
+After obtaining a copy of the distribution, it must be installed and built
+for use at your site.
+
+ - Create an installation directory for the module. The path name
+ of this directory should end with modules/instrument/rknmntr.
+ - Place the distribution file into this directory.
+ - 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.
+
+ - Edit the configure/RELEASE file and set the paths to your
+ installation of EPICS base, stream and ASYN support modules.
+ - Execute make in the top level directory.
+
+
+
+
+
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