Skip to content

Commit

Permalink
Added ChartMetaActions Fucntion for Querying by Truncated Timestamps
Browse files Browse the repository at this point in the history
give it:
- a chart
- a truncation span ("minutes", "hours", "days", etc)
- (optional) time span
- (optional) bbox

and you get aggregated data for the truncated timestamps

Updates #264
  • Loading branch information
Vince Forgione committed Apr 4, 2018
1 parent 259c44a commit 81804a8
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 2 deletions.
31 changes: 29 additions & 2 deletions lib/plenario/actions/chart_meta_actions.ex
Expand Up @@ -55,8 +55,7 @@ defmodule Plenario.Actions.ChartMetaActions do

@template_dir "chart-meta-queries"

def query_time_bucket!(chart, ts_trunc_interval, ts_trunc_span, ts_range \\ nil, bbox \\ nil)
do
def query_time_bucket!(chart, ts_trunc_interval, ts_trunc_span, ts_range \\ nil, bbox \\ nil) do
meta = MetaActions.get(chart.meta_id)

data_fields =
Expand Down Expand Up @@ -85,6 +84,34 @@ defmodule Plenario.Actions.ChartMetaActions do
end
end

def query_time_trunc!(chart, ts_trunc_span, ts_range \\ nil, bbox \\ nil) do
meta = MetaActions.get(chart.meta_id)

data_fields =
chart.data_fields
|> Enum.map(&explode_jsonb_path/1)

filename = Path.join(:code.priv_dir(:plenario), "#{@template_dir}/date_trunc.sql.eex")
sql = EEx.eval_file(filename, [
chart: chart,
table_name: meta.table_name,
ts_range: ts_range,
bbox: bbox,
data_fields: data_fields,
ts_trunc_span: ts_trunc_span,
], trim: true)

case Ecto.Adapters.SQL.query(Repo, sql) do
{:ok, res} ->
res

{:error, error} ->
Logger.error(error.postgres.message)
Logger.error(sql)
raise error
end
end

defp explode_jsonb_path(path) do
fields = String.split(path, ".")
{primary, fields} = List.pop_at(fields, 0)
Expand Down
24 changes: 24 additions & 0 deletions priv/chart-meta-queries/date_trunc.sql.eex
@@ -0,0 +1,24 @@
SELECT
DATE_TRUNC('<%= ts_trunc_span %>', "<%= chart.timestamp_field %>") AS "<%= chart.timestamp_field %>"
<%= for {path, field} <- data_fields do %>
, <%= chart.data_agg_func %>((<%= field %>)::numeric)::float AS "<%= path %>"
<% end %>
FROM
"<%= table_name %>"
<%= if ts_range != nil or bbox != nil do %>
WHERE
<%= if ts_range != nil do %>
'<%= ts_range %>'::tstzrange @> "<%= chart.timestamp_field %>"
<%= if bbox != nil do %>
AND
<% end %>
<% end %>
<%= if bbox != nil do %>
ST_CONTAINS('<%= bbox %>'::geometry, "<%= chart.location_field %>")
<% end %>
<% end %>
GROUP BY
"<%= chart.timestamp_field %>"
ORDER BY
"<%= chart.timestamp_field %>"
;
40 changes: 40 additions & 0 deletions test/plenario/chart_meta_actions_test.exs
Expand Up @@ -155,4 +155,44 @@ defmodule Plenario.Testing.ChartMetaActionsTest do
]
]
end

test :query_time_trunc!, %{meta: meta, vp: vp} do
# insert some more stuff
insert = """
INSERT INTO "#{meta.table_name}"
(node_id, timestamp, longitude, latitude, observations)
VALUES
('001', '2018-01-01 00:01:00+00:00', -87.71, 42.1, '{"BMP180": {"temperature": -1.64}, "HTU21D": {"humidity": 71.94, "temperature": -0.78}, "TSYS01": {"temperature": -1.1}}'),
('001', '2018-01-01 00:02:30+00:00', -87.71, 42.1, '{"BMP180": {"temperature": -1.66}, "HTU21D": {"temperature": -0.78}, "TSYS01": {"temperature": -1.1}}'),
('002', '2018-01-01 00:33:00+00:00', -87.72, 42.1, '{"BMP180": {"temperature": -1.65}, "HTU21D": {"humidity": 71.94, "temperature": -0.78}}'),
('003', '2018-01-01 00:04:00+00:00', -87.73, 42.1, '{"BMP180": {"temperature": -1.65}, "HTU21D": {"humidity": 71.94, "temperature": -0.78}, "TSYS01": {"temperature": -1.1}}'),
('004', '2018-01-01 00:25:00+00:00', -87.74, 42.1, '{"BMP180": {"temperature": -1.65}, "HTU21D": {"humidity": 71.94, "temperature": -0.78}, "TSYS01": {"temperature": -1.1}}'),
('005', '2018-01-01 00:16:00+00:00', -87.75, 42.1, '{"bananas": 1}')
;
"""
{:ok, _} = Ecto.Adapters.SQL.query(Repo, insert)


{:ok, cm} = ChartMetaActions.create(
meta, "name", "description", "timestamp", vp.name,
["observations.BMP180.temperature"], "avg")

%Postgrex.Result{columns: cols, rows: rows, num_rows: 8} =
ChartMetaActions.query_time_trunc!(cm, "minutes")

assert cols == [
"timestamp", "observations.BMP180.temperature"
]

assert rows == [
[{{2018, 1, 1}, {0, 0, 0, 0}}, -1.66],
[{{2018, 1, 1}, {0, 0, 0, 0}}, -1.6475],
[{{2018, 1, 1}, {0, 1, 0, 0}}, -1.64],
[{{2018, 1, 1}, {0, 2, 0, 0}}, -1.66],
[{{2018, 1, 1}, {0, 4, 0, 0}}, -1.65],
[{{2018, 1, 1}, {0, 16, 0, 0}}, nil],
[{{2018, 1, 1}, {0, 25, 0, 0}}, -1.65],
[{{2018, 1, 1}, {0, 33, 0, 0}}, -1.65]
]
end
end

0 comments on commit 81804a8

Please sign in to comment.