7

I have data in an influxdb database from a door sensor. This is a boolean sensor (either the door is open (value is false) or it is closed (value is true)), and the table looks like:

name: door
--------------
time            value
1506026143659488953 true
1506026183699139512 false
1506026751433484237 true
1506026761473122666 false
1506043848850764808 true
1506043887602743375 false

I would like to calculate how long the door was open in a given period of time. The ELAPSED function gets me close, but I'm not sure how to either (a) restrict it to only those intervals for which the intitial value is false, or (b) identify "open" intervals from the output of something like select elapsed(value, 1s) from door.

I was hoping I could do something like:

select elapsed(value, 1s), first(value) from door

But that doesn't get me anything useful:

name: door
--------------
time            elapsed first
0               true
1506026183699139512 40  
1506026751433484237 567 
1506026761473122666 10  
1506043848850764808 17087   
1506043887602743375 38  

I was hoping for something more along the lines of:

name: door
--------------
time            elapsed first
1506026183699139512 40  true
1506026751433484237 567 false
1506026761473122666 10  true
1506043848850764808 17087   false
1506043887602743375 38  true

Short of extracting the data myself and processing it in e.g. python, is there any way to do this via an influxdb query?

larsks
  • 277,717
  • 41
  • 399
  • 399
  • doesn't look like it is supported today - https://stackoverflow.com/questions/27959196/calculating-duration-between-a-start-and-end-event-in-influxdb?rq=1. Lack of native query support also means that there is no way to display this info in viz tools like Grafana. I have only got this to work with client side processing and adding an extra info into a measurement that can be used for rendering in Grafana. – Vinod Sep 25 '17 at 19:24

3 Answers3

0

I came across this problem as well, I wanted to sum the durations of times for which a flag is on, which is pretty common in signal processing in time series libraries, but influxdb just doesn't seem to support that very well. I tried INTEGRATE with a flag of value 1 but it just didn't seem to give me correct values. In the end, I resorted to just calculating intervals in my data source, publishing those as a separate field in influxdb and summing them up. It works much better that way.

Luc
  • 71
  • 1
  • 4
0

This is the closest I have found so far:

https://community.influxdata.com/t/storing-duration-in-influxdb/4669

The idea is to store the boolean event as 0or 1 and to store each state changes with two entries with one unit of time difference. It would look something like this:

name: door
--------------
time            value
1506026143659488953 1
1506026183699139511 1
1506026183699139512 0
1506026751433484236 0
1506026751433484237 1
1506026761473122665 1
1506026761473122666 0
1506043848850764807 0
1506043848850764808 1
1506043887602743374 1
1506043887602743375 0

It should then be possible to use a query like this:

SELECT integral(value) FROM "door" WHERE time > x and time < y

I'm new to influx so let me know if this is a bad way of doing things today. I also haven't tested the example I've written here.

MrBerta
  • 2,457
  • 12
  • 24
0

I had this same problem. After running into this wall with InfluxDB and finding no clean solutions here or elsewhere, I ended up switching to TimescaleDB (PostgreSQL-based) and solving it with a SQL window function, using lag() to calculate the delta to the previous time value.

For the OP's dataset, a possible solution looks like this:

SELECT
  "time",
  ("time" - lag("time") OVER (ORDER BY "time"))/1000000000 AS elapsed,
  value AS first
FROM door
ORDER BY 1
OFFSET 1;  -- omit the initial zero value

Input:

CREATE TEMPORARY TABLE "door" (time bigint, value boolean);
INSERT INTO "door" VALUES
  (1506026143659488953, true),
  (1506026183699139512, false),
  (1506026751433484237, true),
  (1506026761473122666, false),
  (1506043848850764808, true),
  (1506043887602743375, false);

Output:

        time         | elapsed | first 
---------------------+---------+-------
 1506026183699139512 |      40 | f
 1506026751433484237 |     567 | t
 1506026761473122666 |      10 | f
 1506043848850764808 |   17087 | t
 1506043887602743375 |      38 | f
(5 rows)
jrc
  • 20,354
  • 10
  • 69
  • 64
  • Very nice! I've worked a bit with timescaledb in the past, but at the time I was frustrated by the lack of data retention policies. It looks like things may have changed since I last looked. – larsks Oct 09 '20 at 14:28
  • Looks like InfluxDB 2 has a native solution: https://docs.influxdata.com/influxdb/v2.0/query-data/flux/monitor-states/ – jrc May 26 '21 at 13:46