How do I get the last value for each calendar month using flux? - influxdb

I have a few sensors that every 1st day of the month they reset the value. I have been using the last value with success but didnt find a way to get the max/last value in a given calendar month. For each calendar month, for each sensor I mean. I am a beginner working with flux.
I tried the agreggate with 1 month, but looks like it is not going to the last day of each month, and I wanted to have for each month.
I have several sensors that are cumulative per month, but on the first measurement of the month they go to zero. I wanted to have a way to visualise for each past month what the measurement was last, for all the sensors so I can put in grafana and see each month how it was the consumption.
This is my query, which returns the last value for each of the 20 sensors:
from(bucket: "home")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["friendly_name"] =~ /1MON$/ and r["friendly_name"] !~ /^Main/)
|> filter(fn: (r) => r["_field"] == "value")
|> filter(fn: (r) => r["_measurement"] == "kWh")
|> filter(fn: (r) => r["entity_id"] !~ /2$/)

Related

InfluxDB FluxQL query to show daily average over longer period

I'm trying to get a Flux query that shows me what an average day looks like, over a given period. More specifically, I'm querying power usage data of my freezer, gathered and sent to InfluxDB by home assistant.
As a very basic example, if my freezer would have used 100W during the first 15 days of a 30 day period, and 0W during the last 15 days, the daily average of that 30 day period would be 50W.
What I want to see is a graph of a 24h time period, but with the average data of month.
I have this basic query which shows me a months worth of data:
from(bucket: "home_assistant/autogen")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["friendly_name"] == "Shelly plug S Freezer Power 0")
|> filter(fn: (r) => r["_field"] == "value")
|> aggregateWindow(every: 1h, fn: mean, createEmpty: false)
|> yield(name: "mean")
By playing with the aggregateWindow function, changing the every parameter to 1d will show me the average data per day over those 30 days, but that's not what I want.
If you want to have 30 days average you can take a look at the timeMovingAverage. It will return an average of the current value and all row values in the previous period (duration). It returns moving averages at a frequency defined by every parameter.

How to make a condition inside a query function on sheets?

I've been trying to get a list of people who finish their work shift at an specific our, I have not had any problem with this since I've used just a query function:
=QUERY(A1:K48,"select A where B = '7:00 AM' OR C = 'Sunday' OR D = 'Sunday' OR K = TRUE",0)
So, if someone ends their work shift at 7:00 AM or someone rests on Sunday the formula will return these people's names.
Unfortunately, I'm struggling with the next step since those workers work an extra hour or half extra hour some specific days and I was not be able to include in the formula.
For instance, if today is Sunday and today is the Sean long day in which he has to work one extra hour I would like to this Query Formula doesn't includes the Sean's name at 7:00 AM instead of it I would like to include the Sean's name until 8:00 AM. To do this I add "not" in the query formula:
=QUERY(A1:K48,"select A where B = '7:00 AM' AND NOT E matches 'Sunday' OR C = 'Sunday' OR D = 'Sunday' OR K = TRUE",0)
To indicate that Sean is still working, and the formula shouldn't include his name, but now I don't know how to get Sean's name at 8:00 AM.
This is the sheet where I'm working on this Query: Sheet
https://docs.google.com/spreadsheets/d/1Vk95yM8On5nLlFljFerzDH4IG8dZkOgKyHzX36uUWOQ/edit?usp=sharing
To get a clearer idea: I'm getting a list based on column B, C and D values(normal shift days) but before of getting this result I would like to based the list on column E and column F data (long day and hour of the long day) and then if there is no data to take from the E and F column run the first formula.
I hope someone could help me with this I'll be so obliged. Thank you!

Count how many dates in a list are between two dates

I have the given schema
(t1:Tag)-[c:CONNECTED_TO]-(t2:Tag)
Each relationship of type :CONNECTED_TO has a property that is storing dates as a list.
{
"dates": [
"2019-11-27",
"2019-01-24",
"2017-06-27"
]
}
Now I want to find each relationship where one of the dates is between two dates.
MATCH ()-[c:CONNECTED_TO]-()
WHERE ANY (item IN c.dates WHERE date({year: 2019, month: 12}) > item >= date({year: 2019, month: 10}))
RETURN c
But in addition, I also want to count how many dates in the list-property are between those two dates. For the above example, it should return 1 because only one date on the list is between 2019-12-01 and 2019-10-01.
How can I do that?
Edit
I found the following solution for my problem:
MATCH ()-[c:CONNECTED_TO]-()
WITH [x IN range(0,size(c.dates)-1) WHERE date({year: 2019, month: 12}) > c.dates[x] >= date({year: 2019, month: 1})] AS index, id(c) AS id
RETURN id, size(index) AS Size
Sadly this solution is very slow. The date-list can be of size 10.000 or higher. If there is somebody with a faster solution I would be happy to know.
Your MATCH is scanning ALL the nodes in your database to find the CONNECTED_TO relationships. You should be qualifying the end nodes with the Tag label to scan just the Tag nodes.
You should be calculating the static date values just once.
You should use the REDUCE function instead of list comprehension (which generates new lists that your query will just drop) to count the dates within range.
There is no need to use the RANGE function, which also generates a list.
This query should be faster:
WITH date({year: 2019, month: 12}) AS a, date({year: 2019, month: 1}) AS b
MATCH (:Tag)-[c:CONNECTED_TO]-(:Tag)
RETURN ID(c) AS id, REDUCE(s=0, d IN c.dates | CASE WHEN a > d >= b THEN s + 1 ELSE s END) AS Size

Lua Pattern - How get the required string using this lua pattern

local invoiceData =
[[I N V O I C E
Invoice No. :
ABCDEFG125469857
Invoice Date May
2012
]]
The pattern I am using is
print (string.match(invoiceData,'\nInvoice Date (.-)\n'))
I want to fetch the string invoice date as MAY12. or 0512.. please help
Thanks
Instead of matching with .-, be more specific and use %w+ (alpha-nums) and %d+ (digits) to match the month and year.
The script:
local invoiceData =
[[I N V O I C E
Invoice No. :
ABCDEFG125469857
Invoice Date May
2012
]]
month, year = string.match(invoiceData,'Invoice%s+Date%s+(%w+)%s+%d*(%d%d)')
print(month, year)
will print:
May 12

SQL 'overlaps' only get dates between start and end (not include start and end dates)

I use this query to get objects overlaps the period between "start_date" and "end_date", moreover, I would like get the objects with dates end on start_date and objects begin on end_date.
I use
where("(start_date, end_date) overlaps (date ?, date ?), start_date, end_date"
But the objects has dates <=start_date or >=end_date is not get.
This 'overlaps' only gets objects has dates start_date< dates< end_date, not "=".
For example, start_date='2011/2/1', end_date='2011/3/31'. objects has date ends on '2011/2/1' or start on '2011/3/31' will not be get, only dates between '2011/2/1' and '2011/3/31' will get. how to includes objects which holds date ends on the start_date and start on the end_date?
----------------------Edit----------------------------
I try to use:
where("(start_date, end_date) overlaps (date ?, date ?), start_date-1.day, end_date+1.day"
to solve the issue, but when I do like above, if start_date='2011/2/1', end_date='2011/3/31', then objects holds '2011/1/31' also returns which is supposed should not be get.
On the SQL side, you want to generate something like this, assuming
S1, E1 are the start and end dates of
the first range,
S2, E2 are the start and end dates of
the second range,
none of S1, E1, S2, E2 are NULL
WHERE (S1, E1) OVERLAPS (S2, E2) OR (E1 = S2) OR (E2 = S1)
You need both "OR" clauses, because in the general case you don't know which range is earlier.
try this:
where("start_date >= ? and end_date <= ?", start_date.beginning_of_day, end_date.end_of_day)
that should include all from start_date to end_date ;-) hope it helps!
Just assuming a table Details and having attributes(including date),suppose i want info from two specific dates as from start_date to end_date.
so,
Details.where(["date between ? and ? ",start_date,end_date])
will give the required info including start and end dates.Hope it helps

Resources