Skip to content

Instantly share code, notes, and snippets.

@decentlab
Last active November 22, 2023 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save decentlab/e1afb40f4bfcebdab7163c2de863b581 to your computer and use it in GitHub Desktop.
Save decentlab/e1afb40f4bfcebdab7163c2de863b581 to your computer and use it in GitHub Desktop.
Data query API in MATLAB
% MIT License
% Copyright (c) 2016 Decentlab GmbH
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.
function t = query(Domain, ApiKey, TimeFilter, varargin)
p = inputParser;
addRequired(p, 'Domain')
addRequired(p, 'ApiKey')
addRequired(p, 'TimeFilter')
addOptional(p, 'Device', '//')
addOptional(p, 'Location', '//')
addOptional(p, 'Sensor', '//')
addOptional(p, 'IncludeNetworkSensors', false, @islogical)
addOptional(p, 'Channel', '//')
addOptional(p, 'AggFunc', '')
addOptional(p, 'AggInterval', '')
addOptional(p, 'Database', 'main')
addOptional(p, 'Timeout', 20)
addOptional(p, 'DoUnstack', true, @islogical)
addOptional(p, 'ConvertTimestamp', true, @islogical)
addOptional(p, 'Timezone', 'UTC')
parse(p, Domain, ApiKey, TimeFilter, varargin{:})
selectVar = 'value';
fill = '';
interval = '';
networkSensors = ' AND channel !~ /^link-/)';
timeFilter = '';
baseUrl = ['https://' p.Results.Domain '/api/datasources/proxy/uid/' p.Results.Database '/query'];
if ~isempty(p.Results.AggFunc)
selectVar = [p.Results.AggFunc '("value") as value'];
fill = 'fill(null)';
end
if ~isempty(p.Results.AggInterval)
interval = [', time(' p.Results.AggInterval ')'];
end
if ~isempty(p.Results.TimeFilter)
timeFilter = [' AND ', p.Results.TimeFilter];
end
if p.Results.IncludeNetworkSensors
networkSensors = ')';
end
filter = [' location =~ ' p.Results.Location ...
' AND node =~ ' p.Results.Device ...
' AND sensor =~ ' p.Results.Sensor ...
' AND ((channel =~ ' p.Results.Channel ' OR channel !~ /.+/)'...
networkSensors];
q = ['SELECT ' selectVar ' FROM "measurements" ' ...
' WHERE ' filter ' ' timeFilter ...
' GROUP BY "uqk" ' interval ' ' fill];
options = weboptions('KeyName', 'Authorization', ...
'KeyValue', ['Bearer ' p.Results.ApiKey], ...
'Timeout', p.Results.Timeout);
ret = webread(baseUrl, 'db', p.Results.Database, 'epoch', 'ms', 'q', q, options);
if ~isfield(ret.results, 'series')
msg = 'No series returned: ';
if isfield(ret.results, 'message')
msg = [msg ret.results.message ' '];
end
if isfield(ret.results, 'error')
msg = [msg ret.results.error ' '];
end
error(msg)
end
repl = @(series) repmat({series.tags.uqk}, size(series.values, 1), 1);
series = arrayfun(repl, ret.results.series, 'UniformOutput', false);
series = vertcat(series{:});
vals = vertcat(ret.results.series.values);
time = vals(:,1);
value = vals(:,2);
if p.Results.ConvertTimestamp
time = datetime(time / 1000, 'ConvertFrom', 'posixtime', ...
'Timezone', p.Results.Timezone);
end
t = table(time, series, value);
if p.Results.DoUnstack
warning('off', 'MATLAB:table:ModifiedVarnames')
t = unstack(t, 'value', 'series');
warning('on', 'MATLAB:table:ModifiedVarnames')
end
t = sortrows(t, 'time');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment