diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..aa7f457 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,49 @@ +name: Docker-Image-Build-Publish +on: + push: + branches: + #- 'main' + - 'dev' + tags: + - 'v*' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2 + - + name: Docker metadata + id: meta + uses: docker/metadata-action@v3 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + - + name: Login to ghcr + uses: docker/login-action@v1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - + name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 0000000..d601a07 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,69 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Python package +on: + pull_request: + branches: [ dev ] + #push: + # branches: + # - 'dev' + #push: + # branches : 'dev' + +jobs: + build: + runs-on: ubuntu-latest + # for self-hosted: + # runs-on: [self-hosted, linux, X64] + strategy: + matrix: + python-version: [3.9.12] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Upgrade pip + run: | + python3 -m pip install --upgrade pip + python3 -m pip --version + - name: Print environment + run: | + env + - name: Install dependencies + run: | + python3 -m pip install -U black + python3 -m pip install -r requirements/local.txt + python3 -m pip install -e . + + - name: Docker-compose start mqtt + run: | + cd docker/tedd_caen_hvps + pwd + echo "---------------------" + ls + echo $HOME + docker-compose up -d + docker-compose ps -a + cd - + - name: Run black --check . + run: black --check . --exclude _actions + #- name: Test with pytest + # run: | + # cd unittests + # python3 -m pip install pytest-cov + # python3 -m pytest --cov=../ --cov-report=xml + # ls + #- name: Upload coverage to Codecov + # uses: codecov/codecov-action@v3 + # with: + # directory: ./unittests + # env_vars: OS,PYTHON + # fail_ci_if_error: true + # flags: unittests + # name: codecov-umbrella + # # path_to_write_report: ./coverage/codecov_report.txt + # verbose: true + \ No newline at end of file diff --git a/.gitignore b/.gitignore index 94770fb..9f336a0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ dist/ downloads/ eggs/ .eggs/ -lib/ +#lib/ lib64/ parts/ sdist/ diff --git a/Dockerfile b/Dockerfile index fab1620..7ab38e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,7 @@ -FROM --platform=linux/amd64 centos:centos7 +FROM centos:centos7 +#for Mac m1 --> +#FROM --platform=linux/amd64 centos:centos7 + # Update packages and install tools WORKDIR /usr/app @@ -12,42 +15,28 @@ RUN yum install -y java-11-openjdk java-11-openjdk-devel RUN yum install -y wget -#RUN apt-get update && apt-get install -y --no-install-recommends apt-utils - -#WORKDIR /usr/local/lib -#COPY caenlib/CAENHVWrapper-6.3 ./CAENHVWrapper-6.3 -#WORKDIR /usr/local/lib/CAENHVWrapper-6.3/ -#RUN cd CAENHVWrapper-6.3/ - +WORKDIR /usr/app/caen_hvps/ +COPY caen_hvps/hvps . # install dependencies COPY requirements ./requirements - RUN python3 -m pip install --no-cache-dir -r requirements/docker.txt -COPY caenlib ./caenlib -WORKDIR /usr/app/caenlib/ +COPY caen_hvps/caenlib ./caenlib +WORKDIR /usr/app/caen_hvps/caenlib/ RUN tar -xzf CAENHVWrapper-6.3.tgz RUN rm CAENHVWrapper-6.3.tgz -RUN unzip CAEN_HVPSS_ChannelsController.zip -RUN rm CAEN_HVPSS_ChannelsController.zip +WORKDIR /usr/app/caen_hvps/caenlib/CAENHVWrapper-6.3/ +RUN ./install.sh && \ + rm *.txt && \ + rm -rf HVWrapperDemo/ -WORKDIR /usr/app/caenlib/CAENHVWrapper-6.3/ -RUN pwd && ls +#WORKDIR /usr/lib +#CMD pwd && ls +#RUN ldconfig -l libcaenhvwrapper.so.6.3 +#RUN export LD_LIBRARY_PATH="/usr/lib" -RUN ./install.sh -RUN rm *.txt -RUN rm -rf HVWrapperDemo/ -RUN pwd && ls +ENV LD_LIBRARY_PATH="/usr/lib" - - -WORKDIR /usr/lib -CMD pwd && ls -RUN ldconfig -l libcaenhvwrapper.so.6.3 -RUN export LD_LIBRARY_PATH="/usr/lib" - -WORKDIR /usr/app -COPY hvps ./hvps -WORKDIR /usr/app/hvps/ \ No newline at end of file +WORKDIR /usr/app/caen_hvps/ \ No newline at end of file diff --git a/README.md b/README.md index b47e5bb..528e69b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,97 @@ # caen_hvps -integrate caen power supply to tracker dcs +integrate caen SY4527 power supply to tracker dcs +Interface to control CAEN power supplies using a python wrapper to the CAEN C API + +## CAEN prerequisite +In order to use the CAEN power supplies it is necessary to install the CAEN HV Wrapper Library: + +CAENHVWRAPPER https://www.caen.it/download/?filter=CAEN%20HV%20Wrapper%20Library +You need to signup to download. + +CAEN HV Wrapper is a set of ANSI C functions which allows to control CAEN devices. It contains a generic software interface independent by the Power Supply models and by the communication path used to exchange data with them. + +### caenlib +Detalied information can be found in CAENHVWrapper-6.3/CAENHVWrapperReadme.txt +To install the necessary libraries execute: + + ./install.sh + +The installation copies and installs the library in /usr/lib, and installs it in the work directory. + +### hvps + lib/caen.py : Contains CAEN controller class. Provide low level wrapper for CAEN's c-api via Python's cdll functionality and is accessed via hvps.py + + lib/hvps.py : Contains a class of objects that represent all the channels for the HVPS and provides a nicer interface to the CAEN C-wrapper and should be used for all programatic iteractions with the power supply + + hvps_ctrl.py : Main interface to the control software. Handles all user interactions + + hvps.cfg : CAEN HV modules can be setup automatically using a configuration file. + + * Global Section : + Should be defined + * max_bias_voltage + * max_ramp_rate : max_ramp_rate V/sec, probably want to keep this under <=50 + * default_slot (Mandatory): slot number where the boards are located + + * Power supply section : Contains Mandatory informations: + * Hostname or IP address + * username and password + * system_type : CAENHV_BOARD_TYPE (SY4527) for our case it should be 2 + * link_type : CAENHV_LINK_TYPE if TCP/IP then it should be 0 + + * Channels section: All channels must start with CH_. should be defined the following info for each channel; + * channel_num (Mandatory) + * chanel enable/disable (Mandatory) + * max_bias_voltage + * ramp_rate + +### Dockerfile +Create an image and Install all the necessary tools. + +#### Build Docker image + + docker build -t tedd_caen_hvps:centos7 . + + +##### To run the image as a container: + + docker run -it --name=caen_hvps tedd_caen_hvps:centos7 bash + + +###### To run the python file inside the container: + +1- To check the status of the specific channel e.g: channel 0 : + + python3 hvps_ctrl.py --status --chan 0 + + +You will see the following statement: + + Could get the IP address for the hostname :%s 10.2.2.20 + Initilizing HVPS... + DEBUG_INIT::::: admin admin b'10.2.2.20' 10.2.2.20 ds-hvps 2 0 + Initialized Connection to : 10.2.2.20 + communicating with HVPS, check SLOT # and Channel #, IP : b'10.2.2.20', ERROR code : 0x0 + Slot: 4 | Channel Name: LV_1-0 | Channel#: 0 | V0Set : 5.0 | I0Set : 1.1 | RUpTime : 100.0 | RDwTime : 100.0 | Trip : 0.1 | UNVThr : 0.0 | OVVThr : 7.0 | VMon : 0.0 | VCon : 0.4 | IMon : 0.0 | Temp : 0.0 | Pw : 0.0 | TripInt : 0.0 | TripExt : 0.0 | ChToGroup : 0.0 | OnGrDel : 0.0 | Status : Off + + +2- Other parameters: V0Set / RumpDown / Rump Up / Trip / etc.: + + --param V0Set: + + python3 hvps_ctrl.py --action set_param --param V0Set --param_value 6 --chan 1 + + --param RDWn: + + python3 hvps_ctrl.py --action set_param --param RDWn --param_value 40 --chan 0 + + --param RUp: + + python3 hvps_ctrl.py --action set_param --param RUp --param_value 50 --chan 0 + + + --param Trip: + + python3 hvps_ctrl.py --action set_param --param Trip --param_value 0.5 --chan 0 + + diff --git a/caenlib/CAENHVWrapper-6.3.tgz b/caen_hvps/caenlib/CAENHVWrapper-6.3.tgz similarity index 100% rename from caenlib/CAENHVWrapper-6.3.tgz rename to caen_hvps/caenlib/CAENHVWrapper-6.3.tgz diff --git a/caenlib/CAEN_HVPSS_ChannelsController.zip b/caen_hvps/caenlib/CAEN_HVPSS_ChannelsController.zip similarity index 100% rename from caenlib/CAEN_HVPSS_ChannelsController.zip rename to caen_hvps/caenlib/CAEN_HVPSS_ChannelsController.zip diff --git a/caenlib/ChannelsController.jar b/caen_hvps/caenlib/ChannelsController.jar similarity index 100% rename from caenlib/ChannelsController.jar rename to caen_hvps/caenlib/ChannelsController.jar diff --git a/caenlib/README.txt b/caen_hvps/caenlib/README.txt similarity index 100% rename from caenlib/README.txt rename to caen_hvps/caenlib/README.txt diff --git a/caen_hvps/caenlib/lib/CAENHVWrapper.jar b/caen_hvps/caenlib/lib/CAENHVWrapper.jar new file mode 100644 index 0000000..6be5627 Binary files /dev/null and b/caen_hvps/caenlib/lib/CAENHVWrapper.jar differ diff --git a/caen_hvps/caenlib/lib/JTattoo.jar b/caen_hvps/caenlib/lib/JTattoo.jar new file mode 100644 index 0000000..7a793ee Binary files /dev/null and b/caen_hvps/caenlib/lib/JTattoo.jar differ diff --git a/caen_hvps/hvps/hvps.cfg b/caen_hvps/hvps/hvps.cfg new file mode 100644 index 0000000..d1fe074 --- /dev/null +++ b/caen_hvps/hvps/hvps.cfg @@ -0,0 +1,30 @@ +# Global Section +#max_bias_voltage = 10 +# max_ramp_rate V/sec, probably want to keep this under <=50 +#max_ramp_rate = 5 +default_slot = 9 #(slot4: LV channels/ slot9 :HV channels ) +default_hvps = HVPS_SY4527 + +# All power supplies must start with HVPS_ +[HVPS_SY4527] +device_name = SY4527 +system_type = 2 #BOARD_TYPE: SY4527 = 2 +link_type = 0 #TCP/IP +# This can be a hostname or an IP address +hostname = 192.168.1.210 +# Leave username and password blank if your unit does not have these values +username = admin +password = admin + + # All channels must start with CH_ + [[CH_0]] + channel_num = 0 + Enabled = True + #max_bias_voltage = 10 + #ramp_rate = 5 + + [[CH_1]] + channel_num = 1 + Enabled = True + #max_bias_voltage = 10 + #ramp_rate = 5 diff --git a/caen_hvps/hvps/hvps_ctrl.py b/caen_hvps/hvps/hvps_ctrl.py new file mode 100755 index 0000000..28c2ede --- /dev/null +++ b/caen_hvps/hvps/hvps_ctrl.py @@ -0,0 +1,599 @@ +#!/usr/bin/env python3 + +# ************************************************************************************* +# By: Jon Ringuette +# Created: March 23 2020 - During the great plague +# Purpose: Provide a wrapper for CAEN's C library to control the CAEN HVPS which biases +# the HPGe's (8pi's and ULGe) +# CAEN manaul and c-api : https://www.caen.it/products/caen-hv-wrapper-library/ +# ************************************************************************************* + +import argparse +import sys +import time +from os.path import exists + +from configobj import ConfigObj + +from lib.hvps import ( + HVPS_Class, +) # Class that contains high level wrapper functions for the HVPS, + +# import mqtt as my_mqtt +import paho.mqtt.client as mqtt + +# ************************************************************************************* +# process_config_file: +# Process config file using the configparser library +# ************************************************************************************* +class hvps_ctrl: + def __init__(self, config_dict, args, my_slot): + self.config_dict = config_dict + self.my_slot = my_slot + self.args = args + self.default_hvps_key = None + self.HVPS = [] + self.channel_selected = args.channel_selected + self.hvps_name = args.hvps_name + self.iset_current = 0 + self.vset_current = 0 + for mykey in self.config_dict.keys(): + if mykey.startswith("HVPS_"): + self.default_hvps_key = mykey + self.HVPS.append(HVPS_Class(self.config_dict[mykey])) + + if len(self.HVPS) == 0: + print("Could not find HVPS entry in config file.") + exit(1) + # self.force = self.args.force + self.force = getattr(args, "force", False) + self.channel_entry = ( + self.find_channel_in_config() + ) # Get the config entry for channel + + def confirm_channel(self, action, new_voltage): + if self.force is True: + return True + # confirm_channel: Prompt user to confirm a change to the voltage applied to a channel, requires a 'yes' or 'no' answer + channel_status_list = self.HVPS[0].status_channel( + None, self.my_slot, int(self.channel_entry["chan_num"]) + ) + # Iterate over the status of channels until reaching the VSet parameter we're looking for which is the current voltage + current_voltage = int( + next( + item + for item in channel_status_list[0][0]["chan_info"] + if item["parameter"] == "VSet" + )["value"] + ) + print("-------------------------------------") + print("CHANNEL NUMBER : %i " % int(self.channel_entry["chan_num"])) + print("DETECTOR NAME : %s" % self.channel_entry["detector_name"]) + # print("Detector Position : %i" % chan_obj.detector_position) + print("MAX BIAS VOLTAGE : %i V" % int(self.channel_entry["max_bias_voltage"])) + print("RAMP RATE : %i V/sec" % int(self.channel_entry["ramp_rate"])) + print("CURRNET BIAS VOLTAGE : ", current_voltage) + print("** NEW BIAS VOLTAGE : ", new_voltage) + print("-------------------------------------") + user_confirmation_input = input( + "Are you sure you want to %s this channel? (y/n) : " % action.upper() + ) + if user_confirmation_input.upper() == "Y": + return True + else: + print("Could not confirm action, exiting ...") + sys.exit(1) + + def get_max_voltage_ramp_rate(self): + # get_max_voltage_ramp_rate: Pull out the Max Ramp Rate (RUp) from the config file for a channel + # Also go ahead and check that the ramp rate set doesn't exceed the + # max set in the config file + my_ramp_rate = 0 + if int(self.channel_entry["ramp_rate"]) < int( + self.config_dict["max_ramp_rate"] + ): + my_ramp_rate = int(self.channel_entry["ramp_rate"]) + else: + my_ramp_rate = int(self.config_dict["max_ramp_rate"]) + return int(my_ramp_rate) + + def find_channel_in_config(self): + # find_channel_in_config: Checks that there is a config entry for the channel before taking action on it and confirms if the channel is enabled + my_config_dict = self.config_dict[self.default_hvps_key] + channel_entry = None + # for my_channel_key in my_config_dict.keys(): + # if my_channel_key.startswith("CH_"): + # if(my_config_dict[my_channel_key]["chan_num"]==str(self.channel_selected) ) and my_config_dict[my_channel_key]["Enabled"].upper()=="True".upper(): + # channel_entry = my_config_dict[my_channel_key] + # return channel_entry + for key, val in my_config_dict.items(): + if key.startswith("CH_"): + # If channel exists in config file AND it is marked as ENABLED + if (val["chan_num"] == str(self.channel_selected)) and ( + val["Enabled"].upper() == "TRUE" + ): + channel_entry = val + return channel_entry # Return the dict for the specified channel + + def compare_voltage(self, my_new_bias_voltage): + # compare_voltage: Check what the current voltage of the channel and determine if it needs to be further biased on + # user request. + max_channel_bias_voltage = self.channel_entry["max_bias_voltage"] + max_global_bias_voltage = self.config_dict["max_bias_voltage"] + channel = self.channel_entry["chan_num"] + perform_bias = False + new_bias_voltage = int(my_new_bias_voltage) + channel_status_list = self.HVPS[0].status_channel( + None, self.my_slot, int(channel) + ) + # Iterate over the status of channels until reaching the VSet parameter we're looking for which is the current voltage + current_voltage = int( + next( + item + for item in channel_status_list[0][0]["chan_info"] + if item["parameter"] == "VSet" + )["value"] + ) + + if int(new_bias_voltage) > int(max_channel_bias_voltage): + print( + "!! Can not exceed this channels maximum BIAS voltage set in the config file:", + max_channel_bias_voltage, + ) + exit(1) + elif int(new_bias_voltage) > int(max_global_bias_voltage): + print( + "!! Can not exceed this global maximum BIAS voltage set in the config file:", + max_global_bias_voltage, + ) + exit(1) + if current_voltage == int( + new_bias_voltage + ): # Check if voltage is already the requested voltage + print( + "!! Channel:", + channel, + "is already set to bias voltage:", + current_voltage, + ) + exit(1) + else: # If it is not then we will prompt to confirm the change + perform_bias = self.confirm_channel("BIAS", my_new_bias_voltage) + return perform_bias + + def bias(self): + # bias: Runs checks and calls appropriate functions to bias a channel + max_ramp_rate = 10 + if ( + self.channel_selected is not None + ): # If we should go with the default voltage set in the config file + if self.channel_entry is not None: + if self.args.bias_voltage is not None: + my_new_bias_voltage = self.args.bias_voltage + else: + my_new_bias_voltage = self.channel_entry["max_bias_voltage"] + max_ramp_rate = ( + self.get_max_voltage_ramp_rate() + ) # Get the max volatage ramp rate RUp + if ( + self.compare_voltage(my_new_bias_voltage) is True + ): # Check if we need to actually change the voltage or if it is already set + self.HVPS[0].set_channel_param( + self.hvps_name, + self.my_slot, + int(self.channel_selected), + "RUp", + max_ramp_rate, + ) # Ensure the ramp up value is set to something safe + self.HVPS[0].set_channel_param( + self.hvps_name, + self.my_slot, + int(self.channel_selected), + "RDwn", + max_ramp_rate, + ) # Ensure the ramp up value is set to something safe + self.HVPS[0].set_channel_param( + self.hvps_name, + self.my_slot, + int(self.channel_selected), + "I1Set", + self.iset_current, + ) # Ensure we have 0 current set + self.HVPS[0].set_channel_param( + self.hvps_name, + self.my_slot, + int(self.channel_selected), + "V0Set", + self.vset_current, + ) + # self.HVPS[0].set_channel_param(self.hvps_name, self.my_slot, int(self.channel_selected), 'V1Set', self.vset_current) # + time.sleep( + 1 + ) # Sleep for a moment to make sure the setting has taken effect + self.HVPS[0].bias_channel( + self.hvps_name, + self.my_slot, + int(self.channel_selected), + int(my_new_bias_voltage), + ) # Bias the channel + else: + print( + "!! Must specify a BIAS voltage via --bias_voltage or put an entry for the channel in the config file and ensure Enabled is True" + ) + exit(1) + elif self.channel_selected is None: + print("!! Must specify --chan") + exit(1) + return + + def unbias_channel(self): + # unbias_channel: Drop VSet to 0 and also ensure RDwn (ramp down) voltage is set correctly + max_ramp_rate = self.get_max_voltage_ramp_rate() + if self.confirm_channel("UNBIAS", 0): + self.HVPS[0].set_channel_param( + self.hvps_name, + self.my_slot, + int(self.channel_selected), + "RDwn", + max_ramp_rate, + ) # Ensure the ramp up value is set to something safe + self.HVPS[0].unbias_channel( + self.hvps_name, self.my_slot, int(self.channel_selected) + ) + + +def process_cli_args(args, config_dict): + # process_cli_args: Mostly does just that, processes command line arguements and runs appropriate tests + if "default_slot" in config_dict.keys(): + my_slot = int(config_dict["default_slot"]) + else: + my_slot = args.slot_selected + + my_hvps_ctrl = hvps_ctrl(config_dict, args, my_slot) + my_hvps_ctrl.iset_current = args.iset_current + my_hvps_ctrl.vset_current = args.vset_current + + if args.status == True: + if args.channel_selected is None: + my_hvps_ctrl.HVPS[0].status_all_channels(args.hvps_name) + else: + channel_status_list = my_hvps_ctrl.HVPS[0].status_channel( + args.hvps_name, my_slot, args.channel_selected + ) + # TODO: check if it is true + # msg = my_hvps_ctrl.HVPS[0].show_channel_status(channel_status_list) + # print("status channels ===== " , msg) + + elif args.bias_voltage != None: + my_hvps_ctrl.bias() + elif args.unbias == True: + if args.channel_selected is None: + print("Must specify --chan") + else: + my_hvps_ctrl.unbias_channel() + elif args.action == "set_param": + if args.channel_selected is None: + print("Must specify --chan") + else: + if args.param in ["Pon", "Pw", "PDwn", "TripInt", "TripExt"]: + args.param_value = int(args.param_value) + else: + args.param_value = float(args.param_value) + + my_hvps_ctrl.HVPS[0].set_channel_param( + args.hvps_name, + my_slot, + int(args.channel_selected), + args.param, + args.param_value, + ) + elif args.chan_enable is not None: + my_hvps_ctrl.HVPS[0].set_channel_param( + args.hvps_name, my_slot, int(args.chan_enable), "Pw", 1 + ) # Ensure we have 0 current set + elif args.chan_disable is not None: + my_hvps_ctrl.HVPS[0].set_channel_param( + args.hvps_name, my_slot, int(args.chan_enable), "Pw", 0 + ) # Ensure we have 0 current set + else: + my_hvps_ctrl.HVPS[0].status_all_channels(args.hvps_name) + + del my_hvps_ctrl.HVPS[0] + # print("Time 2") # Uncommented this and the next line to try init'ing again. This should work if CAEN ever fixes their CApi which they promised back in Nov2020 + # HVPS = HVPS_Class(caen_system_info_list) + + return + + +'''def process_config_file_configobj(config_file="hvps.cfg"): + # process_config_file_configobj: Using ConfigObj to process config file into nested dict's + if exists(config_file): + config_dict = ConfigObj(config_file) # Change this to config_file after testing + return config_dict + else: + print("Could not open config file:", config_file) + print("Please specify using --config ") + exit(1)''' + +def process_config_file_configobj(config_file=None): + # process_config_file_configobj: Using ConfigObj to process config file into nested dict's + if config_file is not None and exists(config_file): + config_dict = ConfigObj(config_file) + print(f"Using config file: {config_file}") + for section, section_value in config_dict.items(): + if isinstance(section_value, dict): + print(f"[{section}]") + for key, value in section_value.items(): + print(f"{key} = {value}") + else: + print(f"{section} = {section_value}") + else: + # Default configuration in case the config file is not provided or doesn't exist + config_dict = { + "default_slot": "0", + "default_hvps":"HVPS_SY4527", + "HVPS_SY4527": { + "device_name": "SY4527", + "system_type": "2", + "link_type": "0", + "hostname": "192.168.1.210", + "username":"admin", + "password" : "admin", + }, + + # Add more default configuration entries as needed + } + print("No config file provided or config file does not exist. Using default configuration.") + print("Default Configuration:") + for section, section_value in config_dict.items(): + if isinstance(section_value, dict): + print(f"[{section}]") + for key, value in section_value.items(): + print(f"{key} = {value}") + else: + print(f"{section} = {section_value}") + return config_dict +#jandan added this function to print all channels status +def print_all_channel_status(self): + for channel_num in range(1, 33): # Assuming there are 32 channels in total + channel_status_list = self.HVPS[0].status_channel( + self.hvps_name, self.my_slot, channel_num + ) + if channel_status_list: + channel_info = channel_status_list[0][0]["chan_info"] + print(f"Channel {channel_num} Status:") + for item in channel_info: + if "parameter" in item and "value" in item: + parameter = item["parameter"] + value = item["value"] + print(f" {parameter}: {value}") + else: + print(f"Channel {channel_num} not found or not enabled in the config.") +parser = argparse.ArgumentParser( + description="HVPS Controller", + usage="%(prog)s --action [bias, unbias, status, set_name] --chan [channel num]", +) + + +def main(): + # parser = argparse.ArgumentParser( + # description="HVPS Controller", + # usage="%(prog)s --action [bias, unbias, status, set_name] --chan [channel num]", + # ) + parser.add_argument("--hvps_name", dest="hvps_name", default=None, required=False) + parser.add_argument( + "--status", + action="store_true", + default=False, + required=False, + help="Show status of channels (can specify --chan)", + ) + parser.add_argument( + "--unbias", + action="store_true", + default=False, + required=False, + help="Unbias channel specified with --chan #", + ) + parser.add_argument( + "--action", choices=("unbias", "set_param"), required=False, default=None + ) + + parser.add_argument( + "--param", + dest="param", + choices=( + "I1Set", + "V0Set", + "RUp", + "RDwn", + "Pon", + "Pw", + "TripInt", + "TripExt", + "PDwn", + "IMRange", + "Trip", + ), + required=False, + default=None, + help="Specify parameter to modify for channel, must specify with --action set_param", + ) + parser.add_argument( + "--param_value", + dest="param_value", + required=False, + default=None, + help="Specify parameter value, must specify --action set_param and --param", + ) + parser.add_argument( + "--bias", + dest="bias_voltage", + type=int, + required=False, + default=None, + help="Specify new bias voltage for a channel specified with --chan #", + ) + parser.add_argument( + "--iset_current", + dest="iset_current", + type=float, + required=False, + default=0.0, + help="Specify current (I1SET)", + ) + parser.add_argument( + "--vset_current", + dest="vset_current", + type=float, + required=False, + default=0.0, + help="Specify current (VSET)", + ) + parser.add_argument( + "--slot", + dest="slot_selected", + type=int, + required=False, + default=None, + help="Specify slot to take action against", + ) + + parser.add_argument( + "--chan_enable", + dest="chan_enable", + required=False, + type=int, + default=None, + help="Specify channel to turn on", + ) + parser.add_argument( + "--chan_disable", + dest="chan_disable", + required=False, + type=int, + default=None, + help="Specify channel to turn off", + ) + + parser.add_argument( + "--chan", + dest="channel_selected", + required=False, + type=int, + default=None, + help="Specify channel to take action against, specify channel number or ALL", + ) + + parser.add_argument( + "--config_file", + dest="config_file", + required=False, + default="hvps.cfg", + help="Specify the complete path to the config file, by default we'll use hvps.cfg", + ) + + parser.add_argument( + "--force", + action="store_true", + default=False, + required=False, + help="If used than no confirmation will be asked.. !!BE CAREFUL!!", + ) + + args, unknown = parser.parse_known_args() + # print("args==", args) + config_dict = process_config_file_configobj(args.config_file) + process_cli_args(args, config_dict) + + +def on_connect(client, userdata, flags, rc): + # Subscribing in on_connect() means that if we lose the connection and + # reconnect then subscriptions will be renewed. + # client.subscribe(f"/{client.device.name}/cmd/#") + client.subscribe("/SY4527/status/#") + # client.subscribe(f"/{my_hvps_ctrl.hvps_name}/cmd/#") + """Mqtt client on connect method""" + if rc == 0: + print("Connected to MQTT Broker!") + else: + print("Failed to connect, return code %d\n", rc) + + +def on_message(client, userdata, msg): + """Subscribed topic on message action""" + # print("recv", msg.topic, msg.payload) + # client.device.command(msg.topic, msg.payload) + print("RECEIVE message:") + print("Topic: " + msg.topic, msg.payload.decode()) + + +def run(device, mqtt_host): + import json + + client = mqtt.Client() + client.on_connect = on_connect + client.on_message = on_message + + client.device = device + client.connect(mqtt_host, 1883, 60) + # config_dict = process_config_file_configobj(config_file="hvps.cfg") + # print("config ", config_dict) + args, unknown = parser.parse_known_args() + config_dict = process_config_file_configobj(args.config_file) + + if "default_slot" in config_dict.keys(): + my_slot = int(config_dict["default_slot"]) + else: + my_slot = args.slot_selected + + my_hvps_ctrl = hvps_ctrl(config_dict, args, my_slot) + my_hvps_ctrl.iset_current = args.iset_current + my_hvps_ctrl.vset_current = args.vset_current + # client.subscribe(f"/{my_hvps_ctrl.hvps_name}/status/#") + + if args.status == True: + if args.channel_selected is None: + my_hvps_ctrl.HVPS[0].status_all_channels(args.hvps_name) + #my_hvps_ctrl.print_all_channel_status() #to print all channels status + else: + channel_status_list = my_hvps_ctrl.HVPS[0].status_channel( + args.hvps_name, my_slot, args.channel_selected + ) + # TODO: check if it is true + msg = my_hvps_ctrl.HVPS[0].show_channel_status(channel_status_list) + slot = msg["slot"] + channel_name = msg["chan_name"] + channel_number = msg["chan_num"] + channel_info = msg["chan_info"] + + client.loop_start() + topic = "/SY4527/status" + client.subscribe(topic) + while 1: + formatted_msg = f"Message:\nSlot: {slot} | Channel Name: {channel_name} | Channel#: {channel_number} | " + # formatted_msg = "Message:\n" + for item in channel_info: + if "parameter" in item and "value" in item: + parameter = item["parameter"] + value = item["value"] + formatted_msg += f"{parameter}: {value} | " + + client.publish(topic, str(formatted_msg)) + print(f"SEND `{formatted_msg}` to topic `{topic}`") + # client.publish("/{}/status".format(my_hvps_ctrl.hvps_name), json.dumps(msg)) + # client.publish(topic,json.dumps(msg)) + # print(f"SEND `{msg}` to topic `{topic}`") + + time.sleep(4) + time.sleep(4) + client.loop_stop() + client.disconnect() + + +if __name__ == "__main__": + main() + # mqtt_host = "docker.for.mac.host.internal" # if you are working locally + mqtt_host = "lyovis12.in2p3.fr" # or with hostaname:mqtt_host = "lyovis12.in2p3.fr" + # mqtt_port = 1883 + run(hvps_ctrl, mqtt_host) diff --git a/caen_hvps/hvps/lib/caen.py b/caen_hvps/hvps/lib/caen.py new file mode 100644 index 0000000..5a21d67 --- /dev/null +++ b/caen_hvps/hvps/lib/caen.py @@ -0,0 +1,318 @@ +# ************************************************************************************* +# By: Jon Ringuette +# Created: March 23 2020 - During the great plague +# Purpose: Provide low level wrapper for CAEN's c-api via Python's cdll functionality. +# One should use hvps.py to interface with the power supply unless you need very low +# level access to the hardware without any safety checks +# CAEN manaul and c-api : https://www.caen.it/products/caen-hv-wrapper-library/ +# ************************************************************************************* + +import socket +import sys +from ctypes import ( + c_int, + c_float, + c_void_p, + c_char_p, + c_char, + c_ushort, + pointer, + cdll, + cast, + POINTER, + byref, +) + + +class CAEN_Controller: + def __init__( + self, system_type, hostname, username, password, device_name, link_type=0 + ): + self.MAX_CHANNEL_NAME_LENGHT = ( + 12 # This is hardcoded at this time in the CAEN C-API + ) + self.MAX_PARAM_LENGTH = 10 # this too is hardcoded and needed for nasty pointer indexing caused by the char ** they like to use + self.PARAM_TYPE = { + 0: "numeric", + 1: "onoff", + 2: "chstatus", + 3: "bdstatus", + 4: "binary", + 5: "string", + 6: "enum", + } + try: + self.libcaenhvwrapper_so = cdll.LoadLibrary( + "libcaenhvwrapper.so" + ) # Load CAEN's c-api shared library + except: + print("Could not load CAEN's C library : libcaenhvwrapper.so") + print( + "It needs to be in in one of the directories listed in your LD_LIBRARY_PATH environment variable" + ) + exit(1) + self.device_name = device_name + self.system_type = system_type + self.hostname = hostname + self.username = username + self.password = password + self.link_type = link_type + try: + self.ip_address = socket.gethostbyname(hostname).encode( + "utf-8" + ) # We need to pass the IP addresss to the C API, and we need it in utf8 + print("Could get the IP address for the hostname :%s", (hostname)) + except: + print("Could not get the IP address for the hostname :%s", (hostname)) + print("Or the IP address is improperly formatted") + self.handle = c_int(0) + print("Initilizing HVPS...") + self.init() + + def check_return_code(self, return_code): + # check_return_code: Check if the return code passed back from an api call had an issue and attempt to print what it was + if hex(return_code) != hex(0): + print( + "Problem communicating with HVPS, check SLOT # and Channel #, IP : %s, ERROR code : %s" + % (self.ip_address, hex(return_code)) + ) + # print(cast(self.libcaenhvwrapper_so.CAENHV_GetError(self.handle), c_char_p).raw) # this didn't work the first time, maybe i'll come back to it + print("Calling Function:", sys._getframe(1).f_code.co_name) + exit(1) + else: + return return_code + + def init(self): + # init: Initialize the connection to the HVPS and return the handle as a pointer to a structure if successful. + # This handle must be used for all subsequent calls to the API for this session + print( + "DEBUG_INIT:::::", + self.username, + self.password, + self.ip_address, + self.ip_address.decode("utf-8"), + self.device_name, + self.system_type, + self.link_type, + ) + return_code = self.libcaenhvwrapper_so.CAENHV_InitSystem( + c_int(self.system_type), + c_int(self.link_type), + self.ip_address, + self.username.encode(), + self.password.encode(), + pointer(self.handle), + ) + self.check_return_code(return_code) + print("Initialized Connection to : %s" % (self.hostname)) + print( + "communicating with HVPS, check SLOT # and Channel #, IP : %s, ERROR code : %s" + % (self.ip_address, hex(return_code)) + ) + + def deinit(self): + # deinit: De-initilize the connection to the HVPS. + try: + return_code = self.libcaenhvwrapper_so.CAENHV_DeinitSystem(self.handle) + except: + print( + "Something didn't go well with de-init'ing, I wish I could tell you more but it's probably not the end of the world." + ) + return_code = 1 # different from 0 + return return_code + + def get_channel_paramters(self, slot, channel): + # get_channel_parameters: For a specific channel we want to gather all the available channel parameters such as VSet, ISet RUp etc.. + full_channel_parameters_list = [] + c_channel_info_list = c_char_p() # char pointer + c_channel_params_num = ( + c_int * 1 + )() # single value int array, it's just what it needs, don't think about it too hard... + + # Call CAENHV_GETChParamInfo from the c-api, passing the single channel entry by reference, will return c_channel_params_num with the + # number of parameters returned and c_channel_info_list will be an array of channael parameters available (not values of parameters) + return_code = self.libcaenhvwrapper_so.CAENHV_GetChParamInfo( + self.handle, slot, channel, byref(c_channel_info_list), c_channel_params_num + ) + self.check_return_code(return_code) + # print("parameter num :",c_channel_params_num) + + # This is an array and even using only one channel here have to treat it as such + num_parameters_for_channel = c_channel_params_num[0] + + channel_parameter_list = [] + + # For this we must do weird pointer indexing + for i in range(0, num_parameters_for_channel - 1): + pointer_to_param = cast(c_channel_info_list, c_void_p).value + ( + i * self.MAX_PARAM_LENGTH + ) # So we cast to type void_p then incriment the pointer value to move to the next actual value + channel_parameter_list.append( + cast( + pointer_to_param, POINTER(c_char * self.MAX_PARAM_LENGTH) + ).contents.value + ) # then we need to cast back to an array and deference the pointer and get the array value.. + + property_type = c_void_p() + # Here we call CaenHV_GetChParamProp to actually get the value of each of the channel properties one at a time + return_code = self.libcaenhvwrapper_so.CAENHV_GetChParamProp( + self.handle, + slot, + channel, + channel_parameter_list[-1], + "Type".encode("utf-8"), + byref(property_type), + ) + self.check_return_code(return_code) + + my_property_type = 0 + + # I don't know why it comes out as None instead of 0 but whatever.. + if property_type.value is not None: + my_property_type = property_type.value + # Set a dict with the parameter name and value type and value and then go ahead and append it to a list of dict's + parameter_dict = { + "parameter": channel_parameter_list[-1].decode("utf-8"), + "type": self.PARAM_TYPE[my_property_type], + "value": None, + } + full_channel_parameters_list.append(parameter_dict) + return full_channel_parameters_list + + def get_channel_names(self, slot, list_of_channels): + # get_channel_names: Get a list of all the channel names on a SLOT given a list of channels. + # Keep in mind that channel names aren't super useful as they really don't appear to be setable, I tried.. and failed.. + channel_names = [] + num_of_channels = len(list_of_channels) + c_channels_list = (c_ushort * num_of_channels)(*list_of_channels) # Setup array + + # Setup multidimentional array c_channel_names[num_channels][MaxLength] + c_channel_names = (c_char * self.MAX_CHANNEL_NAME_LENGHT * num_of_channels)() + # Call CAENHV_GetChName from c-api to get the name of each of the channels list in list_of_channels + return_code = self.libcaenhvwrapper_so.CAENHV_GetChName( + self.handle, slot, num_of_channels, c_channels_list, c_channel_names + ) + self.check_return_code(return_code) + + for channel_name in c_channel_names: + channel_names.append( + channel_name.value.decode("utf-8") + ) # append the name to a list + return channel_names + + def get_all_info_for_channels(self, slot, channels): + # get_all_info_for_channels: This is a big one where we loop over all the channels and parameters to build up a big list + # of dicts containing all the information for the channels + all_channels_info_list = [] + for my_channel in channels: # loop over all the channels + # Might as well grab the channel name, wonder what it'll be... + channel_name = self.get_channel_names(slot, [my_channel]) + + # get list of all available parameters + full_channel_parameters_list = self.get_channel_paramters(slot, my_channel) + + # Iterate over all the parameters to get all the values, yes there is a little code redundency here but you can fix it ;) + for my_parameter in full_channel_parameters_list: + c_channels_list = (c_ushort * 1)( + *[my_channel] + ) # multi-dimentional c array again + param_value = (c_void_p * 1)() + # Call to CAENHV_GetChParam to get the parameter value of the channel + return_code = self.libcaenhvwrapper_so.CAENHV_GetChParam( + self.handle, + slot, + my_parameter["parameter"].encode("utf-8"), + 1, + c_channels_list, + byref(param_value), + ) + self.check_return_code(return_code) + + cast_param_value = 0 + # Check what type of value we should be getting and cast the c_void_p accordingly + if my_parameter["type"] == "numeric": + cast_param_value = cast( + param_value, POINTER(c_float) + ).contents.value + elif ( + my_parameter["type"] == "onoff" + or my_parameter["type"] == "chstatus" + ): + cast_param_value = cast(param_value, POINTER(c_int)).contents.value + # if (cast_param_value & (1<= 1: + # We can have multiple channel status messages, I think... + my_status = my_status + my_status_code + "," + else: + try: + + channel_status_result["chan_info"].append( + { + "parameter": channel_dict["chan_info"][counter][ + "parameter" + ] + } + ) + channel_status_result["chan_info"][counter][ + "parameter" + ] = channel_dict["chan_info"][counter]["parameter"] + channel_status_result["chan_info"].append( + {"value": channel_dict["chan_info"][counter]["value"]} + ) + channel_status_result["chan_info"][counter][ + "value" + ] = channel_dict["chan_info"][counter]["value"] + + print( + channel_dict["chan_info"][counter]["parameter"], + ":", + channel_dict["chan_info"][counter]["value"], + end=" | ", + ) + except IndexError: + pass + counter += 1 + if my_status == "": + my_status = "Off" + print("Status :", my_status) + channel_status_result["status"]: my_status + # channel_status_result["chan_info"]["parameter"] = channel_dict["chan_info"][0]["parameter"] + # channel_status_result["chan_info"]["value"] = f"{channel_dict["chan_info"][0]['value']:.1f}" + # channel_status_result["chan_info"]["value"] = channel_dict["chan_info"][0]['value'] + return channel_status_result + + # else: + # channel_status_result["chan_info"]["parameter"] = channel_params["parameter"] + # channel_status_result["chan_info"]["value"] = f"{channel_params['value']:.1f}" + # print( + # channel_params["parameter"], + # ":", + # f"{channel_params['value']:.1f}", + # end=" | ", + # ) + # if my_status == "": + # my_status = "Off" + # print("Status :", my_status) + # channel_status_result["status"]: my_status + # return channel_status_result + + def status_channel(self, hvps_name, slot, channel): + # status_channel: Get the parameters and values for an individual channel + channel_status_list = [] + hvps_entry = self.get_object_entry_for_hvps_by_name(hvps_name) + channel_status_list.append( + hvps_entry.get_all_info_for_channels(slot, [channel]) + ) + return channel_status_list + + def set_channel_name(self, hvps_name, slot, channel, channel_name): + # set_channel_name: Attempts to set the channel name, I don't think our HVPS likes this.. + hvps_entry = self.get_object_entry_for_hvps_by_name(hvps_name) + hvps_entry.set_channel_name(slot, channel, channel_name) + return + + def get_all_crates_info(self): + # get_all_crates_info: Attempt to get all the information such as slot # and firmware version for all crates used by + # the configured HVPS's + crate_info_list = [] + for hvps_entry in self.hvps_systems_objects_list: # Loop over all the HVPS's + device_info_dict = { + "device_name": hvps_entry.device_name, + "hostname": hvps_entry.hostname, + } # Throw in a couple extra pieces of data + device_info_dict.update(hvps_entry.get_crate_info()) # combine dict's + crate_info_list.append(device_info_dict) + return crate_info_list + + def get_all_channel_names(self): + # get_all_channel_names: Loops over all HVPS's and gets the channel names for them all + full_list_of_channel_names = [] + crate_info_list = self.get_all_crates_info() # Get all the crates + for my_crate in crate_info_list: # Loop over all the crates + list_of_channel_names = [] + hvps_entry = self.get_object_entry_for_hvps_by_name(my_crate["device_name"]) + for my_slot in range( + 0, my_crate["num_of_slots"] + ): # Loop over all the slots in the crates + list_of_channel_names.extend( + hvps_entry.get_channel_names( + my_slot, list(range(0, my_crate["num_of_channels"])) + ) + ) # Get all channel names + # Put all the info into a list of dicts + device_and_channel_dict = { + "device_name": my_crate["device_name"], + "channel_names": list_of_channel_names, + } + full_list_of_channel_names.append(device_and_channel_dict) + return full_list_of_channel_names + + @staticmethod + def get_all_crate_channel_statuses(my_hpvs_crate): + # get_all_crate_channel_statuses: big aggragate function that tries to get all the channel info for every configured HVPS + channel_status_list = [] + crate_info_dict = my_hpvs_crate.get_crate_info() + for my_slot in range(0, crate_info_dict["num_of_slots"]): + channel_status_list.append( + my_hpvs_crate.get_all_info_for_channels( + my_slot, list(range(0, crate_info_dict["num_of_channels"])) + ) + ) + return channel_status_list + + def status_all_channels(self, hvps_name): + # status_all_channels: Go though all crates, hvps's and get status for every available channel + channel_status_list = [] + if hvps_name is not None: + hvps_entry = next( + ( + hvps_entry + for hvps_entry in self.hvps_systems_objects_list + if hvps_entry.device_name == hvps_name + ), + None, + ) + if hvps_entry is None: + print("Could not find HVPS name:", hvps_name) + exit(1) + channel_status_list.append( + self.get_all_crate_channel_statuses(hvps_entry) + ) # List of dict's + else: + for my_hvps in self.hvps_systems_objects_list: + channel_status_list.append( + self.get_all_crate_channel_statuses(my_hvps) + ) # list of dict's (you should sense a theme by now) + for hvps_entry in channel_status_list: + self.show_channel_status(hvps_entry) + return channel_status_list + + def find_channel_by_name(self, chan_name): + # find_channel_by_name: I haven't found a good enough of a use case to actually impliment this. + return diff --git a/caen_hvps/mqtt.py b/caen_hvps/mqtt.py new file mode 100644 index 0000000..35cf791 --- /dev/null +++ b/caen_hvps/mqtt.py @@ -0,0 +1,17 @@ +import os +import paho.mqtt.client as mqtt +from caen_hvps.utils.logger import logger + + +mqtt_host = os.environ["MQTT_HOST"] + + +def on_connect(client, userdata, flags, rc): + # Subscribing in on_connect() means that if we lose the connection and + # reconnect then subscriptions will be renewed. + logger.info(f"Connected to mqtt broker: {mqtt_host}") + + +client = mqtt.Client() +client.on_connect = on_connect +client.connect(mqtt_host, 1883, 60) diff --git a/caen_hvps/utils/logger.py b/caen_hvps/utils/logger.py new file mode 100644 index 0000000..6f758df --- /dev/null +++ b/caen_hvps/utils/logger.py @@ -0,0 +1,18 @@ +import logging +import os + + +def set_logger(logger_name): + log_format = "%(asctime)s - %(levelname)s - %(message)s" + + log = logging.getLogger(logger_name) + level = os.environ.get("LOG_LEVEL", "INFO") + log.setLevel(level) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(log_format)) + + log.addHandler(handler) + return log + + +logger = set_logger("main") diff --git a/caenlib/CAENHVWrapper-6.3/CAENHVWrapperReadme.txt b/caenlib/CAENHVWrapper-6.3/CAENHVWrapperReadme.txt deleted file mode 100644 index 42a1293..0000000 --- a/caenlib/CAENHVWrapper-6.3/CAENHVWrapperReadme.txt +++ /dev/null @@ -1,64 +0,0 @@ -/*****************************************************************************/ -/* */ -/* --- CAEN SpA - Computing Division --- */ -/* */ -/* CAEN HV Wrapper Library Installation and Use Instructions */ -/* */ -/*****************************************************************************/ - - This archive contains the last release of the CAEN HV Wrapper Library and the - corresponding Release Notes. - - The complete documentation can be found in the CAEN HV Wrapper Library Manual - available once installed the Library or on CAEN's Web Site - at www.caen.it. - - - Content of the archive - ---------------------- - install.sh : script to install the library - - CAENHVWrapperReadme.txt : This file - CAENHVWrapperReleaseNotes.txt : Release Notes of the last software release - - Lib/ - libcaenhvwrapper.so.x.xx : executable of the library (dynamic) - - Doc/ - CAENHVWrapper.pdf : user's manual of the library - - include/ - CAENHVWrapper.h : include file for use of the library - - HVWrapperDemo/ : directory with sources of the demo program - HVWrapperDemo/Makefile : makefile for demo program - - - System Requirements - ------------------- - - - Network Interface Card + TCP/IP protocol (to control SY 1527/ SY 2527 / SY 4527 / SY 5527) - - USB port (to control V65xx Boards, via V1718 VME Bridge) - - Optical Link (to control V65xx Boards, via V2718 - VME-PCI Optical Link Bridge) - - SY 1527/ SY 2527 firmware version 1.10.0 or later (recommended 1.14.03) - - Linux gcc 2.19 or greater with gnu C/C++ compiler - - - Installation notes - ------------------ - - 1. It's necessary to login as root - - 2. execute: ./install.sh - - The installation copies and installs the library in /usr/lib, - and installs it in the work directory. - - To compile demo program execute 'make all' in the HVWrappdemo directory. - To run the demo program launch the application typing ./HVWrappdemo. - - - Note: - ----- - Control of CAEN Power Supplies via USB/OpycalLink link requires the correct - installation of the USB/A2818 device driver and CAENComm library. diff --git a/caenlib/CAENHVWrapper-6.3/CAENHVWrapperReleaseNotes.txt b/caenlib/CAENHVWrapper-6.3/CAENHVWrapperReleaseNotes.txt deleted file mode 100644 index 9c6c125..0000000 --- a/caenlib/CAENHVWrapper-6.3/CAENHVWrapperReleaseNotes.txt +++ /dev/null @@ -1,363 +0,0 @@ -/*****************************************************************************/ -/* */ -/* --- CAEN SpA - Computing Division --- */ -/* */ -/* CAEN HV Wrapper Library Release Notes */ -/* */ -/* Rel. 6.2 - February 2022 */ -/* Rel. 6.1 - February 2021 */ -/* Rel. 6.0 - January 2020 */ -/* Rel. 5.82 - June 2016 */ -/* Rel. 5.81 - March 2016 */ -/* Rel. 5.77 - April 2015 */ -/* Rel. 5.62 - October 2014 */ -/* Rel. 5.61 - September 2014 */ -/* Rel. 5.56 - March 2014 */ -/* Rel. 5.52 - January 2014 */ -/* Rel. 5.50 - November 2013 */ -/* Rel. 5.22 - May 2013 */ -/* Rel. 5.21 - May 2013 */ -/* Rel. 5.20 - March 2013 */ -/* Rel. 5.10 - December 2012 */ -/* Rel. 5.00 - June 2012 */ -/* Rel. 3.20 - March 2012 */ -/* Rel. 3.10 - July 2010 */ -/* Rel. 2.11 - July 2003 */ -/* Rel. 2.8 - December 2002 */ -/* Rel. 2.4 - May 2002 */ -/* Rel. 2.0 - March 2002 */ -/* Rel. 1.2 - November 2000 */ -/* */ -/*****************************************************************************/ - - - Description - ----------- - - This document is updated for every official release of the CAEN HV Wrapper - Library and it contains various information specific to this software which - can not be found in the User's Manual, available together with the software - or on the CAEN web site: www.caen.it. - - - System Requirements - ------------------- - - - Network Interface Card + TCP/IP protocol - (to control SY 1527/ SY 2527 / SY4527 / SY 5527, NIM /DESKTOP HV, N568E, N1068) - - USB Interface (to control V65xx, NIM /DESKTOP HV, DT55xx HV, N568E, N1068) - - CAENComm library (to controll the V65xx or the DT55xx) - - What's New in Rel. 6.3 - --------------------------- - - New Features and Important Notes - - Fixed bug with DT55XX modules - - Fixed bug on concurrent access to HV modules - - What's New in Rel. 6.2 - --------------------------- - - New Features and Important Notes - -------------------------------- - - Added support to V65XX using V4718 and A4818 - - BugFix on SmartHV - - What's New in Rel. 6.1 - --------------------------- - - New Features and Important Notes - -------------------------------- - - - fixed bus on handling error from Sy4527/Sy5527 - - various bugfix - - What's New in Rel. 6.0 - --------------------------- - - add support for SMARTHV devices - - New Features and Important Notes - -------------------------------- - - - add support for N1068 device - - What's New in Rel. 5.82 - --------------------------- - - New Features and Important Notes - -------------------------------- - - - add support for N1068 device - - - What's New in Rel. 5.81 - --------------------------- - - New Features and Important Notes - -------------------------------- - - - add support for DT55XXE device - - - What's New in Rel. 5.77 - --------------------------- - - Bug Fixes - ---------- - - resolved bug in IMonZoom behavior for V65XX devices - - resolved bug in Log for V65XX devices - - resolved some minor bugs - - - What's New in Rel. 5.62 - --------------------------- - - Bug Fixes - ---------- - - resolved bug with SY 2527 / SY 5527 devices, which were not correctly handled in some functions that return - errors. - - resolved bug in CAENHV_GetError function, which deadlocks with SY 1527 / SY 2527 / SY 4527 / SY 5527 devices - - - What's New in Rel. 5.61 - --------------------------- - - Bug Fixes - ---------- - - resolved bug in setting out of range parameters for SY 4527 / SY 5527 devices, which caused a crash in - the library - - What's New in Rel. 5.56 - --------------------------- - - New Features and Important Notes - -------------------------------- - - in NIM devices, current monitor zoom is showed with two different parameters now (IMonL, IMonH) - - Bug Fixes - ---------- - - resolved bug with DT55xx, which does not show correctly parameters resolution - - resolved bug with DT55xx, which causes bad rounded VMax values - - resolved bug in SY4527 / SY 5527 and SY1527 / SY2527, which handles data structures in a - bad way when disconnecting - - - What's New in Rel. 5.52 - --------------------------- - - New Features and Important Notes - -------------------------------- - - added LabView version - - added static library version - - Bug Fixes - ---------- - - resolved bug in GetBdParam(..) internal function for SY 4527 / SY 5527 devices, that returned a wrong code - - - What's New in Rel. 5.50 - --------------------------- - - New Features and Important Notes - -------------------------------- - - add support for N568E device - - add support for DT55xx device - - thread-safe mechanism for SY1527/SY4527 families connections - - Bug Fixes - ---------- - - resolved bug in V65xx optical link connection, with event mode - - - What's New in Rel. 5.22 - --------------------------- - - Bug Fixes - ---------- - - resolved bug in NIM / Destkop connection/disconnection - - resolved bug in NIM / Desktop Read Data - - - What's New in Rel. 5.21 - -------------------------- - - Bug Fixes - --------- - - resolved 64bit version bug - - - What's New in Rel. 5.20 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - add support for V8100 - - Bug Fixes - --------- - - resolved some minor bugs - - What's New in Rel. 5.10 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - add support for N1470 - - add support for V65XX - - Bug Fixes - --------- - - eliminates bug with A1676A with a large number of channels - - - What's New in Rel. 5.00 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - removed support for old modules/system accordingly with CAEN's Product Obsolescence Policy - - add support for new power supply system SY 4527 and SY 5527 - - new api format - - - What's New in Rel. 3.20 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - removed support for old modules/system accordingly with CAEN's Product Obsolescence Policy - - various bug fix - - - What's New in Rel. 3.10 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - add support for Sy1527/Sy2527 Event mode features (only Windows platform) - - add support for Sy4527/Sy5527 - - Bug Fixes - --------- - - - Corrected some minor bugs - - What's New in Rel. 3.10 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - add support for Sy1527/Sy2527 Event mode features - - add support for VME Power Supply modules (V65xx Family) - - What's New in Rel. 2.11 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - Shortened the CAENET systems login timeout from 5.0s to 200ms. - - Made the library "thread safe". - - - Bug Fixes - --------- - - - Eliminated spurious CAENET errors during login attempts. - - - What's New in Rel. 2.8 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - Included control of N568/B 16 Channels Programmable Spectroscopy - Amplifier - - Added the "count" Engineering Unit - - Added support for the CAENHVSetBdParam API function with Sy1527 - (needs Rel. 1.14.00 or more recent in the SY1527/2527) - - - Bug Fixes - --------- - - - Corrected some minor bugs - - - What's New in Rel. 2.4 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - Added support for the new A1303 H. S. CAENET Controller; it is now - possible to have multiple boards (i.e. independent CAENET chains in a - single PC) - - Included control of Sy403 High Voltage System via CAENET (through - Mod. A303A or A1303) - - Added support for CAENET BUSY handling, i.e. by retrying to execute - the CAENET command - - Included control of N470 and N570 Programmable Power Supplies via - CAENET (through Mod. A303A or A1303) - - - Bug Fixes - --------- - - - Corrected some minor bugs - - - What's New in Rel. 2.0 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - Included control of Sy127 and Sy527 via CAENET (through Mod. A303A, - High Speed CAENET Controller for PC) - - Added the "rpm" Engineering Unit - - Handled signed parameters, like i.e. negative temperature - - - Bug Fixes - --------- - - - Corrected some minor bugs - - - What's New in Rel. 1.2 - -------------------------- - - New Features and Important Notes - -------------------------------- - - - Support for communication with SY1527/SY2527 via TCP/IP - - - Determining Your Software Release - --------------------------------- - - To determine the complete software release of the CAEN HV Wrapper Library - installed in your machine, you can use the relevant menu choice of the demo - program. - You will see something like: - 5.21-1.7 - where: 5.21 is the Release of the CAENHVWrapper.dll described in this document - and 1.7 is the Release of the HSCAENETlib.dll library used by the Wrapper - library for the communication with the CAENET Power Supplies (you will find - detailed info for that software in the HSCAENETReleaseNotes.txt document). - - - How to get support - ------------------ - - Our Software Support Group is available for questions, support and any other - software related issue concerning CAEN Power Supplies; for software support - visit the page www.caen.it/computing/support.php. diff --git a/caenlib/CAENHVWrapper-6.3/CAEN_License_Agreement.txt b/caenlib/CAENHVWrapper-6.3/CAEN_License_Agreement.txt deleted file mode 100644 index 252868f..0000000 --- a/caenlib/CAENHVWrapper-6.3/CAEN_License_Agreement.txt +++ /dev/null @@ -1,188 +0,0 @@ -Software License - -Copyright © 1998-2022 C.A.E.N. S.p.A - -Licence Agreement for "CAEN Software or Firmware" (collectively, the "CAEN SwFw") - -By using or distributing this CAEN SwFw (or any work based on the CAEN SwFw) you shall be deemed to have -accepted the terms and conditions set out below. - -C.A.E.N. S.p.A ("C.A.E.N.") is making this CAEN SwFw freely available on the basis that it is accepted as found and -that the user checks its fitness for purpose prior to use. - -The CAEN SwFw is provided 'as-is', without any express or implied warranties whatsoever. In no event will the -authors, partners or contributors be held liable for any damages, claims or other liabilities direct or indirect, arising -from the use of this CAEN SwFw or any derivative work. - -C.A.E.N. will from time to time make CAEN SwFw updates available. However, C.A.E.N. accepts no obligation to -provide any support to free licence holders. - -C.A.E.N. grants you a limited non-exclusive licence to use this CAEN SwFw for any purpose, including commercial -applications and redistribute it freely, subject to the following restrictions: - -1. The origin of this CAEN SwFw must not be misrepresented; you must not claim that you wrote the original CAEN SwFw. -2. You must not alter the CAEN SwFw, user licence or installer in any way. -3. This notice may not be removed or altered from any distribution. -4. You may not resell or charge for the CAEN SwFw. -5. You may not reverse engineer, decompile, disassemble, derive the source code of or modify the CAEN SwFw in order to resell, - rent, lease, loan, derivative works. -6. You must not use CAEN SwFw to engage in or allow others to engage in any illegal activity. -7. You may not claim any sponsorship by, endorsement by, or affiliation with our company. -8. You acknowledge that C.A.E.N. owns the copyright and all associated intellectual property rights relating to the -CAEN SwFw except to the extent that the CAEN SwFw includes identifiable separate components originating from -the CAEN SwFw. - -1. Licensed Uses and Restrictions. - -CAEN SwFw applications, documentation, and local computer files installed or utilised by the installer application -are owned by C.A.E.N., and are licensed to you on a worldwide (except as limited below), non-exclusive, non- -sublicenseable basis on the terms and conditions set forth herein. This CAEN SwFw Licence defines legal use of the -CAEN SwFw, all updates, revisions, substitutions, and any copies of the CAEN SwFw made by or for you. All rights -not expressly granted to you are reserved by C.A.E.N. or their respective owners. - -A(i) YOU MAY install and personally use the CAEN SwFw and any updates provided by C.A.E.N. (in its sole -discretion) in object code form on a personal computer or on board on CAEN Products owned or controlled by you -and may use the CAEN SwFw for your own non commercial use or benefit. Your licence to the CAEN SwFw under -this CAEN SwFw Licence continues until it is terminated by either party. You may terminate the CAEN SwFw Licence -by discontinuing use of all or any of the CAEN SwFw and by destroying all your copies of the applicable CAEN -SwFw. This CAEN SwFw Licence terminates automatically if you violate any term of this CAEN SwFw Licence, -C.A.E.N. publicly posts a written notice of termination on C.A.E.N.�s web site, or C.A.E.N. sends a written notice of -termination to you. - -A (ii) You may make a CAEN SwFw copy only if it is necessary for its use. - -b. YOU MAY NOT: - -(i) decompile, reverse engineer, disassemble, modify the CAEN SwFw or any portion thereof in order to resell, -rent, lease, derivative works (as defined by the Italian Copyright Act, l.22 April 1941, n.633 and following -amendments) or improvements (as defined by Italian patent law), without C.A.E.N.�s prior, express, written -permission. - -(ii) incorporate the CAEN SwFw into any computer chip or the firmware of a computing device manufactured by or -for you except in those where you have received. - -(iii) use the CAEN SwFw in any unlawful manner, for any unlawful purpose. - -(iv) you may not use the CAEN SwFw to operate nuclear facilities, life support, or other mission critical application -where human life or property may be at stake. You understand that the CAEN SwFw is not designed for such -purposes and that its failure in such cases could lead to death, personal injury, or severe property or environmental -damage for which C.A.E.N. is not responsible. - -(v) use or export the CAEN SwFw in violation of applicable Italian laws or regulations - -(vi) sell, lease, loan, distribute, transfer, or sub-license the CAEN SwFw or access thereto or derive income from -the use or provision of the CAEN SwFw, whether for direct commercial or monetary gain or otherwise, without -C.A.E.N.�s prior, express, written permission. - -c. As provided from Berna Convention concerning the Protection of Works of Art and Literature acknowledged in -Italy with Law 20 June 1978, n. 399, the provisions of this agreement can not be interpreted to allow their -application is a jeopardizing event for the owner of the rights or is in conflict with the ordinary use of the CAEN -SwFw - -2. Ownership and Relationship of Parties. - -The CAEN SwFw is protected by copyrights, trademarks, service marks, international treaties, and/or other -proprietary rights and laws of the U.S. and other countries. You agree to abide by all applicable proprietary rights -laws and other laws. C.A.E.N. owns all rights, title, and interest in and to their applicable contributions to the CAEN -SwFw. This CAEN SwFw Licence grants you no right, title, or interest in any intellectual property owned or licensed -by C.A.E.N., including (but not limited to) the CAEN SwFw and the C.A.E.N. trademarks, and creates no relationship -between you and C.A.E.N. other than that of C.A.E.N. to licensee. - -You agree that you will use the CAEN SwFw, and any data accessed through the CAEN SwFw, for your own -personal non-commercial use only. You agree not to assign, copy, transfer, or transmit CAEN SwFw. Your licence to -use the CAEN SwFw will terminate if you violate these restrictions. If your licence terminates, you agree to cease -any and all use of the CAEN SwFw. All rights in any third-party data, any third-party CAEN SwFw, and any third- -party data servers, including all ownership rights are reserved and remain with the respective third parties. You -agree that these third parties may enforce their rights under this Agreement against you directly in their own name. - -3. Support and CAEN SwFw Updates. - -C.A.E.N. may elect to provide you with customer support and/or CAEN SwFw upgrades, enhancements, or -modifications for the CAEN SwFw (collectively, "Support"), in its sole discretion, and may terminate such Support at -any time without notice to you. C.A.E.N. may change, suspend, or discontinue any aspect of the CAEN SwFw at any -time, including the availability of any CAEN SwFw feature, database, or content. C.A.E.N. may also impose limits on -certain features and services or restrict your access to parts or all of the CAEN SwFw or the C.A.E.N. web site -without notice or liability. - -4. Fees and Payments. - -C.A.E.N. reserves the right to charge fees for future use of or access to the CAEN SwFw in C.A.E.N.�s sole -discretion. If C.A.E.N. decides to charge for the CAEN SwFw , such charges will be disclosed to you 28 days before -they are applied. - -5. Disclaimer of Warranties by C.A.E.N. - -Use of the CAEN SwFw and any data accessed through the CAEN SwFw is at your sole risk. They are Provided "as -is." - -Any service or otherwise obtained through the use of the CAEN SwFw is done at your own discretion and risk, and -you will be solely responsible for any damage to your computer system or loss of data that results from the -download and/or use of any such material or service. - -C.A.E.N., its officers, directors, employees, contractors, agents, affiliates, and assigns (collectively, "C.A.E.N. -Entities"), and C.A.E.N.�s Licensors do not represent that the CAEN SwFw or any data accessed therefrom is -appropriate or available for use outside Italy. - -The C.A.E.N. Entities and C.A.E.N. Licensors expressly disclaim all warranties of any kind, whether express or -implied, relating to the CAEN SwFw and any data accessed therefrom, or the accuracy, timeliness, completeness, or -adequacy of the CAEN SwFw and any data accessed therefrom, including the implied warranties of title, -merchantability, satisfactory quality, fitness for a particular purpose, and non-infringement. - -If the CAEN SwFw or any data accessed therefrom proves defective, you (and not the C.A.E.N. Entities, or the -C.A.E.N. Licensors) assume the entire cost of all repair or injury of any kind, even if the C.A.E.N. Entities, or -C.A.E.N. Licensors have been advised of the possibility of such a defect or damages. Some jurisdictions do not -allow restrictions on implied warranties so some of these limitations may not apply to you. - -6. Limitation of liability. - -Notwithstanding any other provision, nothing in this CAEN SwFw Licence shall exclude or limit either party�s liability -for the tort of deceit, fraudulent misrepresentation, death or personal injury caused by negligence. - -The C.A.E.N. Entities and C.A.E.N. Licensors will not be liable to you for claims and liabilities of any kind arising out -of or in any way related to the use of the CAEN SwFw or any derivative work by yourself or by third parties, to the -use or non-use of any brokerage firm or dealer, or to the sale or purchase of any security, whether such claims and -liabilities are based on any legal or equitable theory. - -The C.A.E.N. Entities and C.A.E.N. Licensors are not liable to you for any and all direct, incidental, special, indirect, -or consequential damages arising out of the use or inability to use the CAEN SwFw or any derivative work, -arising out of or related to any third-party CAEN SwFw or any derivative work , any data accessed through the -CAEN SwFw or any derivative work, your use or inability to use or access the CAEN SwFw or any derivative work , -or any data provided through the CAEN SwFw or any derivative work , whether such damage claims are brought -under any theory of law or equity. Damages excluded by this clause include, without limitation, those for loss of -business profits, injury to person or property, business interruption, loss of business or personal information. Some -jurisdictions do not allow limitation of incidental or consequential damages so this restriction may not apply to you. - -Information provided through the CAEN SwFw , may be delayed, inaccurate, or contain errors or omissions, and the -C.A.E.N. Entities and C.A.E.N. Licensors will have no liability with respect thereto. C.A.E.N. may change or -discontinue any aspect or feature of the CAEN SwFw or the use of all or any features or technology in the CAEN -SwFw at any time without prior notice to you, including, but not limited to, content, hours of availability. - -7. Indemnification. - -You are solely responsible for compliance with agreements you have executed with third parties. You agree to -indemnify and hold the C.A.E.N. Entities harmless from any claim or demand, including reasonable legal fees, made -by any third party in connection with or arising out of your use of the CAEN SwFw , your violation of any terms or -conditions of this CAEN SwFw Licence, your violation of applicable laws, or your violation of any rights of another -person or entity. - -8. Controlling Law. - -This CAEN SwFw Licence and the relationship between you and C.A.E.N. is governed by the laws of Italy. -This Agreement shall be construed and governed by Italian Law. -The United Nations Convention on the International Sale of Goods does not apply to this CAEN SwFw Licence. -Any dispute arising out of or in connection with this Agreement shall be referred to and finally resolved by -Arbitration under the provisions of Italian Law (c.p.c. art 816 and following.) by one Arbitrator. -The Arbitrator shall be nominated from Chairman of the Court of Milan. -The place of Arbitration shall be Milan, Italy and the language shall be English - -9. Precedence . - -This CAEN SwFw Licence constitute the entire understanding between the parties respecting use of the CAEN -SwFw, superseding all prior agreements between you and C.A.E.N.. In the event of any conflict between the terms -and conditions of this CAEN SwFw Licence, the terms and conditions of this CAEN SwFw Licence will control - -10. Surviving Provisions. - -Sections 2, and 4 through 10, will survive any termination of this Agreement. - -Tel No: +39.0584.388398 , Fax No.: +39.0584.388959, E-mail: support.computing@caen.it diff --git a/caenlib/CAENHVWrapper-6.3/bin/x86/libcaenhvwrapper.so.6.3 b/caenlib/CAENHVWrapper-6.3/bin/x86/libcaenhvwrapper.so.6.3 deleted file mode 100644 index 2ceff1e..0000000 Binary files a/caenlib/CAENHVWrapper-6.3/bin/x86/libcaenhvwrapper.so.6.3 and /dev/null differ diff --git a/caenlib/CAENHVWrapper-6.3/bin/x86_64/libcaenhvwrapper.so.6.3 b/caenlib/CAENHVWrapper-6.3/bin/x86_64/libcaenhvwrapper.so.6.3 deleted file mode 100644 index 9cc5031..0000000 Binary files a/caenlib/CAENHVWrapper-6.3/bin/x86_64/libcaenhvwrapper.so.6.3 and /dev/null differ diff --git a/caenlib/CAENHVWrapper-6.3/doc/CAENHVWrapper.pdf b/caenlib/CAENHVWrapper-6.3/doc/CAENHVWrapper.pdf deleted file mode 100644 index c3970c4..0000000 Binary files a/caenlib/CAENHVWrapper-6.3/doc/CAENHVWrapper.pdf and /dev/null differ diff --git a/caenlib/CAENHVWrapper-6.3/include/CAENHVWrapper.h b/caenlib/CAENHVWrapper-6.3/include/CAENHVWrapper.h deleted file mode 100644 index b5ec65f..0000000 --- a/caenlib/CAENHVWrapper-6.3/include/CAENHVWrapper.h +++ /dev/null @@ -1,384 +0,0 @@ -/***************************************************************************/ -/* */ -/* --- CAEN Engineering Srl - Computing Systems Division --- */ -/* */ -/* CAENHVWRAPPER.H */ -/* */ -/* */ -/* Source code written in ANSI C */ -/* */ -/* Created: July 2011 */ -/* */ -/***************************************************************************/ - -#ifndef __CAENHVWRAPPER_H -#define __CAENHVWRAPPER_H - -#ifdef UNIX // Rel. 2.0 - Linux -#include -#include -#include - -#define CAENHVLIB_API - -extern void Sleep(unsigned int x); - -#else // UNIX - -#include - -#ifdef CAENHVLIB -#define CAENHVLIB_API __declspec(dllexport) -#else -#define CAENHVLIB_API -#endif - -#endif // UNIX - - -#ifdef __GNUC__ -#define HV_DEPRECATED(func) func __attribute__ ((deprecated)) -#elif defined(_MSC_VER) -#define HV_DEPRECATED(func) __declspec(deprecated) func -#else -#pragma message("WARNING: DEPRECATED marking not supported on this compiler") -#define HV_DEPRECATED(func) func -#endif - -#ifndef uchar -#define uchar unsigned char -#endif -#ifndef ushort -#define ushort unsigned short -#endif -#ifndef ulong -#define ulong unsigned int -#endif - - -#define MAX_CH_NAME 12 - -#define MAX_PARAM_NAME 10 - -#define MAX_CRATES 8 -#define MAX_SLOTS 32 -#define MAX_BOARDS ( MAX_SLOTS * MAX_CRATES ) - -#define MAX_BOARD_NAME 12 -#define MAX_BOARD_DESC 28 -#define SET 1 -#define MON 0 -#define SIGNED 1 -#define UNSIGNED 0 - -#define PARAM_TYPE_NUMERIC 0 -#define PARAM_TYPE_ONOFF 1 -#define PARAM_TYPE_CHSTATUS 2 -#define PARAM_TYPE_BDSTATUS 3 -#define PARAM_TYPE_BINARY 4 // Rel. 2.16 -#define PARAM_TYPE_STRING 5 -#define PARAM_TYPE_ENUM 6 // Rel 5.30 - -#define PARAM_MODE_RDONLY 0 -#define PARAM_MODE_WRONLY 1 -#define PARAM_MODE_RDWR 2 - -#define PARAM_UN_NONE 0 -#define PARAM_UN_AMPERE 1 -#define PARAM_UN_VOLT 2 -#define PARAM_UN_WATT 3 -#define PARAM_UN_CELSIUS 4 -#define PARAM_UN_HERTZ 5 -#define PARAM_UN_BAR 6 -#define PARAM_UN_VPS 7 -#define PARAM_UN_SECOND 8 -#define PARAM_UN_RPM 9 // Rel. 1.4 -#define PARAM_UN_COUNT 10 // Rel. 2.6 -#define PARAM_UN_BIT 11 -#define PARAM_UN_APS 12 - -#define SYSPROP_TYPE_STR 0 -#define SYSPROP_TYPE_REAL 1 -#define SYSPROP_TYPE_UINT2 2 -#define SYSPROP_TYPE_UINT4 3 -#define SYSPROP_TYPE_INT2 4 -#define SYSPROP_TYPE_INT4 5 -#define SYSPROP_TYPE_BOOLEAN 6 - -#define SYSPROP_MODE_RDONLY 0 -#define SYSPROP_MODE_WRONLY 1 -#define SYSPROP_MODE_RDWR 2 - -#define EVENTTYPE_PARAMETER 0 -#define EVENTTYPE_ALARM 1 -#define EVENTTYPE_KEEPALIVE 2 -#define EVENTTYPE_TRMODE 3 - -#define MAXLINE 0x1000 -#define MAX_AVAILABLE_DEVICE 100 - -/*----------------------------------------------------------------------------- - ERROR CODES - - Their meaning is the next: - CODES - 0 Command wrapper correctly executed - 1 Error of operatived system - 2 Write error in communication channel - 3 Read error in communication channel - 4 Time out in server communication - 5 Command Front End application is down - 6 Communication with system not yet connected by a Login command - 7 Communication with a not present board/slot - 8 Communication with RS232 not yet implemented - 9 User memory not sufficient - 10 Value out of range - 11 Execute command not yet implemented - 12 Get Property not yet implemented - 13 Set Property not yet implemented - 14 Property not found - 15 Execute command not found - 16 No System property - 17 No get property - 18 No set property - 19 No execute command - 20 Device configuration changed - 21 Property of param not found - 22 Param not found - 23 No data present - 24 Device already open - 25 To Many devices opened - 26 Function Parameter not valid - 27 Function not available for the connected device - 0x1001 Device already connected - 0x1002 Device not connected - 0x1003 Operating system error - 0x1004 Login failed - 0x1005 Logout failed - 0x1006 Link type not supported - 0x1007 Login failed for username/password ( SY4527 / SY5527 ) - -----------------------------------------------------------------------------*/ -#define CAENHV_OK 0 -#define CAENHV_SYSERR 1 -#define CAENHV_WRITEERR 2 -#define CAENHV_READERR 3 -#define CAENHV_TIMEERR 4 -#define CAENHV_DOWN 5 -#define CAENHV_NOTPRES 6 -#define CAENHV_SLOTNOTPRES 7 -#define CAENHV_NOSERIAL 8 -#define CAENHV_MEMORYFAULT 9 -#define CAENHV_OUTOFRANGE 10 -#define CAENHV_EXECCOMNOTIMPL 11 -#define CAENHV_GETPROPNOTIMPL 12 -#define CAENHV_SETPROPNOTIMPL 13 -#define CAENHV_PROPNOTFOUND 14 -#define CAENHV_EXECNOTFOUND 15 -#define CAENHV_NOTSYSPROP 16 -#define CAENHV_NOTGETPROP 17 -#define CAENHV_NOTSETPROP 18 -#define CAENHV_NOTEXECOMM 19 -#define CAENHV_SYSCONFCHANGE 20 -#define CAENHV_PARAMPROPNOTFOUND 21 -#define CAENHV_PARAMNOTFOUND 22 -#define CAENHV_NODATA 23 -#define CAENHV_DEVALREADYOPEN 24 -#define CAENHV_TOOMANYDEVICEOPEN 25 -#define CAENHV_INVALIDPARAMETER 26 -#define CAENHV_FUNCTIONNOTAVAILABLE 27 -#define CAENHV_SOCKETERROR 28 -#define CAENHV_COMMUNICATIONERROR 29 -#define CAENHV_NOTYETIMPLEMENTED 30 -#define CAENHV_CONNECTED (0x1000 + 1) -#define CAENHV_NOTCONNECTED (0x1000 + 2) -#define CAENHV_OS (0x1000 + 3) -#define CAENHV_LOGINFAILED (0x1000 + 4) -#define CAENHV_LOGOUTFAILED (0x1000 + 5) -#define CAENHV_LINKNOTSUPPORTED (0x1000 + 6) // Rel. 1.2 -#define CAENHV_USERPASSFAILED (0x1000 + 7) // Rel. 5.0 - -// Link Types for InitSystem -#define LINKTYPE_TCPIP 0 -#define LINKTYPE_RS232 1 -#define LINKTYPE_CAENET 2 -#define LINKTYPE_USB 3 -#define LINKTYPE_OPTLINK 4 -#define LINKTYPE_USB_VCP 5 -#define LINKTYPE_USB3 6 -#define LINKTYPE_A4818 7 - - - -#ifndef __CAENHVRESULT__ // Rel. 2.0 - Linux -// The Error Code type -typedef int CAENHVRESULT; -#define __CAENHVRESULT__ -#endif - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -typedef union { - char StringValue[1024]; - float FloatValue; - int IntValue; -} IDValue_t; - -typedef enum { - PARAMETER = 0, - ALARM = 1, - KEEPALIVE = 2, - TRMODE = 3 -}CAENHV_ID_TYPE_t; - -// Rel. 3.00 -typedef struct { - char Type; - char ItemID[64]; - char Lvalue[4]; - char Tvalue[256]; -} CAENHVEVENT_TYPE; - -typedef struct { - CAENHV_ID_TYPE_t Type; - int SystemHandle; - int BoardIndex; - int ChannelIndex; - char ItemID[20]; - IDValue_t Value; -} CAENHVEVENT_TYPE_t; - -typedef enum { - SY1527 = 0, - SY2527 = 1, - SY4527 = 2, - SY5527 = 3, - N568 = 4, - V65XX = 5, - N1470 = 6, - V8100 = 7, - N568E = 8, - DT55XX = 9, - FTK = 10, - DT55XXE = 11, - N1068 = 12, - SMARTHV = 13, - NGPS = 14 -} CAENHV_SYSTEM_TYPE_t; - -typedef enum { - SYNC = 0, - ASYNC = 1, - UNSYNC = 2, - NOTAVAIL = 3 -} CAENHV_EVT_STATUS_t; - -typedef struct { - CAENHV_EVT_STATUS_t System; - CAENHV_EVT_STATUS_t Board[16]; -} CAENHV_SYSTEMSTATUS_t; - -CAENHVLIB_API char* CAENHVLibSwRel(void); - -CAENHVLIB_API CAENHVRESULT CAENHV_InitSystem(CAENHV_SYSTEM_TYPE_t system, int LinkType, void *Arg, - const char *UserName, const char *Passwd, int *handle); - -CAENHVLIB_API CAENHVRESULT CAENHV_DeinitSystem(int handle); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetCrateMap(int handle, - ushort *NrOfSlot, ushort **NrofChList, char **ModelList, char **DescriptionList, - ushort **SerNumList, uchar **FmwRelMinList, uchar **FmwRelMaxList); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetSysPropList(int handle, - ushort *NumProp, char **PropNameList); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetSysPropInfo(int handle, - const char *PropName, unsigned *PropMode, unsigned *PropType); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetSysProp(int handle, - const char *PropName, void *Result); - -CAENHVLIB_API CAENHVRESULT CAENHV_SetSysProp(int handle, - const char *PropName, void *Set); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetBdParam(int handle, - ushort slotNum, const ushort *slotList, const char *ParName, void *ParValList); - -CAENHVLIB_API CAENHVRESULT CAENHV_SetBdParam(int handle, - ushort slotNum, const ushort *slotList, const char *ParName, void *ParValue); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetBdParamProp(int handle, - ushort slot, const char *ParName, const char *PropName, void *retval); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetBdParamInfo(int handle, - ushort slot, char **ParNameList); - -CAENHVLIB_API CAENHVRESULT CAENHV_TestBdPresence(int handle, - ushort slot, ushort *NrofCh, char **Model, char **Description, ushort *SerNum, - uchar *FmwRelMin, uchar *FmwRelMax); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetChParamProp(int handle, - ushort slot, ushort Ch, const char *ParName, const char *PropName, void *retval); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetChParamInfo(int handle, ushort slot, ushort Ch, - char **ParNameList, int *ParNumber); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetChName(int handle, ushort slot, - ushort ChNum, const ushort *ChList, char (*ChNameList)[MAX_CH_NAME]); - -CAENHVLIB_API CAENHVRESULT CAENHV_SetChName(int handle, ushort slot, - ushort ChNum, const ushort *ChList, const char *ChName); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetChParam(int handle, ushort slot, - const char *ParName, ushort ChNum, const ushort *ChList, void *ParValList); - -CAENHVLIB_API CAENHVRESULT CAENHV_SetChParam(int handle, ushort slot, - const char *ParName, ushort ChNum, const ushort *ChList, void *ParValue); - -CAENHVLIB_API CAENHVRESULT CAENHV_GetExecCommList(int handle, - ushort *NumComm, char **CommNameList); - -CAENHVLIB_API CAENHVRESULT CAENHV_ExecComm(int handle, const char *CommName); - -CAENHVLIB_API CAENHVRESULT CAENHV_SubscribeSystemParams(int handle, short Port, const char *paramNameList, - unsigned int paramNum ,char *listOfResultCodes); - -CAENHVLIB_API CAENHVRESULT CAENHV_SubscribeBoardParams(int handle, short Port, const unsigned short slotIndex, - const char *paramNameList, unsigned int paramNum ,char *listOfResultCodes); - -CAENHVLIB_API CAENHVRESULT CAENHV_SubscribeChannelParams(int handle, short Port, const unsigned short slotIndex, - const unsigned short chanIndex, const char *paramNameList, - unsigned int paramNum ,char *listOfResultCodes); - -CAENHVLIB_API CAENHVRESULT CAENHV_UnSubscribeSystemParams(int handle, short Port, const char *paramNameList, - unsigned int paramNum ,char *listOfResultCodes); - -CAENHVLIB_API CAENHVRESULT CAENHV_UnSubscribeBoardParams(int handle, short Port, const unsigned short slotIndex, - const char *paramNameList, unsigned int paramNum ,char *listOfResultCodes); - -CAENHVLIB_API CAENHVRESULT CAENHV_UnSubscribeChannelParams(int handle, short Port, const unsigned short slotIndex, - const unsigned short chanIndex, const char *paramNameList, - unsigned int paramNum ,char *listOfResultCodes); - -CAENHVLIB_API char *CAENHV_GetError(int handle); - -#ifdef WIN32 -CAENHVLIB_API CAENHVRESULT CAENHV_GetEventData(SOCKET sck, CAENHV_SYSTEMSTATUS_t *SysStatus, - CAENHVEVENT_TYPE_t **EventData, unsigned int *DataNumber); -#else -CAENHVLIB_API CAENHVRESULT CAENHV_GetEventData(int sck, CAENHV_SYSTEMSTATUS_t *SysStatus, - CAENHVEVENT_TYPE_t **EventData, unsigned int *DataNumber); -#endif - -CAENHVLIB_API CAENHVRESULT CAENHV_FreeEventData(CAENHVEVENT_TYPE_t **ListOfItemsData); - -CAENHVLIB_API CAENHVRESULT CAENHV_Free(void *arg); - - -/********************************************/ - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // __CAENHVWRAPPER_H diff --git a/caenlib/CAENHVWrapper-6.3/install.sh b/caenlib/CAENHVWrapper-6.3/install.sh deleted file mode 100755 index f9ba5e1..0000000 --- a/caenlib/CAENHVWrapper-6.3/install.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -DEST_DIR="/usr/share/CAEN/HVWrapper" - -VERSION=`ls bin/x86/libcaenhvwrapper.so.* | grep -Po '\.so\.\K([0-9]+\.)*[0-9]+'` -LIBNAME="libcaenhvwrapper.so.$VERSION" - -DEST_INCLUDE_DIR="/usr/include" - -if [ `getconf LONG_BIT` = "64" ] -then - echo "64 bit version detected" - DEST_LIB_DIR="/usr/lib64" - LIB_DIR="./bin/x86_64" - - if [ ! -d $DEST_LIB_DIR ]; then - DEST_LIB_DIR="/usr/lib" - fi -else - echo "32 bit version detected" - DEST_LIB_DIR="/usr/lib" - LIB_DIR="./bin/x86" -fi - -ERROR="Please ensure you have the rights to execute this command." - -set -e - -echo "Installing library $LIBNAME..." - -if ! [ $(id -u) = 0 ]; then - echo - echo "Unable to get root privileges." - echo $ERROR - exit 1 -fi - -if [ -d $DEST_DIR ]; then - echo "Removing old version..." - rm -rf $DEST_DIR/* || { echo $ERROR ; exit 1; } -fi - -install $LIB_DIR/$LIBNAME $DEST_LIB_DIR -ln -sf $DEST_LIB_DIR/$LIBNAME $DEST_LIB_DIR/libcaenhvwrapper.so - -echo "Creating directories..." - -if [ ! -d $DEST_DIR ]; then - mkdir -p $DEST_DIR || { echo $ERROR ; exit 1; } -fi - -echo "Copying files..." - -cp -vf ./include/CAENHVWrapper.h $DEST_INCLUDE_DIR/CAENHVWrapper.h || { echo $ERROR ; exit 1; } -chmod +r $DEST_INCLUDE_DIR/CAENHVWrapper.h || { echo $ERROR ; exit 1; } - -cp -vf ./doc/CAENHVWrapper.pdf $DEST_DIR/ || { echo $ERROR ; exit 1; } -cp -vf ./CAENHVWrapperReadme.txt $DEST_DIR/ || { echo $ERROR ; exit 1; } -cp -vf ./CAENHVWrapperReleaseNotes.txt $DEST_DIR/ || { echo $ERROR ; exit 1; } -cp -vf ./CAEN_License_Agreement.txt $DEST_DIR/ || { echo $ERROR ; exit 1; } -chmod +r $DEST_DIR/* || { echo $ERROR ; exit 1; } - -echo "Running post-installation triggers..." -ldconfig - -echo "Installation completed." diff --git a/docker/docker-compose.yml b/docker/tedd_caen_hvps/docker-compose.yml similarity index 61% rename from docker/docker-compose.yml rename to docker/tedd_caen_hvps/docker-compose.yml index e87edc3..9fa79bd 100644 --- a/docker/docker-compose.yml +++ b/docker/tedd_caen_hvps/docker-compose.yml @@ -11,18 +11,16 @@ services: - mosquitto_data:/mosquitto/data - mosquitto_log:/mosquitto/log - ./mosquitto/config:/mosquitto/config - - #lv_hmp4040: - # image: centos:low_voltage - # build: ../.. - # restart: always - # stdin_open: true - # tty: true - # volumes: - # - low_voltage:/usr/app/low_voltage/ +# caen_hvps: +# image: tedd_caen_hvps:centos7 +# platform: linux/amd64 +# stdin_open: true +# tty: true +# depends_on: +# - mosquitto volumes: mosquitto_data: mosquitto_log: - #low_voltage: + diff --git a/docker/tedd_caen_hvps/mosquitto/config/mosquitto.conf b/docker/tedd_caen_hvps/mosquitto/config/mosquitto.conf new file mode 100644 index 0000000..32cb957 --- /dev/null +++ b/docker/tedd_caen_hvps/mosquitto/config/mosquitto.conf @@ -0,0 +1,896 @@ +# Config file for mosquitto +# +# See mosquitto.conf(5) for more information. +# +# Default values are shown, uncomment to change. +# +# Use the # character to indicate a comment, but only if it is the +# very first character on the line. + +# ================================================================= +# General configuration +# ================================================================= + +# Use per listener security settings. +# +# It is recommended this option be set before any other options. +# +# If this option is set to true, then all authentication and access control +# options are controlled on a per listener basis. The following options are +# affected: +# +# acl_file +# allow_anonymous +# allow_zero_length_clientid +# auto_id_prefix +# password_file +# plugin +# plugin_opt_* +# psk_file +# +# Note that if set to true, then a durable client (i.e. with clean session set +# to false) that has disconnected will use the ACL settings defined for the +# listener that it was most recently connected to. +# +# The default behaviour is for this to be set to false, which maintains the +# setting behaviour from previous versions of mosquitto. +#per_listener_settings false + + +# This option controls whether a client is allowed to connect with a zero +# length client id or not. This option only affects clients using MQTT v3.1.1 +# and later. If set to false, clients connecting with a zero length client id +# are disconnected. If set to true, clients will be allocated a client id by +# the broker. This means it is only useful for clients with clean session set +# to true. +#allow_zero_length_clientid true + +# If allow_zero_length_clientid is true, this option allows you to set a prefix +# to automatically generated client ids to aid visibility in logs. +# Defaults to 'auto-' +#auto_id_prefix auto- + +# This option affects the scenario when a client subscribes to a topic that has +# retained messages. It is possible that the client that published the retained +# message to the topic had access at the time they published, but that access +# has been subsequently removed. If check_retain_source is set to true, the +# default, the source of a retained message will be checked for access rights +# before it is republished. When set to false, no check will be made and the +# retained message will always be published. This affects all listeners. +#check_retain_source true + +# QoS 1 and 2 messages will be allowed inflight per client until this limit +# is exceeded. Defaults to 0. (No maximum) +# See also max_inflight_messages +#max_inflight_bytes 0 + +# The maximum number of QoS 1 and 2 messages currently inflight per +# client. +# This includes messages that are partway through handshakes and +# those that are being retried. Defaults to 20. Set to 0 for no +# maximum. Setting to 1 will guarantee in-order delivery of QoS 1 +# and 2 messages. +#max_inflight_messages 20 + +# For MQTT v5 clients, it is possible to have the server send a "server +# keepalive" value that will override the keepalive value set by the client. +# This is intended to be used as a mechanism to say that the server will +# disconnect the client earlier than it anticipated, and that the client should +# use the new keepalive value. The max_keepalive option allows you to specify +# that clients may only connect with keepalive less than or equal to this +# value, otherwise they will be sent a server keepalive telling them to use +# max_keepalive. This only applies to MQTT v5 clients. The maximum value +# allowable is 65535. Do not set below 10. +# +# For MQTT v3.1.1 and v3.1 clients, there is no mechanism to tell the client +# what keepalive value they should use. If an MQTT v3.1.1 or v3.1 client +# specifies a keepalive time greater than max_keepalive they will be sent a +# CONNACK message with the "identifier rejected" reason code, and disconnected. +# +#max_keepalive 65535 + +# For MQTT v5 clients, it is possible to have the server send a "maximum packet +# size" value that will instruct the client it will not accept MQTT packets +# with size greater than max_packet_size bytes. This applies to the full MQTT +# packet, not just the payload. Setting this option to a positive value will +# set the maximum packet size to that number of bytes. If a client sends a +# packet which is larger than this value, it will be disconnected. This applies +# to all clients regardless of the protocol version they are using, but v3.1.1 +# and earlier clients will of course not have received the maximum packet size +# information. Defaults to no limit. Setting below 20 bytes is forbidden +# because it is likely to interfere with ordinary client operation, even with +# very small payloads. +#max_packet_size 0 + +# QoS 1 and 2 messages above those currently in-flight will be queued per +# client until this limit is exceeded. Defaults to 0. (No maximum) +# See also max_queued_messages. +# If both max_queued_messages and max_queued_bytes are specified, packets will +# be queued until the first limit is reached. +#max_queued_bytes 0 + +# Set the maximum QoS supported. Clients publishing at a QoS higher than +# specified here will be disconnected. +#max_qos 2 + +# The maximum number of QoS 1 and 2 messages to hold in a queue per client +# above those that are currently in-flight. Defaults to 1000. Set +# to 0 for no maximum (not recommended). +# See also queue_qos0_messages. +# See also max_queued_bytes. +#max_queued_messages 1000 +# +# This option sets the maximum number of heap memory bytes that the broker will +# allocate, and hence sets a hard limit on memory use by the broker. Memory +# requests that exceed this value will be denied. The effect will vary +# depending on what has been denied. If an incoming message is being processed, +# then the message will be dropped and the publishing client will be +# disconnected. If an outgoing message is being sent, then the individual +# message will be dropped and the receiving client will be disconnected. +# Defaults to no limit. +#memory_limit 0 + +# This option sets the maximum publish payload size that the broker will allow. +# Received messages that exceed this size will not be accepted by the broker. +# The default value is 0, which means that all valid MQTT messages are +# accepted. MQTT imposes a maximum payload size of 268435455 bytes. +#message_size_limit 0 + +# This option allows persistent clients (those with clean session set to false) +# to be removed if they do not reconnect within a certain time frame. +# +# This is a non-standard option in MQTT V3.1 but allowed in MQTT v3.1.1. +# +# Badly designed clients may set clean session to false whilst using a randomly +# generated client id. This leads to persistent clients that will never +# reconnect. This option allows these clients to be removed. +# +# The expiration period should be an integer followed by one of h d w m y for +# hour, day, week, month and year respectively. For example +# +# persistent_client_expiration 2m +# persistent_client_expiration 14d +# persistent_client_expiration 1y +# +# The default if not set is to never expire persistent clients. +#persistent_client_expiration + +# Write process id to a file. Default is a blank string which means +# a pid file shouldn't be written. +# This should be set to /var/run/mosquitto/mosquitto.pid if mosquitto is +# being run automatically on boot with an init script and +# start-stop-daemon or similar. +#pid_file + +# Set to true to queue messages with QoS 0 when a persistent client is +# disconnected. These messages are included in the limit imposed by +# max_queued_messages and max_queued_bytes +# Defaults to false. +# This is a non-standard option for the MQTT v3.1 spec but is allowed in +# v3.1.1. +#queue_qos0_messages false + +# Set to false to disable retained message support. If a client publishes a +# message with the retain bit set, it will be disconnected if this is set to +# false. +#retain_available true + +# Disable Nagle's algorithm on client sockets. This has the effect of reducing +# latency of individual messages at the potential cost of increasing the number +# of packets being sent. +#set_tcp_nodelay false + +# Time in seconds between updates of the $SYS tree. +# Set to 0 to disable the publishing of the $SYS tree. +#sys_interval 10 + +# The MQTT specification requires that the QoS of a message delivered to a +# subscriber is never upgraded to match the QoS of the subscription. Enabling +# this option changes this behaviour. If upgrade_outgoing_qos is set true, +# messages sent to a subscriber will always match the QoS of its subscription. +# This is a non-standard option explicitly disallowed by the spec. +#upgrade_outgoing_qos false + +# When run as root, drop privileges to this user and its primary +# group. +# Set to root to stay as root, but this is not recommended. +# If set to "mosquitto", or left unset, and the "mosquitto" user does not exist +# then it will drop privileges to the "nobody" user instead. +# If run as a non-root user, this setting has no effect. +# Note that on Windows this has no effect and so mosquitto should be started by +# the user you wish it to run as. +#user mosquitto + +# ================================================================= +# Listeners +# ================================================================= + +# Listen on a port/ip address combination. By using this variable +# multiple times, mosquitto can listen on more than one port. If +# this variable is used and neither bind_address nor port given, +# then the default listener will not be started. +# The port number to listen on must be given. Optionally, an ip +# address or host name may be supplied as a second argument. In +# this case, mosquitto will attempt to bind the listener to that +# address and so restrict access to the associated network and +# interface. By default, mosquitto will listen on all interfaces. +# Note that for a websockets listener it is not possible to bind to a host +# name. +# +# On systems that support Unix Domain Sockets, it is also possible +# to create a # Unix socket rather than opening a TCP socket. In +# this case, the port number should be set to 0 and a unix socket +# path must be provided, e.g. +# listener 0 /tmp/mosquitto.sock +# +# listener port-number [ip address/host name/unix socket path] +listener 1883 + +# By default, a listener will attempt to listen on all supported IP protocol +# versions. If you do not have an IPv4 or IPv6 interface you may wish to +# disable support for either of those protocol versions. In particular, note +# that due to the limitations of the websockets library, it will only ever +# attempt to open IPv6 sockets if IPv6 support is compiled in, and so will fail +# if IPv6 is not available. +# +# Set to `ipv4` to force the listener to only use IPv4, or set to `ipv6` to +# force the listener to only use IPv6. If you want support for both IPv4 and +# IPv6, then do not use the socket_domain option. +# +#socket_domain + +# Bind the listener to a specific interface. This is similar to +# the [ip address/host name] part of the listener definition, but is useful +# when an interface has multiple addresses or the address may change. If used +# with the [ip address/host name] part of the listener definition, then the +# bind_interface option will take priority. +# Not available on Windows. +# +# Example: bind_interface eth0 +#bind_interface + +# When a listener is using the websockets protocol, it is possible to serve +# http data as well. Set http_dir to a directory which contains the files you +# wish to serve. If this option is not specified, then no normal http +# connections will be possible. +#http_dir + +# The maximum number of client connections to allow. This is +# a per listener setting. +# Default is -1, which means unlimited connections. +# Note that other process limits mean that unlimited connections +# are not really possible. Typically the default maximum number of +# connections possible is around 1024. +#max_connections -1 + +# The listener can be restricted to operating within a topic hierarchy using +# the mount_point option. This is achieved be prefixing the mount_point string +# to all topics for any clients connected to this listener. This prefixing only +# happens internally to the broker; the client will not see the prefix. +#mount_point + +# Choose the protocol to use when listening. +# This can be either mqtt or websockets. +# Certificate based TLS may be used with websockets, except that only the +# cafile, certfile, keyfile, ciphers, and ciphers_tls13 options are supported. +#protocol mqtt + +# Set use_username_as_clientid to true to replace the clientid that a client +# connected with with its username. This allows authentication to be tied to +# the clientid, which means that it is possible to prevent one client +# disconnecting another by using the same clientid. +# If a client connects with no username it will be disconnected as not +# authorised when this option is set to true. +# Do not use in conjunction with clientid_prefixes. +# See also use_identity_as_username. +#use_username_as_clientid + +# Change the websockets headers size. This is a global option, it is not +# possible to set per listener. This option sets the size of the buffer used in +# the libwebsockets library when reading HTTP headers. If you are passing large +# header data such as cookies then you may need to increase this value. If left +# unset, or set to 0, then the default of 1024 bytes will be used. +#websockets_headers_size + +# ----------------------------------------------------------------- +# Certificate based SSL/TLS support +# ----------------------------------------------------------------- +# The following options can be used to enable certificate based SSL/TLS support +# for this listener. Note that the recommended port for MQTT over TLS is 8883, +# but this must be set manually. +# +# See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS +# support" section. Only one of certificate or PSK encryption support can be +# enabled for any listener. + +# Both of certfile and keyfile must be defined to enable certificate based +# TLS encryption. + +# Path to the PEM encoded server certificate. +#certfile + +# Path to the PEM encoded keyfile. +#keyfile + +# If you wish to control which encryption ciphers are used, use the ciphers +# option. The list of available ciphers can be optained using the "openssl +# ciphers" command and should be provided in the same format as the output of +# that command. This applies to TLS 1.2 and earlier versions only. Use +# ciphers_tls1.3 for TLS v1.3. +#ciphers + +# Choose which TLS v1.3 ciphersuites are used for this listener. +# Defaults to "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256" +#ciphers_tls1.3 + +# If you have require_certificate set to true, you can create a certificate +# revocation list file to revoke access to particular client certificates. If +# you have done this, use crlfile to point to the PEM encoded revocation file. +#crlfile + +# To allow the use of ephemeral DH key exchange, which provides forward +# security, the listener must load DH parameters. This can be specified with +# the dhparamfile option. The dhparamfile can be generated with the command +# e.g. "openssl dhparam -out dhparam.pem 2048" +#dhparamfile + +# By default an TLS enabled listener will operate in a similar fashion to a +# https enabled web server, in that the server has a certificate signed by a CA +# and the client will verify that it is a trusted certificate. The overall aim +# is encryption of the network traffic. By setting require_certificate to true, +# the client must provide a valid certificate in order for the network +# connection to proceed. This allows access to the broker to be controlled +# outside of the mechanisms provided by MQTT. +#require_certificate false + +# cafile and capath define methods of accessing the PEM encoded +# Certificate Authority certificates that will be considered trusted when +# checking incoming client certificates. +# cafile defines the path to a file containing the CA certificates. +# capath defines a directory that will be searched for files +# containing the CA certificates. For capath to work correctly, the +# certificate files must have ".crt" as the file ending and you must run +# "openssl rehash " each time you add/remove a certificate. +#cafile +#capath + + +# If require_certificate is true, you may set use_identity_as_username to true +# to use the CN value from the client certificate as a username. If this is +# true, the password_file option will not be used for this listener. +#use_identity_as_username false + +# ----------------------------------------------------------------- +# Pre-shared-key based SSL/TLS support +# ----------------------------------------------------------------- +# The following options can be used to enable PSK based SSL/TLS support for +# this listener. Note that the recommended port for MQTT over TLS is 8883, but +# this must be set manually. +# +# See also the mosquitto-tls man page and the "Certificate based SSL/TLS +# support" section. Only one of certificate or PSK encryption support can be +# enabled for any listener. + +# The psk_hint option enables pre-shared-key support for this listener and also +# acts as an identifier for this listener. The hint is sent to clients and may +# be used locally to aid authentication. The hint is a free form string that +# doesn't have much meaning in itself, so feel free to be creative. +# If this option is provided, see psk_file to define the pre-shared keys to be +# used or create a security plugin to handle them. +#psk_hint + +# When using PSK, the encryption ciphers used will be chosen from the list of +# available PSK ciphers. If you want to control which ciphers are available, +# use the "ciphers" option. The list of available ciphers can be optained +# using the "openssl ciphers" command and should be provided in the same format +# as the output of that command. +#ciphers + +# Set use_identity_as_username to have the psk identity sent by the client used +# as its username. Authentication will be carried out using the PSK rather than +# the MQTT username/password and so password_file will not be used for this +# listener. +#use_identity_as_username false + + +# ================================================================= +# Persistence +# ================================================================= + +# If persistence is enabled, save the in-memory database to disk +# every autosave_interval seconds. If set to 0, the persistence +# database will only be written when mosquitto exits. See also +# autosave_on_changes. +# Note that writing of the persistence database can be forced by +# sending mosquitto a SIGUSR1 signal. +#autosave_interval 1800 + +# If true, mosquitto will count the number of subscription changes, retained +# messages received and queued messages and if the total exceeds +# autosave_interval then the in-memory database will be saved to disk. +# If false, mosquitto will save the in-memory database to disk by treating +# autosave_interval as a time in seconds. +#autosave_on_changes false + +# Save persistent message data to disk (true/false). +# This saves information about all messages, including +# subscriptions, currently in-flight messages and retained +# messages. +# retained_persistence is a synonym for this option. +#persistence false + +# The filename to use for the persistent database, not including +# the path. +#persistence_file mosquitto.db + +# Location for persistent database. +# Default is an empty string (current directory). +# Set to e.g. /var/lib/mosquitto if running as a proper service on Linux or +# similar. +#persistence_location + + +# ================================================================= +# Logging +# ================================================================= + +# Places to log to. Use multiple log_dest lines for multiple +# logging destinations. +# Possible destinations are: stdout stderr syslog topic file dlt +# +# stdout and stderr log to the console on the named output. +# +# syslog uses the userspace syslog facility which usually ends up +# in /var/log/messages or similar. +# +# topic logs to the broker topic '$SYS/broker/log/', +# where severity is one of D, E, W, N, I, M which are debug, error, +# warning, notice, information and message. Message type severity is used by +# the subscribe/unsubscribe log_types and publishes log messages to +# $SYS/broker/log/M/susbcribe or $SYS/broker/log/M/unsubscribe. +# +# The file destination requires an additional parameter which is the file to be +# logged to, e.g. "log_dest file /var/log/mosquitto.log". The file will be +# closed and reopened when the broker receives a HUP signal. Only a single file +# destination may be configured. +# +# The dlt destination is for the automotive `Diagnostic Log and Trace` tool. +# This requires that Mosquitto has been compiled with DLT support. +# +# Note that if the broker is running as a Windows service it will default to +# "log_dest none" and neither stdout nor stderr logging is available. +# Use "log_dest none" if you wish to disable logging. +#log_dest stderr + +# Types of messages to log. Use multiple log_type lines for logging +# multiple types of messages. +# Possible types are: debug, error, warning, notice, information, +# none, subscribe, unsubscribe, websockets, all. +# Note that debug type messages are for decoding the incoming/outgoing +# network packets. They are not logged in "topics". +#log_type error +#log_type warning +#log_type notice +#log_type information + + +# If set to true, client connection and disconnection messages will be included +# in the log. +#connection_messages true + +# If using syslog logging (not on Windows), messages will be logged to the +# "daemon" facility by default. Use the log_facility option to choose which of +# local0 to local7 to log to instead. The option value should be an integer +# value, e.g. "log_facility 5" to use local5. +#log_facility + +# If set to true, add a timestamp value to each log message. +#log_timestamp true + +# Set the format of the log timestamp. If left unset, this is the number of +# seconds since the Unix epoch. +# This is a free text string which will be passed to the strftime function. To +# get an ISO 8601 datetime, for example: +# log_timestamp_format %Y-%m-%dT%H:%M:%S +#log_timestamp_format + +# Change the websockets logging level. This is a global option, it is not +# possible to set per listener. This is an integer that is interpreted by +# libwebsockets as a bit mask for its lws_log_levels enum. See the +# libwebsockets documentation for more details. "log_type websockets" must also +# be enabled. +#websockets_log_level 0 + + +# ================================================================= +# Security +# ================================================================= + +# If set, only clients that have a matching prefix on their +# clientid will be allowed to connect to the broker. By default, +# all clients may connect. +# For example, setting "secure-" here would mean a client "secure- +# client" could connect but another with clientid "mqtt" couldn't. +#clientid_prefixes + +# Boolean value that determines whether clients that connect +# without providing a username are allowed to connect. If set to +# false then a password file should be created (see the +# password_file option) to control authenticated client access. +# +# Defaults to false, unless there are no listeners defined in the configuration +# file, in which case it is set to true, but connections are only allowed from +# the local machine. +allow_anonymous true + +# ----------------------------------------------------------------- +# Default authentication and topic access control +# ----------------------------------------------------------------- + +# Control access to the broker using a password file. This file can be +# generated using the mosquitto_passwd utility. If TLS support is not compiled +# into mosquitto (it is recommended that TLS support should be included) then +# plain text passwords are used, in which case the file should be a text file +# with lines in the format: +# username:password +# The password (and colon) may be omitted if desired, although this +# offers very little in the way of security. +# +# See the TLS client require_certificate and use_identity_as_username options +# for alternative authentication options. If a plugin is used as well as +# password_file, the plugin check will be made first. +#password_file + +# Access may also be controlled using a pre-shared-key file. This requires +# TLS-PSK support and a listener configured to use it. The file should be text +# lines in the format: +# identity:key +# The key should be in hexadecimal format without a leading "0x". +# If an plugin is used as well, the plugin check will be made first. +#psk_file + +# Control access to topics on the broker using an access control list +# file. If this parameter is defined then only the topics listed will +# have access. +# If the first character of a line of the ACL file is a # it is treated as a +# comment. +# Topic access is added with lines of the format: +# +# topic [read|write|readwrite|deny] +# +# The access type is controlled using "read", "write", "readwrite" or "deny". +# This parameter is optional (unless contains a space character) - if +# not given then the access is read/write. can contain the + or # +# wildcards as in subscriptions. +# +# The "deny" option can used to explicity deny access to a topic that would +# otherwise be granted by a broader read/write/readwrite statement. Any "deny" +# topics are handled before topics that grant read/write access. +# +# The first set of topics are applied to anonymous clients, assuming +# allow_anonymous is true. User specific topic ACLs are added after a +# user line as follows: +# +# user +# +# The username referred to here is the same as in password_file. It is +# not the clientid. +# +# +# If is also possible to define ACLs based on pattern substitution within the +# topic. The patterns available for substition are: +# +# %c to match the client id of the client +# %u to match the username of the client +# +# The substitution pattern must be the only text for that level of hierarchy. +# +# The form is the same as for the topic keyword, but using pattern as the +# keyword. +# Pattern ACLs apply to all users even if the "user" keyword has previously +# been given. +# +# If using bridges with usernames and ACLs, connection messages can be allowed +# with the following pattern: +# pattern write $SYS/broker/connection/%c/state +# +# pattern [read|write|readwrite] +# +# Example: +# +# pattern write sensor/%u/data +# +# If an plugin is used as well as acl_file, the plugin check will be +# made first. +#acl_file + +# ----------------------------------------------------------------- +# External authentication and topic access plugin options +# ----------------------------------------------------------------- + +# External authentication and access control can be supported with the +# plugin option. This is a path to a loadable plugin. See also the +# plugin_opt_* options described below. +# +# The plugin option can be specified multiple times to load multiple +# plugins. The plugins will be processed in the order that they are specified +# here. If the plugin option is specified alongside either of +# password_file or acl_file then the plugin checks will be made first. +# +# If the per_listener_settings option is false, the plugin will be apply to all +# listeners. If per_listener_settings is true, then the plugin will apply to +# the current listener being defined only. +# +# This option is also available as `auth_plugin`, but this use is deprecated +# and will be removed in the future. +# +#plugin + +# If the plugin option above is used, define options to pass to the +# plugin here as described by the plugin instructions. All options named +# using the format plugin_opt_* will be passed to the plugin, for example: +# +# This option is also available as `auth_opt_*`, but this use is deprecated +# and will be removed in the future. +# +# plugin_opt_db_host +# plugin_opt_db_port +# plugin_opt_db_username +# plugin_opt_db_password + + +# ================================================================= +# Bridges +# ================================================================= + +# A bridge is a way of connecting multiple MQTT brokers together. +# Create a new bridge using the "connection" option as described below. Set +# options for the bridges using the remaining parameters. You must specify the +# address and at least one topic to subscribe to. +# +# Each connection must have a unique name. +# +# The address line may have multiple host address and ports specified. See +# below in the round_robin description for more details on bridge behaviour if +# multiple addresses are used. Note that if you use an IPv6 address, then you +# are required to specify a port. +# +# The direction that the topic will be shared can be chosen by +# specifying out, in or both, where the default value is out. +# The QoS level of the bridged communication can be specified with the next +# topic option. The default QoS level is 0, to change the QoS the topic +# direction must also be given. +# +# The local and remote prefix options allow a topic to be remapped when it is +# bridged to/from the remote broker. This provides the ability to place a topic +# tree in an appropriate location. +# +# For more details see the mosquitto.conf man page. +# +# Multiple topics can be specified per connection, but be careful +# not to create any loops. +# +# If you are using bridges with cleansession set to false (the default), then +# you may get unexpected behaviour from incoming topics if you change what +# topics you are subscribing to. This is because the remote broker keeps the +# subscription for the old topic. If you have this problem, connect your bridge +# with cleansession set to true, then reconnect with cleansession set to false +# as normal. +#connection +#address [:] [[:]] +#topic [[[out | in | both] qos-level] local-prefix remote-prefix] + +# If you need to have the bridge connect over a particular network interface, +# use bridge_bind_address to tell the bridge which local IP address the socket +# should bind to, e.g. `bridge_bind_address 192.168.1.10` +#bridge_bind_address + +# If a bridge has topics that have "out" direction, the default behaviour is to +# send an unsubscribe request to the remote broker on that topic. This means +# that changing a topic direction from "in" to "out" will not keep receiving +# incoming messages. Sending these unsubscribe requests is not always +# desirable, setting bridge_attempt_unsubscribe to false will disable sending +# the unsubscribe request. +#bridge_attempt_unsubscribe true + +# Set the version of the MQTT protocol to use with for this bridge. Can be one +# of mqttv50, mqttv311 or mqttv31. Defaults to mqttv311. +#bridge_protocol_version mqttv311 + +# Set the clean session variable for this bridge. +# When set to true, when the bridge disconnects for any reason, all +# messages and subscriptions will be cleaned up on the remote +# broker. Note that with cleansession set to true, there may be a +# significant amount of retained messages sent when the bridge +# reconnects after losing its connection. +# When set to false, the subscriptions and messages are kept on the +# remote broker, and delivered when the bridge reconnects. +#cleansession false + +# Set the amount of time a bridge using the lazy start type must be idle before +# it will be stopped. Defaults to 60 seconds. +#idle_timeout 60 + +# Set the keepalive interval for this bridge connection, in +# seconds. +#keepalive_interval 60 + +# Set the clientid to use on the local broker. If not defined, this defaults to +# 'local.'. If you are bridging a broker to itself, it is important +# that local_clientid and clientid do not match. +#local_clientid + +# If set to true, publish notification messages to the local and remote brokers +# giving information about the state of the bridge connection. Retained +# messages are published to the topic $SYS/broker/connection//state +# unless the notification_topic option is used. +# If the message is 1 then the connection is active, or 0 if the connection has +# failed. +# This uses the last will and testament feature. +#notifications true + +# Choose the topic on which notification messages for this bridge are +# published. If not set, messages are published on the topic +# $SYS/broker/connection//state +#notification_topic + +# Set the client id to use on the remote end of this bridge connection. If not +# defined, this defaults to 'name.hostname' where name is the connection name +# and hostname is the hostname of this computer. +# This replaces the old "clientid" option to avoid confusion. "clientid" +# remains valid for the time being. +#remote_clientid + +# Set the password to use when connecting to a broker that requires +# authentication. This option is only used if remote_username is also set. +# This replaces the old "password" option to avoid confusion. "password" +# remains valid for the time being. +#remote_password + +# Set the username to use when connecting to a broker that requires +# authentication. +# This replaces the old "username" option to avoid confusion. "username" +# remains valid for the time being. +#remote_username + +# Set the amount of time a bridge using the automatic start type will wait +# until attempting to reconnect. +# This option can be configured to use a constant delay time in seconds, or to +# use a backoff mechanism based on "Decorrelated Jitter", which adds a degree +# of randomness to when the restart occurs. +# +# Set a constant timeout of 20 seconds: +# restart_timeout 20 +# +# Set backoff with a base (start value) of 10 seconds and a cap (upper limit) of +# 60 seconds: +# restart_timeout 10 30 +# +# Defaults to jitter with a base of 5 and cap of 30 +#restart_timeout 5 30 + +# If the bridge has more than one address given in the address/addresses +# configuration, the round_robin option defines the behaviour of the bridge on +# a failure of the bridge connection. If round_robin is false, the default +# value, then the first address is treated as the main bridge connection. If +# the connection fails, the other secondary addresses will be attempted in +# turn. Whilst connected to a secondary bridge, the bridge will periodically +# attempt to reconnect to the main bridge until successful. +# If round_robin is true, then all addresses are treated as equals. If a +# connection fails, the next address will be tried and if successful will +# remain connected until it fails +#round_robin false + +# Set the start type of the bridge. This controls how the bridge starts and +# can be one of three types: automatic, lazy and once. Note that RSMB provides +# a fourth start type "manual" which isn't currently supported by mosquitto. +# +# "automatic" is the default start type and means that the bridge connection +# will be started automatically when the broker starts and also restarted +# after a short delay (30 seconds) if the connection fails. +# +# Bridges using the "lazy" start type will be started automatically when the +# number of queued messages exceeds the number set with the "threshold" +# parameter. It will be stopped automatically after the time set by the +# "idle_timeout" parameter. Use this start type if you wish the connection to +# only be active when it is needed. +# +# A bridge using the "once" start type will be started automatically when the +# broker starts but will not be restarted if the connection fails. +#start_type automatic + +# Set the number of messages that need to be queued for a bridge with lazy +# start type to be restarted. Defaults to 10 messages. +# Must be less than max_queued_messages. +#threshold 10 + +# If try_private is set to true, the bridge will attempt to indicate to the +# remote broker that it is a bridge not an ordinary client. If successful, this +# means that loop detection will be more effective and that retained messages +# will be propagated correctly. Not all brokers support this feature so it may +# be necessary to set try_private to false if your bridge does not connect +# properly. +#try_private true + +# Some MQTT brokers do not allow retained messages. MQTT v5 gives a mechanism +# for brokers to tell clients that they do not support retained messages, but +# this is not possible for MQTT v3.1.1 or v3.1. If you need to bridge to a +# v3.1.1 or v3.1 broker that does not support retained messages, set the +# bridge_outgoing_retain option to false. This will remove the retain bit on +# all outgoing messages to that bridge, regardless of any other setting. +#bridge_outgoing_retain true + +# If you wish to restrict the size of messages sent to a remote bridge, use the +# bridge_max_packet_size option. This sets the maximum number of bytes for +# the total message, including headers and payload. +# Note that MQTT v5 brokers may provide their own maximum-packet-size property. +# In this case, the smaller of the two limits will be used. +# Set to 0 for "unlimited". +#bridge_max_packet_size 0 + + +# ----------------------------------------------------------------- +# Certificate based SSL/TLS support +# ----------------------------------------------------------------- +# Either bridge_cafile or bridge_capath must be defined to enable TLS support +# for this bridge. +# bridge_cafile defines the path to a file containing the +# Certificate Authority certificates that have signed the remote broker +# certificate. +# bridge_capath defines a directory that will be searched for files containing +# the CA certificates. For bridge_capath to work correctly, the certificate +# files must have ".crt" as the file ending and you must run "openssl rehash +# " each time you add/remove a certificate. +#bridge_cafile +#bridge_capath + + +# If the remote broker has more than one protocol available on its port, e.g. +# MQTT and WebSockets, then use bridge_alpn to configure which protocol is +# requested. Note that WebSockets support for bridges is not yet available. +#bridge_alpn + +# When using certificate based encryption, bridge_insecure disables +# verification of the server hostname in the server certificate. This can be +# useful when testing initial server configurations, but makes it possible for +# a malicious third party to impersonate your server through DNS spoofing, for +# example. Use this option in testing only. If you need to resort to using this +# option in a production environment, your setup is at fault and there is no +# point using encryption. +#bridge_insecure false + +# Path to the PEM encoded client certificate, if required by the remote broker. +#bridge_certfile + +# Path to the PEM encoded client private key, if required by the remote broker. +#bridge_keyfile + +# ----------------------------------------------------------------- +# PSK based SSL/TLS support +# ----------------------------------------------------------------- +# Pre-shared-key encryption provides an alternative to certificate based +# encryption. A bridge can be configured to use PSK with the bridge_identity +# and bridge_psk options. These are the client PSK identity, and pre-shared-key +# in hexadecimal format with no "0x". Only one of certificate and PSK based +# encryption can be used on one +# bridge at once. +#bridge_identity +#bridge_psk + + +# ================================================================= +# External config files +# ================================================================= + +# External configuration files may be included by using the +# include_dir option. This defines a directory that will be searched +# for config files. All files that end in '.conf' will be loaded as +# a configuration file. It is best to have this as the last option +# in the main file. This option will only be processed from the main +# configuration file. The directory specified must not contain the +# main configuration file. +# Files within include_dir will be loaded sorted in case-sensitive +# alphabetical order, with capital letters ordered first. If this option is +# given multiple times, all of the files from the first instance will be +# processed before the next instance. See the man page for examples. +#include_dir diff --git a/hvps/hvps.cfg b/hvps/hvps.cfg deleted file mode 100644 index e342079..0000000 --- a/hvps/hvps.cfg +++ /dev/null @@ -1,38 +0,0 @@ -# Global Section -max_bias_voltage = 10 -# max_ramp_rate V/sec, probably want to keep this under <=50 -max_ramp_rate = 5 -default_slot = 0 #(slot4: LV channels num: 8 slot9 :HV channels num=12) -default_hvps = HVPS_ds-hvps - -# All power supplies must start with HVPS_ -[HVPS_ds-hvps] -device_name = ds-hvps -# Type 13 : Internet TCP/IP -#system_type = 13 #CAENHV_BOARD_TYPE: SMARTHV=13 //check CAENHVWrapper.h -system_type = 2 #CAENHV_BOARD_TYPE: SY4527 = 2 -link_type = 0 #CAENHV_LINK_TYPE=TCP/IP -# This can be a hostname or an IP address -#hostname = 142.90.105.151 -hostname = 10.2.2.20 #CAENHV IP 192.168.0.1 -# Leave username and password blank if your unit does not have these values -#User ID: admin Password: admin -username = admin -password = admin - - # All channels must start with CH_ - [[CH_0]] - channel_num = 0 - Enabled = True - #detector_name = "envy" - #detector_position = 1 - max_bias_voltage = 10 - ramp_rate = 5 - - [[CH_1]] - channel_num = 1 - Enabled = True - #detector_name = "rage" - #detector_position = 2 - max_bias_voltage = 10 - ramp_rate = 5 diff --git a/hvps/hvps_ctrl.py b/hvps/hvps_ctrl.py deleted file mode 100755 index caf8061..0000000 --- a/hvps/hvps_ctrl.py +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env python3 - -# ************************************************************************************* -# By: Jon Ringuette -# Created: March 23 2020 - During the great plague -# Purpose: Provide a wrapper for CAEN's C library to control the CAEN HVPS which biases -# the HPGe's (8pi's and ULGe) -# CAEN manaul and c-api : https://www.caen.it/products/caen-hv-wrapper-library/ -# ************************************************************************************* - -import argparse -import configparser -from configobj import ConfigObj -import sys -import os -from pprint import pprint -import time -from os.path import exists - -from lib.hvps import HVPS_Class # Class that contains high level wrapper functions for the HVPS, - - -# ************************************************************************************* -# process_config_file: -# Process config file using the configparser library -# ************************************************************************************* -class hvps_ctrl: - def __init__(self, config_dict, args, my_slot): - self.config_dict = config_dict - self.my_slot = my_slot - self.args = args - self.default_hvps_key = None - self.HVPS = [] - self.channel_selected = args.channel_selected - self.hvps_name = args.hvps_name - self.iset_current = 0 - for mykey in self.config_dict.keys(): - if mykey.startswith('HVPS_'): - self.default_hvps_key = mykey - self.HVPS.append(HVPS_Class(self.config_dict[mykey])) - - if len(self.HVPS) == 0: - print("Could not find HVPS entry in config file.") - exit(1) - self.force = self.args.force - self.channel_entry = self.find_channel_in_config() # Get the config entry for channel - - def confirm_channel(self, action, new_voltage): - if self.force is True: - return True - # confirm_channel: Prompt user to confirm a change to the voltage applied to a channel, requires a 'yes' or 'no' answer - channel_status_list = self.HVPS[0].status_channel(None, self.my_slot, int(self.channel_entry['channel_num'])) - # Iterate over the status of channels until reaching the VSet parameter we're looking for which is the current voltage - current_voltage = int(next(item for item in channel_status_list[0][0]['chan_info'] if item['parameter'] == 'VSet')['value']) - print("-------------------------------------") - print("CHANNEL NUMBER : %i " % int(self.channel_entry['channel_num'])) - print("DETECTOR NAME : %s" % self.channel_entry['detector_name']) - # print("Detector Position : %i" % chan_obj.detector_position) - print("MAX BIAS VOLTAGE : %i V" % int(self.channel_entry['max_bias_voltage'])) - print("RAMP RATE : %i V/sec" % int(self.channel_entry['ramp_rate'])) - print("CURRNET BIAS VOLTAGE : ", current_voltage) - print("** NEW BIAS VOLTAGE : ", new_voltage) - print("-------------------------------------") - user_confirmation_input = input("Are you sure you want to %s this channel? (y/n) : " % action.upper()) - if user_confirmation_input.upper() == "Y": - return True - else: - print("Could not confirm action, exiting ...") - sys.exit(1) - - def get_max_voltage_ramp_rate(self): - # get_max_voltage_ramp_rate: Pull out the Max Ramp Rate (RUp) from the config file for a channel - # Also go ahead and check that the ramp rate set doesn't exceed the - # max set in the config file - my_ramp_rate = 0 - if int(self.channel_entry['ramp_rate']) < int(self.config_dict['max_ramp_rate']): - my_ramp_rate = int(self.channel_entry['ramp_rate']) - else: - my_ramp_rate = int(self.config_dict['max_ramp_rate']) - return int(my_ramp_rate) - - def find_channel_in_config(self): - # find_channel_in_config: Checks that there is a config entry for the channel before taking action on it and confirms if the channel is enabled - my_config_dict = self.config_dict[self.default_hvps_key] - channel_entry = None - for my_channel_key in my_config_dict.keys(): - if my_channel_key.startswith('CH_'): - if (my_config_dict[my_channel_key]['channel_num'] == str(self.channel_selected)) and my_config_dict[my_channel_key]['Enabled'].upper() == "True".upper(): # If channel exists in config file AND it is marked as ENABLED - channel_entry = my_config_dict[my_channel_key] - return channel_entry # Return the dict for the specified channel - - def compare_voltage(self, my_new_bias_voltage): - # compare_voltage: Check what the current voltage of the channel and determine if it needs to be further biased on - # user request. - max_channel_bias_voltage = self.channel_entry['max_bias_voltage'] - max_global_bias_voltage = self.config_dict['max_bias_voltage'] - channel = self.channel_entry['channel_num'] - perform_bias = False - new_bias_voltage = int(my_new_bias_voltage) - channel_status_list = self.HVPS[0].status_channel(None, self.my_slot, int(channel)) - # Iterate over the status of channels until reaching the VSet parameter we're looking for which is the current voltage - current_voltage = int(next(item for item in channel_status_list[0][0]['chan_info'] if item['parameter'] == 'VSet')['value']) - - if int(new_bias_voltage) > int(max_channel_bias_voltage): - print("!! Can not exceed this channels maximum BIAS voltage set in the config file:", max_channel_bias_voltage) - exit(1) - elif int(new_bias_voltage) > int(max_global_bias_voltage): - print("!! Can not exceed this global maximum BIAS voltage set in the config file:", max_global_bias_voltage) - exit(1) - if current_voltage == int(new_bias_voltage): # Check if voltage is already the requested voltage - print("!! Channel:", channel, "is already set to bias voltage:", current_voltage) - exit(1) - else: # If it is not then we will prompt to confirm the change - perform_bias = self.confirm_channel("BIAS", my_new_bias_voltage) - return perform_bias - - def bias(self): - # bias: Runs checks and calls appropriate functions to bias a channel - max_ramp_rate = 10 - if (self.channel_selected is not None): # If we should go with the default voltage set in the config file - if self.channel_entry is not None: - if self.args.bias_voltage is not None: - my_new_bias_voltage = self.args.bias_voltage - else: - my_new_bias_voltage = self.channel_entry['max_bias_voltage'] - max_ramp_rate = self.get_max_voltage_ramp_rate() # Get the max volatage ramp rate RUp - if self.compare_voltage(my_new_bias_voltage) is True: # Check if we need to actually change the voltage or if it is already set - self.HVPS[0].set_channel_param(self.hvps_name, self.my_slot, int(self.channel_selected), 'RUp', max_ramp_rate) # Ensure the ramp up value is set to something safe - self.HVPS[0].set_channel_param(self.hvps_name, self.my_slot, int(self.channel_selected), 'RDwn', max_ramp_rate) # Ensure the ramp up value is set to something safe - self.HVPS[0].set_channel_param(self.hvps_name, self.my_slot, int(self.channel_selected), 'ISet', self.iset_current) # Ensure we have 0 current set - time.sleep(1) # Sleep for a moment to make sure the setting has taken effect - self.HVPS[0].bias_channel(self.hvps_name, self.my_slot, int(self.channel_selected), int(my_new_bias_voltage)) # Bias the channel - else: - print("!! Must specify a BIAS voltage via --bias_voltage or put an entry for the channel in the config file and ensure Enabled is True") - exit(1) - elif self.channel_selected is None: - print("!! Must specify --chan") - exit(1) - return - - def unbias_channel(self): - # unbias_channel: Drop VSet to 0 and also ensure RDwn (ramp down) voltage is set correctly - max_ramp_rate = self.get_max_voltage_ramp_rate() - if self.confirm_channel("UNBIAS", 0): - self.HVPS[0].set_channel_param(self.hvps_name, self.my_slot, int(self.channel_selected), 'RDwn', max_ramp_rate) # Ensure the ramp up value is set to something safe - self.HVPS[0].unbias_channel(self.hvps_name, self.my_slot, int(self.channel_selected)) - - -def process_cli_args(args, config_dict): - # process_cli_args: Mostly does just that, processes command line arguements and runs appropriate tests - if "default_slot" in config_dict.keys(): - my_slot = int(config_dict["default_slot"]) - else: - my_slot = args.slot_selected - - my_hvps_ctrl = hvps_ctrl(config_dict, args, my_slot) - my_hvps_ctrl.iset_current = args.iset_current - if args.status == True: - if args.channel_selected is None: - my_hvps_ctrl.HVPS[0].status_all_channels(args.hvps_name) - else: - channel_status_list = my_hvps_ctrl.HVPS[0].status_channel(args.hvps_name, my_slot, args.channel_selected) - my_hvps_ctrl.HVPS[0].show_channel_status(channel_status_list) - elif args.bias_voltage != None: - my_hvps_ctrl.bias() - - elif args.unbias == True: - if args.channel_selected is None: - print("Must specify --chan") - else: - my_hvps_ctrl.unbias_channel() - - elif args.action == "set_param": - if args.channel_selected is None: - print("Must specify --chan") - else: - if args.param in ['Pon', 'Pw', 'PDwn', 'TripInt', 'TripExt']: - args.param_value = int(args.param_value) - else: - args.param_value = float(args.param_value) - - my_hvps_ctrl.HVPS[0].set_channel_param(args.hvps_name, my_slot, int(args.channel_selected), args.param, args.param_value) - elif args.chan_enable is not None: - my_hvps_ctrl.HVPS[0].set_channel_param(args.hvps_name, my_slot, int(args.chan_enable), 'Pw', 1) # Ensure we have 0 current set - elif args.chan_disable is not None: - my_hvps_ctrl.HVPS[0].set_channel_param(args.hvps_name, my_slot, int(args.chan_enable), 'Pw', 0) # Ensure we have 0 current set - - - else: - my_hvps_ctrl.HVPS[0].status_all_channels(args.hvps_name) - - del my_hvps_ctrl.HVPS[0] - #print("Time 2") # Uncommented this and the next line to try init'ing again. This should work if CAEN ever fixes their CApi which they promised back in Nov2020 - #HVPS = HVPS_Class(caen_system_info_list) - - return - - -def process_config_file_configobj(config_file="hvps.cfg"): - # process_config_file_configobj: Using ConfigObj to process config file into nested dict's - if exists(config_file): - config_dict = ConfigObj(config_file) # Change this to config_file after testing - else: - print("Could not open config file:", config_file) - print("Please specify using --config ") - exit(1) - return config_dict - - -def main(): - parser = argparse.ArgumentParser(description='HVPS Controller', usage='%(prog)s --action [bias, unbias, status, set_name] --chan [channel num]') - parser.add_argument('--hvps_name', dest='hvps_name', default=None, required=False) - parser.add_argument('--status', action='store_true', default=False, required=False, - help="Show status of channels (can specify --chan)") - parser.add_argument('--unbias', action='store_true', default=False, required=False, - help="Unbias channel specified with --chan #") - parser.add_argument('--action', choices=('unbias', 'set_param'), required=False, default=None) - - parser.add_argument('--param', dest='param', choices=('ISet', 'RUp', 'RDwn', 'Pon', 'Pw', 'TripInt', 'TripExt', 'PDwn', 'IMRange', 'Trip'), - required=False, default=None, - help="Specify parameter to modify for channel, must specify with --action set_param") - parser.add_argument('--param_value', dest='param_value', required=False, default=None, - help="Specify parameter value, must specify --action set_param and --param") - parser.add_argument('--bias', dest='bias_voltage', type=int, required=False, default=None, - help="Specify new bias voltage for a channel specified with --chan #") - parser.add_argument('--iset_current', dest='iset_current', type=float, required=False, default=0.0, - help="Specify current (ISET)") - parser.add_argument('--slot', dest='slot_selected', type=int, required=False, default=None, - help="Specify slot to take action against") - - parser.add_argument('--chan_enable', dest='chan_enable', required=False, type=int, default=None, - help="Specify channel to turn on") - parser.add_argument('--chan_disable', dest='chan_disable', required=False, type=int, default=None, - help="Specify channel to turn off") - - parser.add_argument('--chan', dest='channel_selected', required=False, type=int, default=None, - help="Specify channel to take action against, specify channel number or ALL") - - parser.add_argument('--config_file', dest='config_file', required=False, default="hvps.cfg", - help="Specify the complete path to the config file, by default we'll use hvps.cfg") - - parser.add_argument('--force', action='store_true', default=False, required=False, - help="If used than no confirmation will be asked.. !!BE CAREFUL!!") - - args, unknown = parser.parse_known_args() - config_dict = process_config_file_configobj(args.config_file) - process_cli_args(args, config_dict) - - -if __name__ == "__main__": - main() diff --git a/hvps/readme.md b/hvps/readme.md deleted file mode 100644 index 6417733..0000000 --- a/hvps/readme.md +++ /dev/null @@ -1,12 +0,0 @@ -wifi connection should be IPNL ! -(base) 15:36:50:~/Desktop/CAENHV/HVPS/caenlib $ java -jar ChannelsController.jar 10.2.2.20 admin admin -(base) 16:40:57:~/Desktop/CAENHV/HVPS $ docker exec -it caencontainer bash -[root@c6b44ea28417 hvps]# python3 hvps_ctrl.py --status --chan 0 -Could get the IP address for the hostname : 10.2.2.20 ip address: b'10.2.2.20' -Initilizing HVPS... -DEBUG_INIT::::: admin admin b'10.2.2.20' 10.2.2.20 ds-hvps 2 0 -Initialized Connection to : 10.2.2.20 -communicating with HVPS, Hostname IP : b'10.2.2.20', ERROR code : 0x0 -Channel#: 0 | V0Set : 0.0 | I0Set : 355.0 | V1Set : 0.0 | I1Set : 355.0 | RUp : 50.0 | RDWn : 50.0 | Trip : 10.0 | SVMax : 3500.0 | VMon : 0.0 | IMon : 0.0 | Pw : 0.0 | POn : 0.0 | PDwn : 0.0 | ImRange : 0.0 | TripInt : 0.0 | TripExt : 0.0 | ZCDetect : 0.0 | Status : Off - - diff --git a/setup.py b/setup.py index b95a036..c13180a 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup( - name="hvps", + name="caen_hvps", version="1.0.0", packages=find_packages(), include_package_data=True,