Skip to content

Commit 41c3471

Browse files
author
Eugene Tan
committed
Initial commit. Test file.
0 parents  commit 41c3471

File tree

13,978 files changed

+2419062
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

13,978 files changed

+2419062
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
classdef ArchAppliance
2+
%ArchAppliance Interface to the SLAC Archiver Appliance
3+
% The Archiver Appliance (http://epicsarchiverap.sourceforge.net)
4+
% allows many operations via a REST-style HTTP interface.
5+
% This class makes these operations simple from Matlab.
6+
%
7+
% EXAMPLES
8+
% aa = ArchAppliance(); % Create default instance
9+
% data = aa.getData('mypv', '2013-10-14T08:00:00Z', '2013-10-15T08:00:00Z')
10+
%
11+
% PROPERTY INITIALIZATION:
12+
% The properties for this class may be set through an initialization
13+
% file (pointed to by $ARCHAPPL_INIFILE), environment variables,
14+
% and/or through arguments to the constructor.
15+
% The order of precedence follows this order, so parameters set
16+
% in the initialization file are overridden by individual
17+
% environment variables, and environment variables are overridden
18+
% by arguments to the constructor.
19+
%
20+
% The environment variables are:
21+
% ARCHAPPL_INIFILE: path/filename to the initialization file. The
22+
% file format is name=value, one per line, where the allowable names
23+
% are the remaining environment variables.
24+
% ARCHAPPL_HOSTNAME: DNS name (or ip address) of the server where
25+
% an archiver appliance can be contacted. The data retrieval and
26+
% management components must both be running on the host.
27+
% ARCHAPPL_RETRIEVALPORT: Port number at which the retrieval
28+
% component can be reached. Default = 17668.
29+
% ARCHAPPL_MGMTPORT: Port number at which the management
30+
% component can be reached. Default = 17665.
31+
% ARCHAPPL_RETRIEVALPATH: Base path to the retrieval component.
32+
% Default is "/retrieval/data/", and should not need to be changed.
33+
% ARCHAPPL_MGMTPATH: Base path to the management component.
34+
% Default is "/mgmt/bpl/", and should not need to be changed.
35+
%
36+
% See also getAAData
37+
%
38+
% Copyright (c) Lawrence Berkeley National Laboratory
39+
properties
40+
% The server name where the archiver appliance can be contacted
41+
hostname = 'arch02.als.lbl.gov';
42+
% The port on which the retrieval engine runs
43+
retrievalport = 17668;
44+
% The URL base path for the retrieval component. This should never
45+
% need to be changed.
46+
retrievalpath = '/retrieval/data/';
47+
% The URL base path for the management component. This should never
48+
% need to be changed.
49+
mgmtpath = '/mgmt/bpl/';
50+
% The port on which the management component runs
51+
mgmtport = 17665;
52+
53+
end
54+
55+
methods
56+
function AA = ArchAppliance(hostname, retrievalport, mgmtport, retrievalpath, mgmtpath)
57+
%Constructor all arguments are optional
58+
% If any arguments are specified, they will override the environment variables
59+
% Arguments:
60+
% hostname: string the appliance server name
61+
% retrievalpath: string the base of the retrieval URL path
62+
% mgmtpath: string the base of the management URL path
63+
% retrievalport: integer the port of the retrieval component
64+
% mgmtport: integer the port of the management component
65+
narginchk(0,5);
66+
AA = AA.initializeEnvironment();
67+
if nargin >= 1
68+
AA.hostname = hostname;
69+
end
70+
if nargin >= 2
71+
AA.retrievalport = retrievalport;
72+
end
73+
if nargin >= 3
74+
AA.mgmtport = mgmtport;
75+
end
76+
if nargin >= 4
77+
AA.retrievalpath = retrievalpath;
78+
end
79+
if nargin >= 5
80+
AA.mgmtpath = mgmtpath;
81+
end
82+
end
83+
84+
function dat = getData(AA, pvname, from, to)
85+
%getData Retrieve data for a pv from the archiver appliance
86+
%Retrieves data for pvname over the time period from:to
87+
%pvname: the name of the pv
88+
%from: the start date/time in ISO 8601 format
89+
%to: the end date/time in ISO 8601 format
90+
%Note on time format: Use YYYY-MM-DDTHH:MM:SS.FFFZ. The
91+
%timezone may replace Z, e.g. -08 for PST.
92+
%Returns a 1x1 struct containing subelements header and data.
93+
%These are each structs with the elements:
94+
% header:
95+
% source (e.g. "Archiver appliance")
96+
% pvName
97+
% from = startdate in UTC
98+
% to = enddate in UTC
99+
% data: (N = #samples retrieved)
100+
% values = Nx1 double, or NxM double if pv is a waveform
101+
% epochSeconds = Nx1 int64
102+
% nanos = Nx1 int64
103+
% isDST = Nx1 uint8
104+
105+
url = strcat('http://', AA.hostname, ...
106+
':', int2str(AA.retrievalport), ...
107+
AA.retrievalpath, ...
108+
'getData.mat');
109+
urlwrite(url, 'AAtemp.mat', 'get', ...
110+
{'pv', pvname, ...
111+
'from', from, ...
112+
'to', to});
113+
dat = load('AAtemp.mat');
114+
delete('AAtemp.mat');
115+
end
116+
117+
function lst = getPVs(AA, wildcard)
118+
%getPVs Retrieve the list of pv names
119+
%Retrieves a 1xN array of pv names, limited by an optional
120+
%wildcard.
121+
%Examples:
122+
% lst = AA.getPVs()
123+
% Returns all pv names in the archiver appliance. Note
124+
% that this can return millions of pvs.
125+
% lst = AA.getPVs('cmm:*')
126+
% Returns all pv names that start with "cmm:"
127+
url = strcat('http://', AA.hostname, ...
128+
':', int2str(AA.mgmtport), ...
129+
AA.mgmtpath, ...
130+
'getAllPVs');
131+
if nargin == 1
132+
str = urlread(url);
133+
else
134+
str = urlread(url, 'get', {'pv', wildcard});
135+
end
136+
% Giving up some flexibility by not using parse_json here
137+
% because it is potentially very slow if lots of pvs are
138+
% returned.
139+
if str(1) == '['
140+
str2 = str(3:length(str)-3);
141+
lst = strsplit(str2, '","');
142+
else
143+
lst = [];
144+
end
145+
end
146+
147+
function stats = getPVStatus(AA, pvnames)
148+
%getPVStatus Get the status of a PV
149+
%Retrieves the archiving status of one or more pvs.
150+
%param pvnames: the name(s)of the pv for which status
151+
%is to be determined. If a pv is not being archived,
152+
%the returned status will be "Not being archived."
153+
%You can also pass in GLOB wildcards here and multiple
154+
%PVs as vector.
155+
url = strcat('http://', AA.hostname, ...
156+
':', int2str(AA.mgmtport), ...
157+
AA.mgmtpath, ...
158+
'getPVStatus');
159+
if isa(pvnames, 'char')
160+
result = urlread(url, 'get', {'pv', pvnames});
161+
else
162+
result = urlread(url, 'post', ...
163+
{'pv', strjoin(pvnames, ',')});
164+
end
165+
stats = parse_json(result);
166+
end
167+
168+
function info = getPVTypeInfo(AA, pvname)
169+
%getPVTypeInfo Get the type info for a given PV.
170+
%In the archiver appliance terminology, the PVTypeInfo
171+
%contains the various archiving parameters for a PV.
172+
url = strcat('http://', AA.hostname, ...
173+
':', int2str(AA.mgmtport), ...
174+
AA.mgmtpath, ...
175+
'getPVTypeInfo');
176+
result = urlread(url, 'get', {'pv', pvname});
177+
info = parse_json(result);
178+
end
179+
180+
function info = getNeverConnectedPVs(AA)
181+
%getNeverConnectedPVs Get a list of PVs that have never
182+
%connected.
183+
url = strcat('http://', AA.hostname, ...
184+
':', int2str(AA.mgmtport), ...
185+
AA.mgmtpath, ...
186+
'getNeverConnectedPVs');
187+
result = urlread(url);
188+
info = parse_json(result);
189+
end
190+
191+
function info = getCurrentlyDisconnectedPVs(AA)
192+
%getCurrentlyDisconnectedPVs Get a list of PVs that are
193+
%currently disconnected.
194+
url = strcat('http://', AA.hostname, ...
195+
':', int2str(AA.mgmtport), ...
196+
AA.mgmtpath, ...
197+
'getCurrentlyDisconnectedPVs');
198+
result = urlread(url);
199+
info = parse_json(result);
200+
end
201+
end
202+
203+
methods (Access = private)
204+
function AA = initializeEnvironment(AA)
205+
%initializeEnvironment Initializes AA from environment variables
206+
%If ARCHAPPL_INIFILE is set, attempts to read settings from it first.
207+
%Other environment variables will override settings from ARCHAPPL_INIFILE.
208+
%If arguments are provided to the AA constructor, they will override
209+
%all settings from environment variables.
210+
path = getenv('ARCHAPPL_INIFILE');
211+
if ~isempty(path)
212+
fid = fopen(path, 'r');
213+
if fid == -1
214+
exc = MException('ArchAppliance:InvalidPath', ...
215+
'ARCHAPPL_INIFILE env. variable points to a nonexistent path (%s)', path);
216+
throw(exc);
217+
end
218+
vars = textscan(fid, '%s %s', 'delimiter', '=', 'commentStyle', '#')
219+
AA = AA.setFromEnv(vars{1}, vars{2});
220+
end
221+
end
222+
223+
function AA = setFromEnv(AA, name, value)
224+
for i = 1:length(name)
225+
n = char(name{i})
226+
v = char(value{i})
227+
switch(n)
228+
case 'ARCHAPPL_SERVER'
229+
AA.hostname = v;
230+
case 'ARCHAPPL_RETRIEVALPORT'
231+
AA.retrievalport = str2double(v);
232+
case 'ARCHAPPL_RETRIEVALPATH'
233+
AA.retrievalpath = v;
234+
case 'ARCHAPPL_MGMTPORT'
235+
AA.mgmtport = str2double(v);
236+
case 'ARCHAPPL_MGMTPATH'
237+
AA.mgmtpath = v;
238+
otherwise
239+
warning('Unexpected environment variable name %s, skipping', n);
240+
end
241+
end
242+
end
243+
end
244+
245+
end
246+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
% MATLAB
2+
%
3+
% Files
4+
% ArchAppliance - ArchAppliance Interface to the SLAC Archiver Appliance
5+
% getAACurrentlyDisconnectedPVs - getAACurrentlyDisconnectedPVs Get a list of PVs that are
6+
% getAAData - getAAData Retrieves data from the archiver appliance
7+
% getAANeverConnectedPVs - getNeverConnectedPVs Get a list of PVs that have never
8+
% getAAPVs - getAAPVs Retrieves pv names from the archiver appliance
9+
% getAAPVStatus - getAAPVStatus Get the status of a PV
10+
% getAAPVTypeInfo - getAAPVTypeInfo Get the type info for a given PV.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
function aa = aaepoch2datenum(aa)
2+
3+
DateNumber1970 = 719529; %datenum('1-Jan-1970');
4+
5+
if isstruct(aa)
6+
TimeZoneDiff = (double(aa.data.isDST) - 8) / 24;
7+
8+
SecondsDateNum = double(aa.data.epochSeconds)/60/60/24;
9+
nSecondsDateNum = double(aa.data.nanos)/1e9/60/60/24;
10+
aa.data.datenum = SecondsDateNum + nSecondsDateNum + DateNumber1970 + TimeZoneDiff;
11+
12+
%datestr(aaDateNum(1), 'yyyy-mm-dd HH:MM:SS.FFF')
13+
%datestr(aaDateNum(end), 'yyyy-mm-dd HH:MM:SS.FFF')
14+
else
15+
16+
end
17+
18+
19+
20+
% This is what labca2datenum does. AA is already in local time.
21+
% TimeZoneDiff = getfamilydata('TimeZone')
22+
%
23+
% DateNumber1970 = 719529; %datenum('1-Jan-1970');
24+
%
25+
% if isempty(TimeZoneDiff)
26+
% % The problem with doing this is if the PV wasn't processed in the last .5 hours, it will be treated like a time zone change!!!
27+
% t0 = clock;
28+
% days = datenum(t0(1:3)) - DateNumber1970;
29+
% t0_sec = 24*60*60*days + 60*60*t0(4) + 60*t0(5) + t0(6);
30+
% TimeZoneDiff = round((t0_sec - real(DataTime(1,1)))/60/60);
31+
% end
32+
%
33+
% DataTime = (real(DataTime)/60/60 + TimeZoneDiff)/24 + DateNumber1970 + imag(DataTime)/(1e9 * 60 * 60 * 24);
1.35 MB
Binary file not shown.
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function info = getAACurrentlyDisconnectedPVs()
2+
%GETAACURRENTLYDISCONNECTEDPVS Get a list of PVs that are
3+
%currently disconnected.
4+
% Copyright (c) Lawrence Berkeley National Laboratory
5+
6+
aa = ArchAppliance();
7+
info = aa.getCurrentlyDisconnectedPVs();
8+
9+
end
10+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
function [ output_args ] = getAAData( pvname, startdate, enddate )
2+
%getAAData Retrieves data from the archiver appliance
3+
% Archiver data are retrieved for a pv over a given
4+
% time range.
5+
% getAAData('mypv', '2008-01-01T00:00:00-08', '2008-12-31T23:59:59-08')
6+
% Retrieves data for the pv "mypv" for all of 2008, in Pacific
7+
% Standard Time
8+
%
9+
% @param pvname the pv name
10+
% @param startdate a string representing the start date/time in ISO 8601
11+
% format
12+
% @param enddate a string representing the end date/time in ISO 8601
13+
% format
14+
% @output a 1x1 struct containing subelements header and data. These are
15+
% each structs with the elements:
16+
% header:
17+
% source (e.g. "Archiver appliance")
18+
% pvName
19+
% from = startdate
20+
% to = enddate
21+
% data: (N = # samples)
22+
% values = Nx1 double, or NxM double if pv is a waveform
23+
% epochSeconds = Nx1 int64
24+
% nanos = Nx1 int64
25+
% isDST = Nx1 uint8
26+
%
27+
% Formats for startdate, enddate: The ISO 8601 format is
28+
% YYYY-MM-DDTHH:MM:SS.UZ where:
29+
% YYYY-MM-DD = Year, month, date
30+
% T = Delimiter between date and time (a literal "T")
31+
% HH:MM:SS = Hour, minute, second
32+
% .F = Fractional part of second
33+
% Z = Optional timezone. If not specified, local time is used. If
34+
% specified and "Z", UTC time is used. May also be specified as
35+
% +/-HH, where HH is hours, e.g. -08 for Pacific Standard Time.
36+
% Examples of valid date/time representations:
37+
% 2000-07-04T00:00:00-07 July 4, 2000 midnight, PDT
38+
% 2013-11-22T08:00:00Z Nov. 22, 2013 at 08:00 am UTC (=midnight PST)
39+
%
40+
% See also ArchAppliance.getData
41+
%
42+
% Copyright (c) Lawrence Berkeley National Laboratory
43+
44+
aa = ArchAppliance();
45+
output_args = aa.getData(pvname, startdate, enddate);
46+
47+
end
48+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function [ output ] = getAANeverConnectedPVs()
2+
%getAANeverConnectedPVs Get a list of PVs that have never
3+
%connected.
4+
% Copyright (c) Lawrence Berkeley National Laboratory
5+
6+
aa = ArchAppliance();
7+
output = aa.getNeverConnectedPVs();
8+
9+
end
10+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function [ output_args ] = getAAPVStatus( pvnames )
2+
%getAAPVStatus Get the status of a PV
3+
%Retrieves the archiving status of one or more pvs.
4+
%param pvnames: the name(s)of the pv for which status
5+
%is to be determined. If a pv is not being archived,
6+
%the returned status will be "Not being archived."
7+
%You can also pass in GLOB wildcards here and
8+
%multiple PVs as vector.
9+
% See also ArchAppliance.getPVStatus
10+
11+
aa = ArchAppliance();
12+
output_args = aa.getPVStatus(pvnames);
13+
14+
end
15+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function [ output ] = getAAPVTypeInfo( pvname )
2+
%GETAAPVTYPEINFO Get the type info for a given PV.
3+
%In the archiver appliance terminology, the PVTypeInfo
4+
%contains the various archiving parameters for a PV.
5+
% Copyright (c) Lawrence Berkeley National Laboratory
6+
7+
aa = ArchAppliance();
8+
output = aa.getPVTypeInfo(pvname);
9+
end
10+

0 commit comments

Comments
 (0)