Error while trying to use conditionnal

Hello,

I’m trying to automate bytesIn measurement from interface depending of my router’s model.
I wrote this query where $hostname and $model are already defined and working:

> from(bucket: "telegraf/autogen")
>   |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
>   |> filter(fn: (r) => r["hostname"] == "$hostname")
>   |> filter(fn: (r) => r["_field"] == "${Model}")
>   |> filter(fn: (r) => if ${Model} == "RouterOS RBD53GR-5HacD2HnD" then
>                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r.if-name == "lte1" and r._field == "bytesIn"
>                     else
>                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r.if-name == "ether1" and r._field == "bytesIn",
>                     )
>   |> map(fn: (r) => ({r with _value: r._value *8}))
>   |> derivative(unit: 1s, nonNegative: false)
>   |> yield(name: "derivative")

This is not working, I have this error:
invalid: compilation failed: error at @6:21-6:22: expected THEN, got IDENT (RB2011UiAS) at 5:36 error at @6:21-6:22: expected THEN, got SUB (-) at 5:46 error at @6:21-6:22: expected THEN, got INT (2) at 5:47 error at @6:21-6:22: expected THEN, got IDENT (HnD) at 5:48 error at @6:21-6:22: expected THEN, got EQ (==) at 5:52 error at @6:21-6:22: expected THEN, got STRING ("RouterOS RBD53GR-5HacD2HnD") at 5:55 error at @6:108-6:112: expected IDENT, got IF (if) at 6:105 error at @6:108-6:112: expected IDENT, got SUB (-) at 6:107 error at @8:108-8:112: expected IDENT, got IF (if) at 8:105 error at @8:108-8:112: expected IDENT, got SUB (-) at 8:107

What I doing wrong ?

Regards,

@Tiki10 One error I see is that you need to wrap ${Model} in your conditional in quotes. I’m wondering if that will fix the rest of the errors.

- |> filter(fn: (r) => if ${Model} == //...
+ |> filter(fn: (r) => if "${Model}" == //...

Hello Scott,

Thank you for your reply.
I have tested with your syntax and I have another error:
invalid: compilation failed: error at @6:109-6:113: expected IDENT, got IF (if) at 6:106 error at @6:109-6:113: expected IDENT, got SUB (-) at 6:108 error at @8:109-8:113: expected IDENT, got IF (if) at 8:106 error at @8:109-8:113: expected IDENT, got SUB (-) at 8:108

As “$model” is already defined in variable like that:

from(bucket: "telegraf/autogen")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "snmp")
  |> filter(fn: (r) => r["hostname"] == "${hostname}")
  |> filter(fn: (r) => r["_field"] == "Modèle")
  |> aggregateWindow(every: v.windowPeriod, fn: distinct, createEmpty: false)

I’ve tried with this query:

from(bucket: "telegraf/autogen")
   |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
   |> filter(fn: (r) => if "${Model}" == "RouterOS RBD53GR-5HacD2HnD" then
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r.if-name == "lte1" and r._field == "bytesIn"
                     else
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r.if-name == "ether1" and r._field == "bytesIn",
                    )
   |> map(fn: (r) => ({r with _value: r._value *8}))
   |> derivative(unit: 1s, nonNegative: false)
   |> yield(name: "derivative")

And I have a similar error:
invalid: compilation failed: error at @4:109-4:113: expected IDENT, got IF (if) at 4:106 error at @4:109-4:113: expected IDENT, got SUB (-) at 4:108 error at @6:109-6:113: expected IDENT, got IF (if) at 6:106 error at @6:109-6:113: expected IDENT, got SUB (-) at 6:108

Regards,

Ah, I needed to scroll over more :smile:. Right now, r.if-name is being parsed as a conditional statement and an arithmetic operation (-). Becuase you have a dash in the property key, you need to use bracket notation instead of dot notation.

Try this:

from(bucket: "telegraf/autogen")
   |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
   |> filter(fn: (r) => if "${Model}" == "RouterOS RBD53GR-5HacD2HnD" then
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r["if-name"] == "lte1" and r._field == "bytesIn"
                     else
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r["if-name"] == "ether1" and r._field == "bytesIn",
                    )
   |> map(fn: (r) => ({r with _value: r._value *8}))
   |> derivative(unit: 1s, nonNegative: false)

Hello Scott,

Thank you for your time, patience and advices.
Syntax was, indeed, the problem.
Now, I have another error : invalid: runtime error @3:7-7:22: filter: type conflict: int != string
There is a way to have something like “echo” or “var_dump”. I’d like to have _value’s return. _value should be an integer and it seems to be a string.

Regards,

I don’t think this is an error related to the type of your _value column. I think it’s an error related to the types used in your predicate. What version of InfluxDB / Flux are you using? I’m wondering if you’re using and older version of Flux that doesn’t automatically interpolate numeric values in strings (fixed in Flux 0.109) and your Model variable is actually an integer. If that’s the case, try this:

// ...
   |> filter(fn: (r) => if "${string(v: Model)}" == "RouterOS RBD53GR-5HacD2HnD" then
// ...

Hello Scott,

Influx version 's return is :
root@poc ~ $ influx version
Influx CLI 2.2.1 (git: 31ac783) build_date: 2021-11-09T21:24:22Z

With:

from(bucket: "telegraf/autogen")
   |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
   |> filter(fn: (r) => if "${string(v: ${Model})}" == "RouterOS RBD53GR-5HacD2HnD" then
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r["if-name"] == "lte1" and r._field == "bytesIn"
                     else
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r["if-name"] == "ether1" and r._field == "bytesIn"
                    )
   |> map(fn: (r) => ({r with _value: r._value * 8}))
   |> derivative(unit: 1s, nonNegative: false)

I have this error:
invalid: error @3:41-3:49: undefined identifier RouterOS error @3:50-3:57: undefined identifier RBD53GR error @3:41-3:59: invalid binary operator <INVALID_OP> error @3:59-3:67: undefined identifier HacD2HnD error @3:41-3:67: invalid binary operator <INVALID_OP>

So I think that the minus symbol in RouterOS RBD53GR-5HacD2HnD is (again) the problem.

Regards

@Tiki10 remove the string interpolation around Model:

- |> filter(fn: (r) => if "${string(v: ${Model})}" == "RouterOS RBD53GR-5HacD2HnD" then
+ |> filter(fn: (r) => if "${string(v: Model)}" == "RouterOS RBD53GR-5HacD2HnD" then

Hello Scott,

Sorry for the long time to reply.
I’ve tried without interpolation like that

from(bucket: "telegraf/autogen")
   |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
   |> filter(fn: (r) => if "${string(v: Model)}" == "RouterOS RBD53GR-5HacD2HnD" then
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r["if-name"] == "lte1" and r._field == "bytesIn"
                     else
                     r._measurement == "snmp_interfaces" and r.hostname == "${hostname}" and r["if-name"] == "ether1" and r._field == "bytesIn"
                    )
   |> map(fn: (r) => ({r with _value: r._value * 8}))
   |> derivative(unit: 1s, nonNegative: false)

The error is now : Undefined idnetifier Model

Regards

Hello,

I reimagined the way to have a dynamic interface then I change the Interface’s variable query instead of trying the add it in each dashboard query in Grafana, and, it works !
I’ve used your first reply like that:

from(bucket: "telegraf/autogen")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "snmp_interfaces")
  |> filter(fn: (r) => r["hostname"] == "${hostname}")
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> group()
  |> distinct(column: "if-name")
  |> filter(  
      fn: (r) => if "${Model}" == "RouterOS RBD53GR-5HacD2HnD" then
          r._value == "lte1"
      else
          r._value == "ether1",
    )

I don’t know why it’s working in Variables setting and not in Dashboard Queries.

Regards,

Vincent