1069 lines
42 KiB
Matlab
1069 lines
42 KiB
Matlab
%function example()
|
||
%mocha
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% Jan Chrin, Paul Scherrer Institut
|
||
% March 2017
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (1) Establishing connections to EPICS Process Variables (PVs)
|
||
% (2) Simple single channel operations (and the PVData Object)
|
||
% (3) Understanding the Status Error Code / MATLAB Exceptions
|
||
% (4) Waveforms and Arrays
|
||
% (5) Handling Enumerated Types
|
||
% (6) Multiple scalar operations, i.e., operations on several PVs with scalar values
|
||
% (7) Multiple cell array ('compound') operations, i.e., on several PVS with scalar/vector values
|
||
% (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors
|
||
% (9) Asynchronous interactions and retrieving data from Cache
|
||
% (10) Synchronous group operations, also with externally defined groups
|
||
% (11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts)
|
||
% (12) Control system parameters, i.e., operating limits, engineerimg units
|
||
% (13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc.
|
||
% (14) Setting timeouts for set/get operations
|
||
% (15) Setting synchronous group timeouts for set/get operations
|
||
% (16) Special Methods, e.g., setAndGet, setAndMatch
|
||
% (17:END) Gracefully terminate CAFE
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% the mocha release is accompanied with the long established mca scripts
|
||
% which have been accordingly 'mocha-fied',
|
||
% i.e., the 'mocha' interface is used from within the mca scripts
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% Test channels
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
% To run this test script, first create 5 soft channels of the given class.
|
||
% pv(1:2) are scalar numerics, pv(3) is a wf, pv(4) is a mbbo record (enum),
|
||
% pv(5) is a dbr_string_t, pv(6) does not exist
|
||
pv={'ARIDI-BPM-01LE:X-AVG','ARIDI-BPM-01LE:Y-AVG','ARIDI-BPM-01LE:WF-INT-2','ARIDI-BPM-01LE:SET-ENABLE','ARIDI-BPM-01LE:SET-ENABLE.DESC','PV-JOKE'};
|
||
|
||
%
|
||
% MATLAB's Run and Advance utility will run each of these 17 sections at the user's prompt.
|
||
|
||
% To create an executable:
|
||
% uncomment function example in first line and run the mcc compiler
|
||
% mcc -m example
|
||
% ./run_example.sh $MATLAB_DIR
|
||
|
||
|
||
% The following monitorAction.m is included in the movcha release for test purposes.
|
||
% Otherwise please copy and place it in your local directory from where matlab
|
||
% will be started. This file can optionally be used as a callback function for monitors.
|
||
|
||
%monitorAction.m
|
||
%{
|
||
function varargout = monitorAction(varargin)
|
||
disp('monitorAction called for:');
|
||
pvName=mocha('getPVFromHandle', varargin{1});
|
||
disp(pvName);
|
||
X=['Handle =', num2str(varargin{1})];
|
||
disp(X);
|
||
|
||
%[varargout{1} varargout{2}] = mocha ('getCache', varargin{1});
|
||
[var1,var2]=mocha ('getCache', varargin{1});
|
||
[s,t]=mocha('getStatus', varargin{1});
|
||
%X=['Value=', num2str(varargout{1}), ' Status=', num2str(s), ' [',t(1), ' ', t(2),']'];
|
||
X=['Value =', num2str(var1)];
|
||
Y=['Status=', num2str(s)];
|
||
disp(X)
|
||
disp(Y)
|
||
disp([t(1),t(2)])
|
||
%}
|
||
|
||
|
||
|
||
%%%%
|
||
mocha('test'); %test if mocha MEX-file is accessible
|
||
mocha('version'); %lists mocha/cafe version
|
||
%mocha('show'); %lists all available mocha methods
|
||
%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (1) Establishing connections to EPICS Process Variables (PVs)
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%Explicitly opening channels is good practice even if only optional
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (1) Establishing connections to EPICS Process Variables (PVs) ');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
%returns an array of handles (object references)
|
||
%hpv=mocha('open',pv);
|
||
|
||
%When executing the 'open' message as above, the default behaviour
|
||
%is for each 'open' to wait for a maximum amount of time, given by:
|
||
openTime = mocha ('getOpenWaitTime'); %currently 0.4s
|
||
%The 'open' wait time can, however, be configured by the user as follows:
|
||
mocha ('setOpenWaitTime', 0.2); %set to 0.2s
|
||
mocha ('setOpenWaitTime'); %reset to default (0.4s)
|
||
%The above shoud be set before the mocha 'open' method is executed
|
||
|
||
|
||
%If opening numerous channels, however, better to do this with a single message.
|
||
%This is done as shown here:
|
||
mocha('openPrepare');
|
||
hpv=mocha('open',pv);
|
||
% and more mocha 'open' messages would follow here...
|
||
% Finally send the messages and wait for a maximum of 0.2s for connections to complete
|
||
mocha('openNowAndWait', 0.2)
|
||
|
||
%There are a number of ways to extract information on the created handles
|
||
%print all handles whether connected or not
|
||
mocha('printHandles');
|
||
|
||
%Array of handles and matching PVnames
|
||
[handles, pvs] = mocha ('getHandles');
|
||
[handles, pvs] = mocha ('getConnectedHandles');
|
||
[handles, pvs] = mocha ('getDisconnectedHandles');
|
||
%Array of handles, matching PVnames and connection states
|
||
[handles, pvs, states] = mocha ('getHandleStates');
|
||
|
||
%print information on disconnected channels
|
||
if (~mocha('allConnected'))
|
||
mocha('printDisconnectedHandles');
|
||
%or
|
||
[handles, pvs] = mocha ('getDisconnectedHandles');
|
||
for n =1 : length(handles)
|
||
X=['Handle=', num2str(handles(n)), 'PV=',pvs(n)];
|
||
disp(X);
|
||
end
|
||
end
|
||
|
||
%To check on the connection state of a single channel
|
||
logicValue=mocha('isConnected', pv(1)); %by pvName
|
||
logicValue=mocha('isConnected', hpv(1)); %byHandle
|
||
|
||
|
||
%Handle and PV Mapping
|
||
%Retrieve handle for a given PV
|
||
handle = mocha ('getHandleFromPV', pv(1));
|
||
pvName = mocha ('getPVFromHandle', hpv(1));
|
||
|
||
%%
|
||
%or run the MATLAB script (which also shows latest values)
|
||
disp('If val is NaN then a harmless warning will appear from struct2table');
|
||
%Warning: Out of range or non-integer values truncated during
|
||
%conversion to character
|
||
|
||
pvtable
|
||
|
||
|
||
%Channels may be closed when the application no longer needs them
|
||
%mocha ('close', pv(1)); %close given channel
|
||
%mocha ('close', pv); %close given channels
|
||
%Close all chanels and release all ca resources before exiting MATLAN
|
||
%mocha ('close');
|
||
|
||
%END (1) Establishing connections to EPICS Process Variables (PVs)
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(2) Simple single channel operations (and the PVData Object)
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (2) Simple single channel operations ');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%Now perform some get/set operations
|
||
|
||
%Mocha operations will accept either a pv name or the pv handle
|
||
%(as returned from the mocha 'open' method) as the 2nd input argument
|
||
|
||
%GET value
|
||
%by pvName; value (scalar or vector) returned in native data type
|
||
[value, status]= mocha ('get', pv(1));
|
||
%by Handle; value (scalar or vector) returned in native data type
|
||
[value, status]= mocha ('get', hpv(1));
|
||
|
||
%by pvName; value (scalar or vector) returned as a MATLAB double
|
||
[value, status]= mocha ('get', pv(1), 'uint8');
|
||
%by pvName; value (scalar or vector) returned as a MATLAB uint8 type
|
||
[value, status]= mocha ('get', pv(1), 'double');
|
||
|
||
%SET
|
||
%value (scalar or vector) can be in any MATLAB data type
|
||
[status] = mocha('set', pv(1), value);
|
||
|
||
%Single channel operations that return data, alarms and timestamps
|
||
%pvData struct returned; pvData.val has the native data type
|
||
pvData = mocha ('getPV', pv(1));
|
||
%pvData struct returned; pvData.val has the double data type
|
||
disp('Displaying pvdata struct');
|
||
pvData = mocha ('getPV', pv(1), 'double')
|
||
|
||
pvData.val;
|
||
pvData.status; % int32
|
||
pvData.alarmStatus; %int16
|
||
pvData.alarmSeverity; %int16
|
||
pvData.ts; %[year, month, day, hour, min, sec, nsec]
|
||
|
||
|
||
%Other ways to retrieve alarms and timestamps from cache following a 'get'
|
||
ts=mocha('getTimestamp', pv(1));
|
||
[ets]=mocha('getETS', pv(1)) % [secPastEpoch, nsec]
|
||
|
||
[alarmStatSev] = mocha ('getAlarm', pv(1)); %[alarmStatus, alarmSeverity]
|
||
[alarmStatSev] = mocha ('getAlarmAsString', pv(1)) %[alarmStatus, alarmSeverity]
|
||
|
||
%The string equivalenty of an integer alarmStatus/Severity
|
||
%may be gotten at any time as follows;
|
||
alarmStatus_str = mocha('alarmStatusAsString', pvData.alarmStatus);
|
||
alarmSeverity_str = mocha('alarmSeverityAsString', pvData.alarmSeverity);
|
||
|
||
%Alarm conditions and alarm severities can be listed as follows:
|
||
disp('Listing all possible alarm condition value/name pairs')
|
||
[strVal, intVal] = mocha('alarmStatusList');
|
||
for n = 1:length(intVal)
|
||
[intVal(n), strVal(n)]
|
||
end
|
||
disp('Listing all possible alarm severity value/name pairs')
|
||
[strVal, intVal] = mocha('alarmSeverityList');
|
||
for n = 1:length(intVal)
|
||
[intVal(n), strVal(n)]
|
||
end
|
||
|
||
|
||
%An extended (x) struct holding supplementary data may also be retrieved:
|
||
disp('Displaying extended pvdata struct');
|
||
pvStruct = mocha ('getStruct', pv(1))
|
||
pvStruct.handle; %uint32
|
||
pvStruct.pv; %char
|
||
pvStruct.val;
|
||
pvStruct.status; %int32
|
||
pvStruct.status_str; %char
|
||
pvStruct.alarmStatus; %int16
|
||
pvStruct.alarmStatus_str; %char
|
||
pvStruct.alarmSeverity; %int16
|
||
pvStruct.alarmSeverity_str; %char
|
||
pvStruct.ts; %[year, month, day, hour, min, sec, nsec]
|
||
pvStruct.epicsTS; %[secPastEpoch, nsec]
|
||
|
||
%END (2) Simple single channel operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(3) Understanding the Status Error Code / MATLAB Exceptions
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (3) Understanding the Status Error Code / MATLAB Exceptions');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
[value, status]= mocha ('get', pv(1));
|
||
pvData = mocha ('getPV', pv(1));
|
||
status = pvData.status;
|
||
|
||
%A Status Code of 1 represents a normal completion
|
||
%Status Codes <=480 are generated by the native ca library
|
||
%Status Codes >=600 are generated by the underlying CAFE library
|
||
|
||
%A status code is paired to an enumerated name
|
||
statusAsString=mocha ('statusAsString', status);
|
||
%The following returns the enumerated name
|
||
%preceded with severity (SUCCESS, INFO, WARNING, ERROR)
|
||
statusText = mocha ('statusAsText', status);
|
||
%Further information concerning the code
|
||
statusInfo = mocha ('statusInfo', status);
|
||
|
||
%Another way to retrieve the full status information w.r.t. the previous
|
||
%operation on a given handle is
|
||
[status, statusArray] = mocha ('getStatus', pv(1))
|
||
%status is the integer status code
|
||
%statusArray[1] returns same data as statusText above
|
||
%statusArray[2] returns same data as statusInfo above
|
||
|
||
%Status code/name pairs can be listed as follows:
|
||
disp('Listing all possible status code value/name pairs')
|
||
[strVal, intVal] = mocha('statusList');
|
||
|
||
%Alarm conditions and alarm severities can be listed as follows:
|
||
%disp('Listing all possible alarm condition value/name pairs')
|
||
[strVal, intVal] = mocha('alarmStatusList');
|
||
for n = 1:length(intVal)
|
||
[intVal(n), strVal(n)]; %not printed to window
|
||
end
|
||
|
||
%Rather than have to check on the status codes, CAFE MATLAB exceptions can be
|
||
%enabled (mocha default is to have exceptions dis-enabled)
|
||
|
||
mocha ('withExceptions', true) %enables MATLAB exceptions for single channel operations
|
||
|
||
try
|
||
[val, status] = mocha ('get', pv(6)) %pv(6) is dis-connected as channel does not exist
|
||
catch ME
|
||
ME
|
||
%A MATLAB exception, MException, comprises the 'identifier' and 'message' properties
|
||
if strfind(ME.identifier,'CAFE_WARN')
|
||
warning(ME.message);
|
||
elseif strfind(ME.identifier, 'CAFE_INFO')
|
||
disp(ME.message);
|
||
elseif strfind(ME.identifer,'CAFE_ERROR')
|
||
error(ME.message);
|
||
else
|
||
disp(ME.message);
|
||
end
|
||
end
|
||
|
||
mocha ('withExceptions', false) %dis-enable MATLAB exceptions for single channel operations
|
||
|
||
%END (3) Simple single channel operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(4) Waveforms and Arrays
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (4) Waveforms and Arrays');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
[value, status] = mocha ('get', pv(3)); %Returns all elements of the wf
|
||
[pvdata] = mocha ('getPV', pv(3)); %Returns all elements of the wf in pvdata.val
|
||
|
||
%The default behaviour is for all elements of the wf to be read out and
|
||
%presented. However, this number together with an offset can be configured
|
||
%by the user
|
||
|
||
nelemWF = mocha('setNelem', pv(3), 20);
|
||
offsetWF= mocha('setOffset',pv(3), 12);
|
||
|
||
%nelemWF = mocha('setNelem', pv(3)); %sets to native value
|
||
%offsetWF= mocha('setOffset',pv(3), 0); %but remember to set offset to 0 too!
|
||
|
||
%The subsequent method then returns an array (value) of length 20,
|
||
%containing data from the 13th until the 32nd element of the waveform.
|
||
[value, status] = mocha ('get', pv(3), 'double')
|
||
|
||
%END (4) Waveforms and Arrays
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(5) Handling Enumerated Data Types
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (5) Handling Enumerated Data Types');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%Consider pv(4) which is an mbbo record with enumerated value/names
|
||
%0/off 1/on 2/{transient state}
|
||
%with current value 1, i.e., 'on'
|
||
|
||
%Default behaviour is to present the value as a string:
|
||
[value, status] = mocha ('get', pv(4));
|
||
%Hence above method will return a value of 'on'
|
||
X=[pv(4), 'has value', value];
|
||
disp(X);
|
||
%Any MATLAB numberic data type, such as 'int8', 'single' could also be specified
|
||
[value, status] = mocha ('get', pv(4), 'uint8');
|
||
%Hence above method would return a value of 1
|
||
X=[pv(4), 'has value', num2str(value)];
|
||
disp(X);
|
||
|
||
%For set, the input value can be any valid numeric or string;
|
||
%It will be internally converted to an unsigned short before being sent to the IOC.
|
||
[status] = mocha ('set', pv(4), 0); % will send the value 0, i.e. 'off'
|
||
[status] = mocha ('set', pv(4), 'off'); % will send the value 0, being the value euivalent of the enumerated name
|
||
[status] = mocha ('set', pv(4), '0'); %will send an unsigned short value of 0
|
||
[status] = mocha ('set', pv(4), 'anything'); %will complain that this is not a valid enumerated name
|
||
[status] = mocha ('set', pv(4), '0anything'); %will convert this to an unsigned short value of 0
|
||
|
||
%END (5) Handling Enumerated Data Types
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(6) Multiple Scalar Operations, i.e., operations on several PVs with scalar values
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (6) Multiple Scalar Operations, i.e., operations on several PVs with scalar values');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%GET:
|
||
%Messages are collected and transmitted with one single method invocation
|
||
%If Handle/PV points to a WF, only the 1st element of the WF is returned.
|
||
%If a data type for the retrieved data is not specified, then the native type
|
||
%of the first handle/pv is selected, here (pv(1))
|
||
|
||
|
||
pvInput=[pv(1:3),pv(6)];
|
||
[val, isAllOK, s] = mocha ('getScalarArray', pvInput, 'double');
|
||
% Alternatively
|
||
% [val, isAllOK, s] = mocha ('get', pvInput, 'double');
|
||
% may be called;
|
||
% mocha('getScalarArray') will then be called internally
|
||
[val, isAllOK, s] = mocha ('get', pvInput, 'double')
|
||
if isAllOK ~= 1
|
||
for n=1:length(s)
|
||
if s(n) ~= 1
|
||
[codes,ctext]=mocha('getStatus', pvInput(n));
|
||
X=['GET: Error in Elem:', num2str(n), pvInput(n), ':'];
|
||
Y=[num2str(codes), ctext(1)];
|
||
disp(X); disp(Y);
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
%SET:
|
||
val(1)=val(1)+0.001;
|
||
[isAllOK, s] = mocha ('setScalarArray', pvInput, val);
|
||
% Alternatively
|
||
% [isAllOK, s] = mocha ('set', pvInput, val);
|
||
% may be called;
|
||
% mocha('setScalarArray') will then be called internally
|
||
|
||
|
||
[isAllOK, s] = mocha ('set', pvInput, val);
|
||
|
||
if isAllOK ~= 1
|
||
for n=1:length(s)
|
||
if s(n) ~= 1
|
||
[codes,ctext]=mocha('getStatus', pvInput(n));
|
||
X=['SET: Error in Elem.:', num2str(n), pvInput(n), ':'];
|
||
Y=[num2str(codes), ctext(1)];
|
||
disp(X); disp(Y);
|
||
end
|
||
end
|
||
end
|
||
|
||
%END (6) Multiple Scalar Operations, i.e., operations on several PVs with scalar values
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(7) Multiple cell array ('compound') operations, i.e., on several PVS with scalar/vector values
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (7) Multiple cell array ("compound") operations, i.e., on several PVS with scalar/vector values');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
%GET
|
||
%Note the use of the handles; one could equally use the PV array, pv
|
||
[val, isAllOK, s] = mocha ('getCellArray', hpv);
|
||
%returns a cell array, wherein the elements are of native data type and can be of any size
|
||
|
||
%SET
|
||
val{1}=1.111;
|
||
val{2}=2.222;
|
||
val{3}=(1:256); %wf
|
||
val{4}='on'; %mbbo
|
||
[isAllOK, s] = mocha ('set', hpv, val{:});
|
||
|
||
%Here, the data type of all returned values is defined to be a string
|
||
[val, isAllOK, s] = mocha ('getCellArray', hpv, 'string')
|
||
|
||
%END (7) Multiple Scalar Operations, i.e., operations on several PVs with scalar values
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%GET
|
||
%returns a sequence of pvData structs
|
||
%%
|
||
|
||
[pvData, isAllOK] = mocha ('getPVArray', pv)
|
||
disp('Display all pvData.val values and statuses:');
|
||
%pvData(i) corresponds to the data returned by pv(i)
|
||
{pvData.val}
|
||
[pvData.status]
|
||
%pvData(1:6).ts %timestamps
|
||
%[pvData(1:6).alarmStatus]
|
||
%[pvData.alarmSeverity]
|
||
|
||
%Note: the following method is equivelent to the above
|
||
%as it will call getPVArray internally
|
||
[pvData, isAllOK] = mocha ('getPV', pv);
|
||
|
||
|
||
%returns a sequence of extended (x) pvData structs
|
||
%%[pvStruct, isAllOK] = mocha ('getStructArray', pv)
|
||
%pvStruct(i) corresponds to the data returned by pv(i)
|
||
%%disp('Display all pvStruct as arrays:');
|
||
%%[pvStruct.handle]
|
||
%%{pvStruct.pv}
|
||
%%{pvStruct.val}
|
||
%%[pvStruct.status]
|
||
%%{pvStruct.status_str}
|
||
%%[pvStruct.alarmStatus]
|
||
%%{pvStruct.alarmStatus_str}
|
||
%%[pvStruct.alarmSeverity]
|
||
%%{pvStruct.alarmSeverity_str}
|
||
%%pvStruct.ts
|
||
%%pvStruct.epicsTS
|
||
%%[pvStruct.alarmSeverity]
|
||
%%{pvStruct.alarmSeverity_str}
|
||
%pvStruct(1:6).ts %timestamps
|
||
%[pvStruct(1:6).alarmStatus]
|
||
|
||
%% %%%%
|
||
%Note: the following method is equivelent to the above
|
||
%as it will call getStructArray internally
|
||
[pvStruct, isAllOK] = mocha ('getStruct', pv);
|
||
%%%%%%%%
|
||
|
||
disp('Alternatively part data (values, statuses only) could also be retrieved with getCellArray:');
|
||
%% %%%%
|
||
[val, isAllOK, s] = mocha ('getCellArray', hpv)
|
||
%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%SET -overwrite pvData
|
||
pvData(1).val =0.2345;
|
||
pvData(2).val =2.6789;
|
||
pvData(3).val =(256:512);
|
||
pvData(4).val = 'off';
|
||
|
||
%%%%%%
|
||
[isAllOK, s] = mocha ('set', hpv, pvData(1:6).val);
|
||
%%%%%%%%%%%%%%%%%%%
|
||
|
||
%Check values were set
|
||
[val, isAllOK, s] = mocha ('getCellArray', hpv)
|
||
%%%%%%%%%
|
||
|
||
disp('Recall we had previously set an offset for wf of value:');
|
||
offset=mocha('getOffset',hpv(3))
|
||
disp('Setting new offset/nelem for wf has value:');
|
||
offset=mocha('setOffset',hpv(3),0)
|
||
%nelem =mocha('setNelem',hpv(3), mocha('getnelemnative',hpv(3)) )
|
||
nelem =mocha('setNelem',hpv(3),10);
|
||
disp('Note that setNelem and setOffset are for readback of waveform only');
|
||
%SET
|
||
%Another way to set
|
||
dd{1} = 3.33;
|
||
dd{2} = uint8(4);
|
||
dd{3} = [1,2,3,4,5,6,7,8,9,10,11,12,2.6,2.7,2.8,2.9,3.0,3.1,3.2,3.3]; %(2:257); %
|
||
dd{4} = 'off';
|
||
dd{5} = 'Enable or Dis-enable BPM';
|
||
dd{6} = 0;
|
||
[isAllOK,s] = mocha ('setMany', pv(1:5), dd{1:5});
|
||
%or this will call setMany
|
||
dd{4} = 'on';
|
||
[isAllOK,s] = mocha ('set', pv(1:5), dd{1:5});
|
||
%Check values were set
|
||
[pvData, isAllOK] = mocha ('getPVArray', hpv(1:5));
|
||
{pvData.val}
|
||
pvData(3).val
|
||
%END (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(9) Asynchronous interactions and retrieving data from Cache
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(9) Asynchronous interactions and retrieving data from Cache');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%GET
|
||
%Messages are aggregated until the user decides when to send the messages
|
||
%Note that there is no variable for the return data! This will be retrieved
|
||
%later through the getCache method
|
||
[s] = mocha ('getAsyn', pv(1));
|
||
[isAllOK,s] = mocha ('getAsyn', pv(2:5));
|
||
%Now send the messages
|
||
mocha('sendNow'); %optional; otherwise 'getCache' will do the send
|
||
%or mocha('caFlush');
|
||
|
||
%getCache methods are used to retrieve the data;
|
||
%methods will wait until any outstanding callback is complete or a timeout is reached
|
||
[val, s] = mocha('getCache', pv(1), 'double');
|
||
pvData = mocha('getCache', pv(2));
|
||
%get several pvs in one call
|
||
[val, isAllOK, s] = mocha('getScalarArrayCache', pv, 'string');
|
||
%or getCache will call getScalarArrayCache
|
||
[val, isAllOK, s] = mocha('getCache', pv, 'string')
|
||
[val, isAllOK, s] = mocha('getCellArrayCache', pv)
|
||
[pvData, isAllOK] = mocha('getPVArrayCache', pv)
|
||
%return extended pvStruct
|
||
[pvStruct, isAllOK] = mocha('getStructArrayCache', pv)
|
||
%SET
|
||
%Set messages are by default asynchronous and non-blocking.
|
||
%The user may configure any given handle such that the messages are blocking,
|
||
%meaning a subsequent set method will wait until the server has reported back to the client:
|
||
%BLOCKING:
|
||
mocha('setPutWait', pv); %policy changed to blocking for all handles pv(1:6)
|
||
status = mocha ('set', pv(1), 0.1); %blocks, status may return a timeout error
|
||
%NON_BLOCKING - this is the default
|
||
mocha('setPutNoWait', pv); %policy changed to non-blocking for all handles pv(1:6)
|
||
status = mocha ('set', pv(1), 0.2); %blocks, status will never return a timeout error
|
||
%Want to be sure the value got written?
|
||
disp('Executing setAndGet; Return val should equal input value, i.e., 0.3');
|
||
[val, status]= mocha('setAndGet', pv(1), 0.3) %val will be 0.3 on success.
|
||
%The above method initiates a set followed immediately by a get.
|
||
%The user should be aware that in the event of other applications writing
|
||
%to the same epics channel, the possibility exists that this external write
|
||
%may occur between the set and subsequent get in the above method.
|
||
%The data type of the returned value matches that of the input value.
|
||
|
||
%AGGREGATING ASYNCHRONOUS SET OPERATIONS - Can be ignored as user case is expected to be uncommon
|
||
%If required set methods can also be aggregated before being sent asynchronously over the network
|
||
dd{1} = double(3.3);
|
||
dd{2} = uint8(4);
|
||
dd{3} = [11,12,13,14,15,6,7,8,9,10,11,12,2.6,2.7,2.8,2.9,3.0,3.1,3.2,3.3]; %(2:257); %
|
||
dd{4} = 'off';
|
||
dd{5} = 'Enable or Dis-enable BPM';
|
||
dd{6} = 0;
|
||
|
||
mocha('setPutPrepare', pv(1:6));
|
||
s = mocha ('set', pv(1), dd{1});
|
||
s = mocha ('set', pv(2), dd{2});
|
||
s = mocha ('set', pv(3), dd{3});
|
||
s = mocha ('set', pv(4:5), dd{4:5});
|
||
s = mocha ('set', pv(6), dd{6});
|
||
mocha('sendNow');
|
||
|
||
%Note that a subsequent set on the same given channel
|
||
%will trigger a 'send' to IOC transaction on the pending set
|
||
mocha('setPutPrepare', pv(1:6));
|
||
s = mocha ('set', pv(1), dd{1});
|
||
s = mocha ('set', pv(1), 0.2); %will first trigger a send of the previous 'set'
|
||
[val,s]=mocha('get', pv(1)) %a get method will also initiate a send of all previous messages
|
||
|
||
%Reset Policy - Remember to reset the policy, e.g., to asynchronous, blocking
|
||
mocha('setPutWait', pv);
|
||
%or
|
||
%Reset Policy - Remember to reset the (default) policy, e.g., to asynchronous, non-blocking, non-aggregating
|
||
mocha('setPutNoWait', pv);
|
||
|
||
%END (9) Asynchronous interactions and retrieving data from Cache
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(10) Synchronous Group Operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(10) Synchronous Group Operations');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%
|
||
%Uses the ca_sg functionality which guarantees a set of ca requests have completed, or a timeout is reached
|
||
%First define a group; here a simple group of two BPMs
|
||
s = mocha('defineGroup', 'gBPM', pv(1:2));
|
||
%First define a group; here a collection of non-related pvs
|
||
s = mocha('defineGroup', 'gSnapshot', pv(1:5));
|
||
%Open a group; optional, otherwise first get/set method will establish the connections
|
||
gHandle1 = mocha('openGroup', 'gBPM');
|
||
gHandle2 = mocha('openGroup', 'gSnapshot');
|
||
|
||
%A synchronous group can be regarded as a logical software unity;
|
||
%*** A pv within a group will have its own, separate handle ***
|
||
%as revealed from within the following command
|
||
mocha('printHandles');
|
||
%or
|
||
[hArray, pvArray]=mocha('getHandles');
|
||
%For example, three ca virual circuits have thus been created for pv(1)
|
||
%as this pv exists in its own right, within group 'gBPM' and within group 'gSnapshot'
|
||
%Likewise two ca virtual circuits have been created for the waveform in pv(3)
|
||
%The various handles for the given pv may be configured independently
|
||
%e.g. In the following we will set the nelem for pv(3) (hpv(3)) to 6
|
||
% and the the nelem for pv(3) within the group 'gSnapshot' to 12
|
||
newNelem=mocha('setNelem', pv(3), 6); %corresponds to handle for pv(3)
|
||
%set nelements for handle withing group for pv(3) to 12
|
||
handlesWithinGroup=mocha('getHandlesWithinGroup', gHandle2);
|
||
newNelem=mocha('setNelem', handlesWithinGroup(3), 12); %handlesWithinGroup(3) corresponds to pv(3) in group 'gSnapshot'
|
||
disp('pv(3) should have been read with 6 elements:')
|
||
[val,s]=mocha('get', pv(3));
|
||
val
|
||
disp('pv(3) should have been read with 12 elements:')
|
||
[val,s]=mocha('get', handlesWithinGroup(3));
|
||
val
|
||
|
||
|
||
[pvData1, isAllOK] = mocha('getPVGroup', 'gBPM'); %2nd argument could equally have been the group handle, i.e., gHandle1
|
||
[pvData2, isAllOK] = mocha('getPVGroup', gHandle2); %2nd argument could equally have been the group name, i.e., 'gSnapshot'
|
||
|
||
%To retrieve extended PVData;
|
||
[pvStruct, isAllOK] = mocha('getStructGroup', 'gBPM');
|
||
|
||
%pvData is an array of returned s
|
||
pvData2.val
|
||
pvData2.status; % int32
|
||
pvData2.alarmStatus; %int16
|
||
pvData2.alarmSeverity; %int16
|
||
pvData2.ts; %[year, month, day, hour, min, sec, nsec]
|
||
|
||
|
||
mocha('get',handlesWithinGroup(3))
|
||
|
||
pvData2(3).val=(1:256);
|
||
[isAllOK,s]=mocha('setGroup', gHandle2, pvData2.val);
|
||
%reset to 256
|
||
mocha('setNelem', handlesWithinGroup(3), 256)
|
||
mocha('get',handlesWithinGroup(3))
|
||
|
||
|
||
%Configuring groups through XML - See documentation/talk for XML format
|
||
%Here the test.xml contains a group consistimng of 2 BPMs
|
||
mocha('loadXMLGroups', 'test.xml');
|
||
|
||
%List Groups and group Members
|
||
disp('listGroups:');
|
||
[groups] = mocha('listGroups')
|
||
disp('Show members of group gSnapshot:');
|
||
[members]= mocha('listGroupMembers', 'gSnapshot')
|
||
disp('Show members of group gTest (as loaded from test.xml):');
|
||
[members]= mocha('listGroupMembers', 'gTest')
|
||
%This will only CLOSE and remove groups that have already been OPENED!
|
||
%%for i =1:length(groups)
|
||
%%mocha('closeGroup', groups{i})
|
||
%%end
|
||
|
||
%END (10) Synchronous Group Operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%(11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts)
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%Simple Monitors
|
||
monitorID = mocha ('monitor', pv(1));
|
||
[monitorIDArray, isAllOK, statusArray] = mocha ('monitor', pv(1:6)); %start monitors for several pvs/handles
|
||
%Once the monitor is started, data may be retrieved via one of the cache methods
|
||
|
||
pause(0.1)
|
||
|
||
[val,s] = mocha('getCache', pv(1)); %Scalar or vector returned in native data type
|
||
[val,s] = mocha('getCache', pv(1), 'double'); %Scalar or vector returned as a MATLAB double
|
||
[val,s] = mocha('getCache', pv(1), 'uint8'); %Scalar or vector returned as a MATLAB uint8
|
||
|
||
|
||
[pvData] = mocha('getPVCache', pv(1)) %PVData Object returned with pvData.val in native data type
|
||
[pvData] = mocha('getPVCache', pv(1), 'single'); %PVData Object returned with pvData.val as a MATLAB float
|
||
[pvData] = mocha('getPVCache', pv(1), 'int32'); %PVData Object returned as a MATLAB int32
|
||
|
||
[pvStruct] = mocha('getStructCache', pv(1)) %Extended (x) mocha closepvData
|
||
|
||
s = mocha('monitorStop', pv(1), monitorID); %Stop monitor for pv/handle with given monitorID
|
||
s = mocha('monitorStop', pv(1)); %Stop all monitors for this pv/handle
|
||
s = mocha('monitorStop', pv(1:6)); %Stop all monitors for these pvs/handles
|
||
s = mocha('monitorStop'); %Stop all monitors for all pvs/handles
|
||
|
||
|
||
%Monitors with Actions, i,e, callback of MATLAB script
|
||
|
||
%Need to give the numeric value of the handle as input argument to monitorAction
|
||
monAction=['monitorAction(', num2str(hpv(1)), ')'] ;
|
||
%The above reads monAction = 'monitorAction(1)'
|
||
%Here monitorAction(1) refers to a Matlab Script monitorAction.m
|
||
%that takes a single input argument, which is the handle of the monitored channel
|
||
|
||
monitorID= mocha('monitor',hpv(1),monAction);
|
||
|
||
%Mulitple monitors with actions:
|
||
%monAction2=['monitorAction(', num2str(hpv(2)), ')'] ;
|
||
%[monitorID] = mocha('monitor', hpv(1:2), monAction, monAction2);
|
||
|
||
%The monitorAction.m script will typically retrieve data from Cache as follows:
|
||
%[val,status]=mocha ('getCache', varargin{1});
|
||
|
||
mocha('monitorFlushEvent', pv(1)); %will execute the MATLAB script monitorAction.m if new data has arrived
|
||
mocha('monitorFlushEvent'); %will execute all 'actions' for all 'handles' that have received new data
|
||
|
||
%The above command is used in conjunction with MATLAB timer (as for MCA's mcamontimer.m)
|
||
obj.t = timer('TimerFcn', 'mocha(''monitorFlushEvent'')', 'Period', 2.0, 'ExecutionMode', 'fixedSpacing');
|
||
%Else if double quotes cannot be used in the above; here's a way around the problem:
|
||
%obj.t = timer('TimerFcn', 'mocha(402)', 'Period', 2.0, 'ExecutionMode', 'fixedSpacing');
|
||
start(obj.t);
|
||
disp ('Callback for monitors for 5 seconds')
|
||
for n=1:5
|
||
mocha('set', pv(1), n); %See the script be executed
|
||
pause(0.5);
|
||
end
|
||
stop(obj.t);
|
||
|
||
%END Monitors, either with or without user supplied callbacks (in essence, matlab scripts)
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (12) Control system parameters, i.e. operating limits, engineerimg units
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(12) Control system parameters, i.e. operating limits, engineerimg units');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
[ctrlData] = mocha('getCtrl', hpv(1));
|
||
%Usually it is sufficient to use the getCtrlCache method
|
||
[ctrlData] = mocha('getCtrlCache', hpv(1));
|
||
ctrlData
|
||
% This is what an output may look like for an ao/ai record
|
||
%{
|
||
handle: 1
|
||
pv: 'ARIDI-BPM-01LE:X-AVG'
|
||
val: 3.2000
|
||
status: 1
|
||
alarmStatus: 0
|
||
alarmSeverity: 0
|
||
precision: 6
|
||
units: 'mm'
|
||
noEnumStrings: 0
|
||
enumStrings: {1<>0 cell}
|
||
upperDisplayLimit: 2
|
||
lowerDisplayLimit: -2
|
||
upperAlarmLimit: NaN
|
||
lowerAlarmLimit: NaN
|
||
upperWarningLimit: NaN
|
||
lowerWarningLimit: NaN
|
||
upperControlLimit: 2
|
||
lowerControlLimit: -2
|
||
%}
|
||
[ctrlData] = mocha('getCtrlCache', hpv(4));
|
||
ctrlData
|
||
% This is what an output may look like for an mbbo/i record
|
||
%{
|
||
handle: 2
|
||
pv: 'ARIDI-BPM-01LE:SET-ENABLE'
|
||
val: 'off'
|
||
status: 1
|
||
alarmStatus: 0
|
||
alarmSeverity: 0
|
||
precision: 0
|
||
units: ''
|
||
noEnumStrings: 3
|
||
enumStrings: {'off' 'on' 'monitor'}
|
||
upperDisplayLimit: 0
|
||
lowerDisplayLimit: 0
|
||
upperAlarmLimit: 0
|
||
lowerAlarmLimit: 0
|
||
upperWarningLimit: 0
|
||
lowerWarningLimit: 0
|
||
upperControlLimit: 0
|
||
lowerControlLimit: 0
|
||
%}
|
||
|
||
%
|
||
%END (12) Control system parameters, i.e. operating limits, engineerimg units
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc.
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc. ');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
iStruct=mocha('getInfo', pv(1));
|
||
iStruct
|
||
% This is what an output may look like:
|
||
% The members connectFlag, accessRead, and accessWrite are all of MATLAB data type, logical
|
||
%{
|
||
handle: 1
|
||
pv: 'ARIDI-BPM-01LE:X-AVG'
|
||
channelID: '0x7f46fc879ae0'
|
||
connectFlag: 1
|
||
hostName: 'psi-softioc-2.psi.ch:45408'
|
||
dataType: 'DBR_DOUBLE'
|
||
className: 'ai'
|
||
accessRead: 1
|
||
accessWrite: 1
|
||
nelem: 1
|
||
connectionState: 'CA_OP_CONN_UP'
|
||
%}
|
||
|
||
%
|
||
%END (13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc.
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (14) Setting timeouts for set/get operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(14) Setting timeouts for set/get operations');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
%Timeouts in CAFE are self-regulating and are regulated by
|
||
%the following parameters in defines.h in the CAFE livrary
|
||
%const bool DEFAULT_SELF_GOVERNING_TIMEOUT = true;
|
||
%const unsigned short DEFAULT_PEND_IO_NO_TRIES = 2;
|
||
%const double DEFAULT_PEND_IO_INCREMENT_TIME = 2.0;
|
||
|
||
%Self governing timeouts may be turned off/on for all handles,
|
||
%or on a per handle basis
|
||
|
||
%Make true (default) for handle hpv(1)
|
||
mocha('setselfgoverningtimeout', pv(1), true);
|
||
|
||
%Make true for all handles
|
||
mocha('setselfgoverningtimeout', true);
|
||
|
||
|
||
%Timeouts can be set separately for blocking SET/GET operations
|
||
%either globally or on a per handle basis
|
||
[t] = mocha('getTimeout', pv(1));
|
||
%t(1) is timeout for a blocking put operation
|
||
%t(2) is timeout for a blocking get operation
|
||
|
||
%the minimum timeout is returned from among all handles
|
||
[t] = mocha('getTimeout');
|
||
%t(1) is minimum put timeout from among all handles
|
||
%t(2) is minimum get timeout from among all handles
|
||
|
||
%Timeouts can be set in a number of ways, for all handles
|
||
%or on a per handle basis
|
||
|
||
%set both put and get timeouts for handle hpv(1) to 10.0 seconds
|
||
status=mocha('setTimeout', pv(1), 10.0);
|
||
|
||
%set both put and get timeouts for all handles to 10.0 seconds
|
||
status=mocha('setTimeout', 10.0);
|
||
|
||
%set put timeout for handle hpv(1) to 5.0 seconds
|
||
status=mocha('setTimeoutPut', pv(1), 5.0);
|
||
|
||
%set put timeouts for all handles to 5.0 seconds
|
||
status=mocha('setTimeoutPut', 5.0);
|
||
|
||
%set get timeout for handle hpv(1) to 10.0 seconds
|
||
status=mocha('setTimeoutGet', pv(1), 10.0);
|
||
|
||
%set put timeouts for all handles to 10.0 seconds
|
||
status=mocha('setTimeoutGet', 10.0);
|
||
|
||
%
|
||
%END (14) Setting timeouts for set/get operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (15) Setting synchronous group timeouts for set/get operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(15) Setting synchronous group timeouts for set/get operations');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
%Self governing timeouts may be turned off/on for all group handles,
|
||
%or on a per group handle basis
|
||
|
||
%Make true (default) for handle hpv(1)
|
||
mocha('setSGselfgoverningtimeout', gHandle1, true);
|
||
|
||
%Make true for all handles
|
||
mocha('setSGselfgoverningtimeout', true);
|
||
|
||
|
||
%Timeouts can be set separately for blocking SET/GET operations
|
||
%either globally or on a per grop handle basis
|
||
[t] = mocha('getSGTimeout',gHandle1);
|
||
%t(1) is timeout for a group put operation
|
||
%t(2) is timeout for a grop get operation
|
||
|
||
%the minimum timeout is returned from among all handles
|
||
[t] = mocha('getSGTimeout');
|
||
%t(1) is minimum put timeout from among all group handles
|
||
%t(2) is minimum get timeout from among all group handles
|
||
|
||
%Timeouts can be set in a number of ways, for all gourp handles
|
||
%or on a per grop handle basis
|
||
|
||
%set both put and get timeouts for group handle, gHandle1, to 10.0 seconds
|
||
status=mocha('setSGTimeout', gHandle1, 10.0);
|
||
|
||
%set both put and get timeouts for all group handles to 10.0 seconds
|
||
status=mocha('setSGTimeout', 10.0);
|
||
|
||
%set put timeout for group handle, gHandle1, to 5.0 seconds
|
||
status=mocha('setSGTimeoutPut', gHandle1, 5.0);
|
||
|
||
%set put timeouts for all group handles to 5.0 seconds
|
||
status=mocha('setSGTimeoutPut', 5.0);
|
||
|
||
%set get timeout for group handle, gHandle1, to 10.0 seconds
|
||
status=mocha('setTimeoutGet', gHandle1, 10.0);
|
||
|
||
%set put timeouts for all group handles to 10.0 seconds
|
||
status=mocha('setSGTimeoutGet', 10.0);
|
||
|
||
%
|
||
%END (15) Setting synchronous group timeouts for set/get operations
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (16) Special Methods, e.g., setAndGet
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(16) Special Methods, e.g., setAndGet, setAndMatch ');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
|
||
%%Several specialized methods exist within the CAFE library,
|
||
%%such as setAndMatch which can set a number of PVs to a given value
|
||
%%and then examines a given collection of readback PVS.
|
||
%%Method verifies whether or not the set/readback values agree within
|
||
%%the given tolerance and timeout. Useful for, e.g., ID Gap Scans,
|
||
%%Other specialized methods can be exposed to mocha on request
|
||
|
||
% \brief Set Channels followed by a corresponding readback of Channels
|
||
% Method verifies whether or not the set/readback values agree within
|
||
% the given tolerance and timeout. ICAFE_NORMAL is returned as soon as
|
||
% a match is reached else ECAFE_TIMEOUT_SET_AND_MATCH if timeout.
|
||
% \param 1 input: 'setAndMatch'
|
||
% \param 2 input: array of handles/pvs to set
|
||
% \param 3 input: array of values to set
|
||
% \param 4 input: array of handles/ov of readback channel
|
||
% \param 5 input: tolerance (+-) margin
|
||
% \param 6 input: timeout value; maximum time allowed for agreement to occur
|
||
% \param 7 input: printFlag bool, set to true for diagnostics
|
||
% \return ECA_NORMAL if all OK else first ECAFE error encountered, else
|
||
% ECAFE_TIMEOUT_SET_AND_MATCH if timeout
|
||
|
||
% For the purpose of this example, the readbnack channels are the same as
|
||
% the input channels thus ensuring that a match is found
|
||
status=mocha ('setAndMatch', pv(1:2), [1.1,2.2], pv(1:2), 0.01, 5.0, true);
|
||
|
||
%%Another simple method is the setAndGet Method
|
||
%%Set a PV and immediately retrieve its value
|
||
|
||
%The method (previously presente in (9) above, initiates a set and is
|
||
%followed immediately by a get.
|
||
%The user should be aware that in the event of other applications writing
|
||
%to the same epics channel, the possibility exists that this external write
|
||
%may occur between the set and subsequent get within the 'setAndGet'.
|
||
|
||
setValue=0.4;
|
||
[getValue, status] = mocha ('setAndGet', pv(1), setValue)
|
||
%The data type of the returned value matches that of the input value.
|
||
|
||
%
|
||
%END (16) Special Methods, e.g., setAndGet
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% (17) Gracefully terminate CAFE
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
disp('Section(17) Gracefully terminate CAFE ');
|
||
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
|
||
|
||
|
||
%Stops all monitors (if any)
|
||
%Closes all channels
|
||
%Releases all CA resources
|
||
mocha ('close')
|
||
%
|
||
%END (17) Gracefully terminate CAFE
|
||
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
|
||
|
||
|
||
|