How to use stateChangesOnly()

Hi @Anaisdg,
stateChanges works for me, and I want to get the record just state changed.
I use the stateChangesOnly but get empty record

stateChanges :
import “influxdata/influxdb/monitor”
import “influxdata/influxdb/schema”
from(bucket: “Mybucket”)
|> range(start: 2021-12-22T00:00:00Z, stop: 2021-12-22T23:59:59Z)
|> filter(fn: (r) => r["_measurement"] == “Sensor”)
|> filter(fn: (r) => r[“SensorId”] == “sensor0”)
|> rename(columns: {“MyLevel”: “_level”})
|> monitor.stateChanges(fromLevel: “0”, toLevel: “1”)
|> aggregateWindow(every: 1h, fn: count,column: “MyState”, createEmpty: true)

stateChangesOnly :
import “influxdata/influxdb/monitor”
import “influxdata/influxdb/schema”
from(bucket: “Mybucket”)
|> range(start: 2021-12-22T00:00:00Z, stop: 2021-12-22T23:59:59Z)
|> filter(fn: (r) => r["_measurement"] == “Sensor”)
|> filter(fn: (r) => r[“SensorId”] == “sensor0”)
|> rename(columns: {“MyLevel”: “_level”})
|> monitor.stateChangesOnly()

 thanks

Hello @Erikson,
Can you please share some of your data?

Hi @Anaisdg

,result,table,_time,_start,_stop,SensorId,_measurement,MyLevel
,,0,2022-01-04T01:21:32.749972517Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T01:24:14.051705026Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T01:30:54.375700332Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,0
,,0,2022-01-04T01:31:57.76111273Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T01:33:36.0650061Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T01:40:11.500062982Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T01:54:06.227517383Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T02:11:19.635009545Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,0
,,0,2022-01-04T02:22:45.199428528Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1
,,0,2022-01-04T02:27:20.917940063Z,2022-01-03T16:00:00Z,2022-01-04T16:00:00Z,5FA6,TestSensor,1

I am having the exact same problem myself, when running monitor.stateChanges() I get data back, but when using monitor.stateChangesOnly() nothing shows up.

@MWinther and @Erikson
Is the column name with the level named _level? If not it won’t work.
You can use rename() to change the column name.

#group,false,false,true,true,false,false,true,true,true
#datatype,string,long,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string,string,string
#default,_result,,,,,,,,
,result,table,_start,_stop,_time,_value,_field,_measurement,host
,,0,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:00Z,on,used_percent,mem,host1
,,0,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:10Z,on,used_percent,mem,host1
,,0,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:20Z,off,used_percent,mem,host1
,,1,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:00Z,off,used_percent,mem,host2
,,1,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:10Z,on,used_percent,mem,host2
,,1,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:20Z,off,used_percent,mem,host2

And the flux code:

import "influxdata/influxdb/monitor"
from(bucket: "test_bucket")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r.host == "host1")
  |> rename(columns: {"_value": "_level"})
  |> monitor.stateChangesOnly()

yields “no results” in the data explorer, whereas

import "influxdata/influxdb/monitor"
from(bucket: "test_bucket")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r.host == "host1")
  |> rename(columns: {"_value": "_level"})
  |> monitor.stateChanges(fromLevel: "on", toLevel: "off")

yields

#group,false,false,true,true,true,true,false,true,true
#datatype,string,long,string,string,dateTime:RFC3339,dateTime:RFC3339,dateTime:RFC3339,string,string
#default,_result,,,,,,,,
,result,table,_field,_measurement,_start,_stop,_time,host,_level
,,0,used_percent,mem,2019-09-16T20:30:51Z,2022-03-13T22:30:51.381Z,2020-01-01T00:00:20Z,host1,off

Please help.

Hi,
It looks like monitor.stateChangesOnly() only works if _level contains values ok, info, warn, or crit. You could possibly use monitor.stateChanges() or just convert the values to conform to the expected values before using monitor.stateChangesOnly().

Example:

import "influxdata/influxdb/monitor"
from(bucket: "test_bucket")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r.host == "host1")
  |> map(fn: (r) => ({ r with _level: if r._value == "off" then "crit" else "ok" }))
  |> monitor.stateChangesOnly()

Let us know if this worked. I can also check as to why the monitor.stateChangesOnly() was not designed to work in all situations.

Regards
Balaji

1 Like

Wow, that explains so much, thank you for the information! From what I can tell, this information is not available in the documentation here monitor.stateChangesOnly() function | Flux 0.x Documentation , so if this is the expected behavior, it would be nice if it was added to that page, especially since stateChanges() seem to accept other values.