Using fritzinfluxdb with InfluxDBv2

Hey there.
I just found this cool project and wanted to use it, but it seems, that it is not available for user who use influxDB in Version 2.
Is there any possibility to use this project with version 2, or will this be available in a next release?

Hi, good point. Haven't tested influxdb 2. Will give it a go in the next few days and see what the issue is.
Do you have any output from the tool about the complaint?

Hey @bb-Ricardo thanks for your reply.
I have to say, that I didn't try to get it working, because for influxDBv2 you don't use username and password anymore, but a token and a bucket.

Ahhh I see. I have to admit I didn't look into influxdb since version 2 was released but can't be that difficult to solve. Maybe a small project for tonight.

Bookmark: https://docs.influxdata.com/influxdb/v2.0/write-data/developer-tools/api/

Hi,
can you test the branch "add-influx2.0-support"? I was able to see the measurements in the Influx GUI.

Hey @bb-Ricardo,
it seems to be working. I get data to my InfluxDB instance.
The only thing that isn't working is the dashboard template. I tried to get it working, but that isn't as simple as I thought ^^

That's true. I hoped it would work as it seemed that there was a compatible layer to query data "the old way". Maybe the data needs to written differently to match the queries.
I will have a look.

Just spun up some containers and it seems like that we have to rewrite all queries for InfluxDB2 to Flux query language.
Sorry. This might take some time as I don't know any about the language.

can you try out this basic dashboard with one panel

The test dashboard json

{
  "__inputs": [
    {
      "name": "DS_INFLUXDB2",
      "label": "InfluxDB2",
      "description": "",
      "type": "datasource",
      "pluginId": "influxdb",
      "pluginName": "InfluxDB"
    }
  ],
  "__requires": [
    {
      "type": "grafana",
      "id": "grafana",
      "name": "Grafana",
      "version": "7.4.1"
    },
    {
      "type": "panel",
      "id": "graph",
      "name": "Graph",
      "version": ""
    },
    {
      "type": "datasource",
      "id": "influxdb",
      "name": "InfluxDB",
      "version": "1.0.0"
    }
  ],
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "gnetId": null,
  "graphTooltip": 0,
  "id": null,
  "links": [],
  "panels": [
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": "${DS_INFLUXDB2}",
      "fieldConfig": {
        "defaults": {
          "custom": {},
          "links": []
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 13,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "hiddenSeries": false,
      "id": 2,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "links": [],
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.4.1",
      "pointradius": 5,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [
        {
          "alias": "/UP.*/",
          "transform": "negative-Y"
        },
        {
          "alias": "/.*Physical Max/",
          "color": "#64b0c8",
          "fill": 0
        },
        {
          "alias": "/.*DSL Sync/",
          "color": "#3f6833",
          "fill": 0
        },
        {
          "alias": "/.*netto Max/",
          "color": "#890f02",
          "fill": 0
        },
        {
          "alias": "/.*rror.*/",
          "bars": true,
          "yaxis": 2
        }
      ],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "alias": "UP",
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "linear"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "fritzbox",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"sendrate\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value *8,\n      _field: \"UP\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "refId": "A",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "sendrate"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              },
              {
                "params": [
                  "*8"
                ],
                "type": "math"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "DOWN",
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "linear"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "fritzbox",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"receiverate\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value *8,\n      _field: \"DOWN\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "refId": "B",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "receiverate"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              },
              {
                "params": [
                  "*8"
                ],
                "type": "math"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "DOWN netto Max",
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "linear"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "fritzbox",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"downstreammax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"DOWN netto Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "refId": "C",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "downstreammax"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "last"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "DOWN Physical Max",
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "linear"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "fritzbox",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"downstreamphysicalmax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"DOWN Physical Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "refId": "D",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "downstreamphysicalmax"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "last"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "DOWN DSL Sync",
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "linear"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "fritzbox",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"downstream_dsl_sync_max\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value * 1000,\n      _field: \"DOWN DSL Sync\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "rawQuery": false,
          "refId": "E",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "downstream_dsl_sync_max"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              },
              {
                "params": [
                  "*1000"
                ],
                "type": "math"
              }
            ]
          ],
          "tags": []
        },
        {
          "alias": "UP netto Max",
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "linear"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "measurement": "fritzbox",
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"upstreammax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"UP netto Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "rawQuery": false,
          "refId": "F",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "upstreammax"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"upstreamphysicalmax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"UP Physical Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "refId": "G",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"upstream_dsl_sync_max\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value * 1000,\n      _field: \"UP DSL Sync\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
          "refId": "H",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"crc_errors\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"CRC Errors\"\n    })\n  )\n  |> derivative(unit: v.windowPeriod, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")",
          "refId": "I",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"errored_seconds\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"Errored Seconds\"\n    })\n  )\n  |> derivative(unit: v.windowPeriod, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")",
          "refId": "J",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        },
        {
          "groupBy": [
            {
              "params": [
                "$__interval"
              ],
              "type": "time"
            },
            {
              "params": [
                "null"
              ],
              "type": "fill"
            }
          ],
          "hide": false,
          "orderByTime": "ASC",
          "policy": "default",
          "query": "from(bucket: \"fritzflux\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r._measurement == \"fritzbox\" and\n    r._field == \"severely_errored_seconds\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"Severely Errored Seconds\"\n    })\n  )\n  |> derivative(unit: v.windowPeriod, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")",
          "refId": "K",
          "resultFormat": "time_series",
          "select": [
            [
              {
                "params": [
                  "value"
                ],
                "type": "field"
              },
              {
                "params": [],
                "type": "mean"
              }
            ]
          ],
          "tags": []
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "Current UP/DOWN",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "decimals": null,
          "format": "bps",
          "label": "DSL Speed",
          "logBase": 1,
          "max": "142000000",
          "min": "-40000000",
          "show": true
        },
        {
          "decimals": 0,
          "format": "short",
          "label": "Errors",
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    }
  ],
  "schemaVersion": 27,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-6h",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "",
  "title": "New dashboard Copy",
  "uid": "8tNTrYEMk",
  "version": 6
}

Is it okay, if I test it tomorrow? I'm not on the corresponding system anymore for today. :-)

Yes, of course. No problem

Looking good :)

Great. Let's see when I got time to modify all the other panels.
You might want to adjust the max Y axis value to 80000000.

can you try out this new version? It should be close to the InfluxDB 1 Dashboard

The test dashboard json

{
    "__inputs": [
      {
        "name": "DS_INFLUXDB2",
        "label": "InfluxDB2",
        "description": "",
        "type": "datasource",
        "pluginId": "influxdb",
        "pluginName": "InfluxDB"
      },
      {
        "name": "VAR_MEASUREMENT",
        "type": "constant",
        "label": "InfluxDB measurement",
        "value": "fritzbox",
        "description": ""
      },
      {
        "name": "VAR_BUCKET",
        "type": "constant",
        "label": "InfluxDB bucket",
        "value": "fritzflux",
        "description": ""
      },
      {
        "name": "VAR_DOWN_MAX",
        "type": "constant",
        "label": "Max Down Speed (Mbit)",
        "value": "100",
        "description": ""
      },
      {
        "name": "VAR_UP_MAX",
        "type": "constant",
        "label": "Max Up Speed (Mbit)",
        "value": "40",
        "description": ""
      },
      {
        "name": "VAR_DATA_INTERVAL",
        "type": "constant",
        "label": "Data retrieval Interval",
        "value": "10",
        "description": ""
      }
    ],
    "__requires": [
      {
        "type": "panel",
        "id": "gauge",
        "name": "Gauge",
        "version": ""
      },
      {
        "type": "grafana",
        "id": "grafana",
        "name": "Grafana",
        "version": "7.4.1"
      },
      {
        "type": "panel",
        "id": "graph",
        "name": "Graph",
        "version": ""
      },
      {
        "type": "datasource",
        "id": "influxdb",
        "name": "InfluxDB",
        "version": "1.0.0"
      },
      {
        "type": "panel",
        "id": "singlestat",
        "name": "Singlestat",
        "version": ""
      },
      {
        "type": "panel",
        "id": "stat",
        "name": "Stat",
        "version": ""
      },
      {
        "type": "panel",
        "id": "table",
        "name": "Table",
        "version": ""
      }
    ],
    "editable": true,
    "gnetId": null,
    "graphTooltip": 0,
    "id": null,
    "iteration":<PHONE_NUMBER>909,
    "links": [],
    "panels": [
      {
        "aliasColors": {},
        "bars": false,
        "dashLength": 10,
        "dashes": false,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "custom": {},
            "links": []
          },
          "overrides": []
        },
        "fill": 1,
        "fillGradient": 0,
        "gridPos": {
          "h": 13,
          "w": 24,
          "x": 0,
          "y": 0
        },
        "hiddenSeries": false,
        "id": 2,
        "legend": {
          "avg": false,
          "current": false,
          "max": false,
          "min": false,
          "show": true,
          "total": false,
          "values": false
        },
        "lines": true,
        "linewidth": 1,
        "links": [],
        "nullPointMode": "null",
        "options": {
          "alertThreshold": true
        },
        "percentage": false,
        "pluginVersion": "7.4.1",
        "pointradius": 5,
        "points": false,
        "renderer": "flot",
        "seriesOverrides": [
          {
            "alias": "/UP.*/",
            "transform": "negative-Y"
          },
          {
            "alias": "/.*Physical Max/",
            "color": "#64b0c8",
            "fill": 0
          },
          {
            "alias": "/.*DSL Sync/",
            "color": "#3f6833",
            "fill": 0
          },
          {
            "alias": "/.*netto Max/",
            "color": "#890f02",
            "fill": 0
          },
          {
            "alias": "/.*rror.*/",
            "bars": true,
            "yaxis": 2
          }
        ],
        "spaceLength": 10,
        "stack": false,
        "steppedLine": false,
        "targets": [
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"sendrate\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value *8,\n      _field: \"UP\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "refId": "A",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"receiverate\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value *8,\n      _field: \"DOWN\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "refId": "B",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"downstreammax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"DOWN netto Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "refId": "C",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"downstreamphysicalmax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"DOWN Physical Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "refId": "D",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"downstream_dsl_sync_max\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value * 1000,\n      _field: \"DOWN DSL Sync\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "rawQuery": false,
            "refId": "E",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"upstreammax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"UP netto Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "rawQuery": false,
            "refId": "F",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"upstreamphysicalmax\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"UP Physical Max\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "refId": "G",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"upstream_dsl_sync_max\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value * 1000,\n      _field: \"UP DSL Sync\"\n    })\n  )\n  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |> yield(name: \"mean\")",
            "refId": "H",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"crc_errors\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"CRC Errors\"\n    })\n  )\n  |> derivative(unit: v.windowPeriod, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")",
            "refId": "I",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"errored_seconds\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"Errored Seconds\"\n    })\n  )\n  |> derivative(unit: v.windowPeriod, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")",
            "refId": "J",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) =>\n    r[\"_measurement\"] == \"${measurement}\" and\n    r._field == \"severely_errored_seconds\"\n  )\n  |> map(fn: (r) => ({\n      r with\n      _field: \"Severely Errored Seconds\"\n    })\n  )\n  |> derivative(unit: v.windowPeriod, nonNegative: true, columns: [\"_value\"], timeColumn: \"_time\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")",
            "refId": "K",
            "resultFormat": "time_series"
          }
        ],
        "thresholds": [],
        "timeFrom": null,
        "timeRegions": [],
        "timeShift": null,
        "title": "Current UP/DOWN",
        "tooltip": {
          "shared": true,
          "sort": 0,
          "value_type": "individual"
        },
        "type": "graph",
        "xaxis": {
          "buckets": null,
          "mode": "time",
          "name": null,
          "show": true,
          "values": []
        },
        "yaxes": [
          {
            "decimals": null,
            "format": "bps",
            "label": "DSL Speed",
            "logBase": 1,
            "max": null,
            "min": null,
            "show": true
          },
          {
            "decimals": 0,
            "format": "short",
            "label": "Errors",
            "logBase": 1,
            "max": null,
            "min": null,
            "show": true
          }
        ],
        "yaxis": {
          "align": false,
          "alignLevel": null
        }
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {},
            "mappings": [
              {
                "id": 0,
                "op": "=",
                "text": "N/A",
                "type": 1,
                "value": "null"
              },
              {
                "id": 1,
                "op": "=",
                "text": "No",
                "type": 1,
                "value": "0"
              },
              {
                "id": 2,
                "op": "=",
                "text": "Yes",
                "type": 1,
                "value": "1"
              }
            ],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "#6ed0e0",
                  "value": null
                },
                {
                  "color": "dark-blue",
                  "value": 0
                },
                {
                  "color": "#508642",
                  "value": 1
                }
              ]
            },
            "unit": "none"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 4,
          "w": 2,
          "x": 0,
          "y": 13
        },
        "id": 4,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "colorMode": "value",
          "graphMode": "none",
          "justifyMode": "auto",
          "orientation": "horizontal",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "",
            "values": false
          },
          "text": {},
          "textMode": "auto"
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"upgrade_available\")\n  |> last()",
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "title": "Update Available",
        "type": "stat"
      },
      {
        "cacheTimeout": null,
        "colorBackground": false,
        "colorValue": false,
        "colors": [
          "rgba(245, 54, 54, 0.9)",
          "rgba(237, 129, 40, 0.89)",
          "#1f78c1"
        ],
        "datasource": "${DS_INFLUXDB2}",
        "decimals": 2,
        "fieldConfig": {
          "defaults": {
            "custom": {}
          },
          "overrides": []
        },
        "format": "dtdurations",
        "gauge": {
          "maxValue": 100,
          "minValue": 0,
          "show": false,
          "thresholdLabels": false,
          "thresholdMarkers": true
        },
        "gridPos": {
          "h": 2,
          "w": 6,
          "x": 2,
          "y": 13
        },
        "hideTimeOverride": true,
        "id": 6,
        "interval": null,
        "links": [],
        "mappingType": 1,
        "mappingTypes": [
          {
            "name": "value to text",
            "value": 1
          },
          {
            "name": "range to text",
            "value": 2
          }
        ],
        "maxDataPoints": 100,
        "nullPointMode": "connected",
        "nullText": null,
        "postfix": "",
        "postfixFontSize": "50%",
        "prefix": "",
        "prefixFontSize": "50%",
        "rangeMaps": [
          {
            "from": "null",
            "text": "N/A",
            "to": "null"
          }
        ],
        "sparkline": {
          "fillColor": "rgba(31, 118, 189, 0.18)",
          "full": false,
          "lineColor": "rgb(31, 120, 193)",
          "show": false
        },
        "tableColumn": "",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"linkuptime\")\n  |> last()\n",
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "thresholds": "1,1",
        "timeFrom": "5m",
        "timeShift": null,
        "title": "DSL Link Uptime",
        "type": "singlestat",
        "valueFontSize": "50%",
        "valueMaps": [
          {
            "op": "=",
            "text": "N/A",
            "value": "null"
          },
          {
            "op": "=",
            "text": "Disconnected",
            "value": "0"
          }
        ],
        "valueName": "current"
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "continuous-GrYlRd"
            },
            "custom": {},
            "decimals": 1,
            "mappings": [],
            "min": 0,
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "rgba(245, 54, 54, 0.9)",
                  "value": null
                }
              ]
            },
            "unit": "Bps"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 4,
          "w": 3,
          "x": 8,
          "y": 13
        },
        "id": 10,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "orientation": "horizontal",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "/^receiverate$/",
            "values": false
          },
          "showThresholdLabels": false,
          "showThresholdMarkers": false,
          "text": {}
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"receiverate\")\n  |> last()\n",
            "refId": "A",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\"  and r._field == \"downstreammax\")\n  |> last()\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value / 8,\n    })\n  )",
            "refId": "B",
            "resultFormat": "time_series"
          }
        ],
        "title": "Current Download",
        "type": "gauge"
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "continuous-YlBl"
            },
            "custom": {},
            "decimals": 1,
            "mappings": [],
            "min": 0,
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "rgba(245, 54, 54, 0.9)",
                  "value": null
                }
              ]
            },
            "unit": "Bps"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 4,
          "w": 3,
          "x": 11,
          "y": 13
        },
        "id": 12,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "orientation": "horizontal",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "/^sendrate$/",
            "values": false
          },
          "showThresholdLabels": false,
          "showThresholdMarkers": false,
          "text": {}
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"sendrate\")\n  |> last()\n",
            "refId": "A",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\"  and r._field == \"upstreammax\")\n  |> last()\n  |> map(fn: (r) => ({\n      r with\n      _value: r._value / 8,\n    })\n  )",
            "refId": "B",
            "resultFormat": "time_series"
          }
        ],
        "title": "Current Upload",
        "type": "gauge"
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {},
            "decimals": 3,
            "mappings": [],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "red",
                  "value": null
                }
              ]
            },
            "unit": "decbytes"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 4,
          "w": 5,
          "x": 14,
          "y": 13
        },
        "hideTimeOverride": true,
        "id": 14,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "colorMode": "value",
          "graphMode": "area",
          "justifyMode": "auto",
          "orientation": "horizontal",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "",
            "values": false
          },
          "text": {},
          "textMode": "auto"
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytessent\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n",
            "rawQuery": true,
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "timeFrom": "24h",
        "timeShift": null,
        "title": "Total Upload since connection",
        "description": "Don't trust this values, FritzBox seems to have an issue to reset 'totalbytessent' to 0 on reconnect",
        "type": "stat"
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {},
            "mappings": [],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "semi-dark-blue",
                  "value": null
                }
              ]
            },
            "unit": "decbytes"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 4,
          "w": 5,
          "x": 19,
          "y": 13
        },
        "hideTimeOverride": true,
        "id": 16,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "colorMode": "value",
          "graphMode": "area",
          "justifyMode": "auto",
          "orientation": "horizontal",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "",
            "values": false
          },
          "text": {},
          "textMode": "auto"
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytesreceived\")\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n",
            "rawQuery": true,
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "timeFrom": "24h",
        "title": "Total Download since connection",
        "description": "Don't trust this values, FritzBox seems to have an issue to reset 'totalbytesreceived' to 0 on reconnect",
        "type": "stat"
      },
      {
        "cacheTimeout": null,
        "colorBackground": false,
        "colorValue": false,
        "colors": [
          "rgba(245, 54, 54, 0.9)",
          "rgba(237, 129, 40, 0.89)",
          "rgba(50, 172, 45, 0.97)"
        ],
        "datasource": "${DS_INFLUXDB2}",
        "decimals": 2,
        "fieldConfig": {
          "defaults": {
            "custom": {}
          },
          "overrides": []
        },
        "format": "dtdurations",
        "gauge": {
          "maxValue": 100,
          "minValue": 0,
          "show": false,
          "thresholdLabels": false,
          "thresholdMarkers": true
        },
        "gridPos": {
          "h": 2,
          "w": 6,
          "x": 2,
          "y": 15
        },
        "hideTimeOverride": true,
        "id": 8,
        "interval": null,
        "links": [],
        "mappingType": 1,
        "mappingTypes": [
          {
            "name": "value to text",
            "value": 1
          },
          {
            "name": "range to text",
            "value": 2
          }
        ],
        "maxDataPoints": 100,
        "nullPointMode": "connected",
        "nullText": null,
        "postfix": "",
        "postfixFontSize": "50%",
        "prefix": "",
        "prefixFontSize": "50%",
        "rangeMaps": [
          {
            "from": "null",
            "text": "N/A",
            "to": "null"
          }
        ],
        "sparkline": {
          "fillColor": "rgba(31, 118, 189, 0.18)",
          "full": false,
          "lineColor": "rgb(31, 120, 193)",
          "show": false
        },
        "tableColumn": "",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"systemuptime\")\n  |> last()\n",
            "rawQuery": false,
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "thresholds": "1,1",
        "timeFrom": "5m",
        "title": "System Uptime",
        "type": "singlestat",
        "valueFontSize": "50%",
        "valueMaps": [
          {
            "op": "=",
            "text": "N/A",
            "value": "null"
          }
        ],
        "valueName": "current"
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {},
            "decimals": 3,
            "mappings": [],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "semi-dark-red",
                  "value": null
                }
              ]
            },
            "unit": "decbytes"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 3,
          "w": 6,
          "x": 0,
          "y": 17
        },
        "id": 18,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "colorMode": "value",
          "graphMode": "area",
          "justifyMode": "auto",
          "orientation": "horizontal",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "",
            "values": false
          },
          "text": {},
          "textMode": "auto"
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytessent\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < ${up_max} * ${data_interval} * 2 * 100000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n ",
            "rawQuery": true,
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "timeFrom": "24h",
        "timeShift": null,
        "title": "Last 24h Upload",
        "type": "stat"
      },
      {
        "cacheTimeout": null,
        "datasource": "${DS_INFLUXDB2}",
        "description": "",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {},
            "mappings": [],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "semi-dark-blue",
                  "value": null
                }
              ]
            },
            "unit": "decbytes"
          },
          "overrides": []
        },
        "gridPos": {
          "h": 3,
          "w": 6,
          "x": 6,
          "y": 17
        },
        "hideTimeOverride": false,
        "id": 20,
        "interval": null,
        "links": [],
        "maxDataPoints": 100,
        "options": {
          "colorMode": "value",
          "graphMode": "area",
          "justifyMode": "auto",
          "orientation": "auto",
          "reduceOptions": {
            "calcs": [
              "lastNotNull"
            ],
            "fields": "",
            "values": false
          },
          "text": {},
          "textMode": "auto"
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "dsType": "influxdb",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytesreceived\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < ${down_max} * ${data_interval} * 2 * 100000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> yield(name: \"last\")\n",
            "rawQuery": true,
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "timeFrom": "24h",
        "timeShift": null,
        "title": "Last 24h Download",
        "type": "stat"
      },
      {
        "aliasColors": {
          "Download": "semi-dark-blue",
          "Upload": "#e24d42",
          "download": "#1F78C1",
          "upload": "#EA6460"
        },
        "annotate": {
          "enable": false
        },
        "bars": true,
        "dashLength": 10,
        "dashes": false,
        "datasource": "${DS_INFLUXDB2}",
        "decimals": null,
        "editable": true,
        "fieldConfig": {
          "defaults": {
            "custom": {},
            "links": []
          },
          "overrides": []
        },
        "fill": 0,
        "fillGradient": 0,
        "grid": {},
        "gridPos": {
          "h": 8,
          "w": 12,
          "x": 12,
          "y": 17
        },
        "hiddenSeries": false,
        "id": 22,
        "interval": "1h",
        "legend": {
          "avg": false,
          "current": true,
          "max": false,
          "min": false,
          "show": true,
          "total": true,
          "values": true
        },
        "lines": false,
        "linewidth": 1,
        "links": [],
        "nullPointMode": "null",
        "options": {
          "alertThreshold": false
        },
        "percentage": false,
        "pluginVersion": "7.4.1",
        "pointradius": 5,
        "points": false,
        "renderer": "flot",
        "resolution": 100,
        "scale": 1,
        "seriesOverrides": [],
        "spaceLength": 10,
        "stack": false,
        "steppedLine": true,
        "targets": [
          {
            "dsType": "influxdb",
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytesreceived\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < ${down_max} * ${data_interval} * 2 * 100000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> map(fn: (r) => ({ r with _field: \"Download\" }))\n  |> yield(name: \"last\")\n\n",
            "rawQuery": true,
            "refId": "A",
            "resultFormat": "time_series"
          },
          {
            "dsType": "influxdb",
            "fill": "null",
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytessent\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < ${up_max} * ${data_interval} * 2 * 100000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> map(fn: (r) => ({ r with _field: \"Upload\" }))\n  |> yield(name: \"last\")\n\n",
            "rawQuery": true,
            "refId": "B",
            "resultFormat": "time_series"
          }
        ],
        "thresholds": [],
        "timeFrom": "24h",
        "timeRegions": [],
        "timeShift": null,
        "title": "Current Traffic",
        "tooltip": {
          "msResolution": false,
          "query_as_alias": true,
          "shared": true,
          "sort": 0,
          "value_type": "cumulative"
        },
        "type": "graph",
        "xaxis": {
          "buckets": null,
          "mode": "time",
          "name": null,
          "show": true,
          "values": []
        },
        "yaxes": [
          {
            "decimals": null,
            "format": "decbytes",
            "label": "",
            "logBase": 1,
            "max": null,
            "min": 0,
            "show": true
          },
          {
            "format": "short",
            "logBase": 1,
            "max": null,
            "min": null,
            "show": false
          }
        ],
        "yaxis": {
          "align": false,
          "alignLevel": null
        },
        "zerofill": true
      },
      {
        "aliasColors": {
          "Download": "#1f78c1",
          "Upload": "#e24d42",
          "fritzbox_value.non_negative_derivative": "#ba43a9",
          "fritzbox_value.non_negative_difference": "#e24d42"
        },
        "bars": true,
        "dashLength": 10,
        "dashes": false,
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "custom": {},
            "links": []
          },
          "overrides": []
        },
        "fill": 1,
        "fillGradient": 0,
        "gridPos": {
          "h": 7,
          "w": 12,
          "x": 0,
          "y": 20
        },
        "hiddenSeries": false,
        "id": 24,
        "interval": "24h",
        "legend": {
          "alignAsTable": false,
          "avg": false,
          "current": true,
          "hideEmpty": false,
          "hideZero": false,
          "max": false,
          "min": false,
          "rightSide": false,
          "show": true,
          "total": false,
          "values": true
        },
        "lines": false,
        "linewidth": 1,
        "links": [],
        "maxDataPoints": null,
        "nullPointMode": "null",
        "options": {
          "alertThreshold": true
        },
        "percentage": false,
        "pluginVersion": "7.4.1",
        "pointradius": 5,
        "points": false,
        "renderer": "flot",
        "seriesOverrides": [],
        "spaceLength": 10,
        "stack": false,
        "steppedLine": false,
        "targets": [
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytesreceived\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < ${down_max} * ${data_interval} * 2 * 100000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> map(fn: (r) => ({ r with _field: \"Download\" }))\n  |> yield(name: \"last\")",
            "refId": "A",
            "resultFormat": "time_series"
          },
          {
            "hide": false,
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytessent\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < ${up_max} * ${data_interval} * 2 * 100000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> map(fn: (r) => ({ r with _field: \"Upload\" }))",
            "refId": "B",
            "resultFormat": "time_series"
          }
        ],
        "thresholds": [],
        "timeFrom": "7d",
        "timeRegions": [],
        "timeShift": null,
        "title": "Daily Traffic",
        "tooltip": {
          "shared": true,
          "sort": 0,
          "value_type": "individual"
        },
        "type": "graph",
        "xaxis": {
          "buckets": null,
          "mode": "time",
          "name": null,
          "show": true,
          "values": []
        },
        "yaxes": [
          {
            "decimals": null,
            "format": "decbytes",
            "label": "",
            "logBase": 1,
            "max": null,
            "min": null,
            "show": true
          },
          {
            "format": "decbytes",
            "label": null,
            "logBase": 1,
            "max": null,
            "min": null,
            "show": false
          }
        ],
        "yaxis": {
          "align": false,
          "alignLevel": null
        }
      },
      {
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {
              "align": null,
              "filterable": false
            },
            "mappings": [],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "green",
                  "value": null
                }
              ]
            }
          },
          "overrides": [
            {
              "matcher": {
                "id": "byName",
                "options": "Metric"
              },
              "properties": [
                {
                  "id": "displayName",
                  "value": "Name"
                },
                {
                  "id": "mappings",
                  "value": [
                    {
                      "from": "",
                      "id": 1,
                      "text": "Link Status",
                      "to": "",
                      "type": 1,
                      "value": "connection_status"
                    },
                    {
                      "from": "",
                      "id": 2,
                      "text": "External IPv4",
                      "to": "",
                      "type": 1,
                      "value": "external_ip"
                    },
                    {
                      "from": "",
                      "id": 3,
                      "text": "External IPv6",
                      "to": "",
                      "type": 1,
                      "value": "external_ipv6"
                    },
                    {
                      "from": "",
                      "id": 4,
                      "text": "Last Connect Error",
                      "to": "",
                      "type": 1,
                      "value": "last_connection_error"
                    },
                    {
                      "from": "",
                      "id": 5,
                      "text": "Model",
                      "to": "",
                      "type": 1,
                      "value": "model"
                    },
                    {
                      "from": "",
                      "id": 6,
                      "text": "Number of Hosts",
                      "to": "",
                      "type": 1,
                      "value": "number_of_hosts"
                    },
                    {
                      "from": "",
                      "id": 7,
                      "text": "Link Status",
                      "to": "",
                      "type": 1,
                      "value": "physicallinkstatus"
                    },
                    {
                      "from": "",
                      "id": 8,
                      "text": "Link Type",
                      "to": "",
                      "type": 1,
                      "value": "physicallinktype"
                    },
                    {
                      "from": "",
                      "id": 9,
                      "text": "Remote POP",
                      "to": "",
                      "type": 1,
                      "value": "remote_pop"
                    },
                    {
                      "from": "",
                      "id": 10,
                      "text": "Serial",
                      "to": "",
                      "type": 1,
                      "value": "serialnumber"
                    },
                    {
                      "from": "",
                      "id": 11,
                      "text": "SW Version",
                      "to": "",
                      "type": 1,
                      "value": "softwareversion"
                    }
                  ]
                }
              ]
            }
          ]
        },
        "gridPos": {
          "h": 10,
          "w": 12,
          "x": 12,
          "y": 25
        },
        "hideTimeOverride": true,
        "id": 29,
        "interval": "",
        "links": [],
        "options": {
          "frameIndex": 1,
          "showHeader": true
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "groupBy": [],
            "hide": false,
            "limit": "1",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and (\n    r[\"_field\"] == \"connection_status\" or \n    r[\"_field\"] == \"physicallinkstatus\" or \n    r[\"_field\"] == \"physicallinktype\" or \n    r[\"_field\"] == \"last_connection_error\" or \n    r[\"_field\"] == \"external_ip\" or \n    r[\"_field\"] == \"external_ipv6\" or \n    r[\"_field\"] == \"remote_pop\" or \n    r[\"_field\"] == \"model\" or \n    r[\"_field\"] == \"serialnumber\" or \n    r[\"_field\"] == \"softwareversion\" or \n    r[\"_field\"] == \"number_of_hosts\"))\n  |> last()\n  |> keep(columns: [\"_time\",\"_field\", \"_value\"])\n\n",
            "rawQuery": false,
            "refId": "A",
            "resultFormat": "time_series"
          }
        ],
        "timeFrom": "1m",
        "timeShift": null,
        "title": "FritzBox Info",
        "transformations": [
          {
            "id": "seriesToRows",
            "options": {
              "reducers": []
            }
          }
        ],
        "type": "table"
      },
      {
        "datasource": "${DS_INFLUXDB2}",
        "fieldConfig": {
          "defaults": {
            "color": {
              "mode": "thresholds"
            },
            "custom": {
              "align": null,
              "filterable": false
            },
            "decimals": 2,
            "displayName": "",
            "mappings": [],
            "thresholds": {
              "mode": "absolute",
              "steps": [
                {
                  "color": "green",
                  "value": null
                }
              ]
            },
            "unit": "decbytes"
          },
          "overrides": [
            {
              "matcher": {
                "id": "byName",
                "options": "Time"
              },
              "properties": [
                {
                  "id": "displayName",
                  "value": "Time"
                },
                {
                  "id": "unit",
                  "value": "time: MMMM D, YYYY LT"
                },
                {
                  "id": "custom.align",
                  "value": null
                }
              ]
            },
            {
              "matcher": {
                "id": "byName",
                "options": "Upload fritzbox"
              },
              "properties": [
                {
                  "id": "displayName",
                  "value": "Upload"
                }
              ]
            },
            {
              "matcher": {
                "id": "byName",
                "options": "Download fritzbox"
              },
              "properties": [
                {
                  "id": "displayName",
                  "value": "Download"
                }
              ]
            }
          ]
        },
        "gridPos": {
          "h": 8,
          "w": 12,
          "x": 0,
          "y": 27
        },
        "id": 27,
        "interval": "24h",
        "links": [],
        "options": {
          "frameIndex": 1,
          "showHeader": true
        },
        "pluginVersion": "7.4.1",
        "targets": [
          {
            "alias": "Download",
            "dsType": "influxdb",
            "measurement": "fritzbox_value",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytessent\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < 45000000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> map(fn: (r) => ({ r with _field: \"Upload\" }))\n  |> yield(name: \"last\")",
            "rawQuery": true,
            "refId": "A",
            "resultFormat": "time_series"
          },
          {
            "alias": "Upload",
            "dsType": "influxdb",
            "measurement": "fritzbox_value",
            "orderByTime": "ASC",
            "policy": "default",
            "query": "from(bucket: \"${bucket}\")\n  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |> filter(fn: (r) => r[\"_measurement\"] == \"${measurement}\" and r[\"_field\"] == \"totalbytesreceived\")\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> fill(column: \"_value\", usePrevious: true)\n  |> filter(fn: (r) => r._value < 150000000)\n  |> cumulativeSum(columns: [\"_value\"])\n  |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n  |> difference(nonNegative: true, columns: [\"_value\"])\n  |> map(fn: (r) => ({ r with _field: \"Download\" }))\n  |> yield(name: \"last\")",
            "rawQuery": true,
            "refId": "B",
            "resultFormat": "time_series"
          }
        ],
        "timeFrom": "7d",
        "timeShift": null,
        "title": "Daily Traffic",
        "transformations": [
          {
            "id": "seriesToColumns",
            "options": {}
          }
        ],
        "type": "table"
      }
    ],
    "refresh": "10s",
    "schemaVersion": 27,
    "style": "dark",
    "tags": [],
    "templating": {
      "list": [
        {
          "description": "Measurement name for the fritzflux data",
          "error": null,
          "hide": 2,
          "label": "InfluxDB measurement",
          "name": "measurement",
          "query": "${VAR_MEASUREMENT}",
          "skipUrlSync": false,
          "type": "constant",
          "current": {
            "value": "${VAR_MEASUREMENT}",
            "text": "${VAR_MEASUREMENT}",
            "selected": false
          },
          "options": [
            {
              "value": "${VAR_MEASUREMENT}",
              "text": "${VAR_MEASUREMENT}",
              "selected": false
            }
          ]
        },
        {
          "description": "Bucket name for the fritzflux data",
          "error": null,
          "hide": 2,
          "label": "InfluxDB bucket",
          "name": "bucket",
          "query": "${VAR_BUCKET}",
          "skipUrlSync": false,
          "type": "constant",
          "current": {
            "value": "${VAR_BUCKET}",
            "text": "${VAR_BUCKET}",
            "selected": false
          },
          "options": [
            {
              "value": "${VAR_BUCKET}",
              "text": "${VAR_BUCKET}",
              "selected": false
            }
          ]
        },
        {
          "description": "This is used to filter out wrong values",
          "error": null,
          "hide": 2,
          "label": "Max Down Speed (Mbit)",
          "name": "down_max",
          "query": "${VAR_DOWN_MAX}",
          "skipUrlSync": false,
          "type": "constant",
          "current": {
            "value": "${VAR_DOWN_MAX}",
            "text": "${VAR_DOWN_MAX}",
            "selected": false
          },
          "options": [
            {
              "value": "${VAR_DOWN_MAX}",
              "text": "${VAR_DOWN_MAX}",
              "selected": false
            }
          ]
        },
        {
          "description": "This is used to filter out wrong values",
          "error": null,
          "hide": 2,
          "label": "Max Up Speed (Mbit)",
          "name": "up_max",
          "query": "${VAR_UP_MAX}",
          "skipUrlSync": false,
          "type": "constant",
          "current": {
            "value": "${VAR_UP_MAX}",
            "text": "${VAR_UP_MAX}",
            "selected": false
          },
          "options": [
            {
              "value": "${VAR_UP_MAX}",
              "text": "${VAR_UP_MAX}",
              "selected": false
            }
          ]
        },
        {
          "description": "Interval of FritzBox data written to InfluxDB",
          "error": null,
          "hide": 2,
          "label": "Data retrieval Interval",
          "name": "data_interval",
          "query": "${VAR_DATA_INTERVAL}",
          "skipUrlSync": false,
          "type": "constant",
          "current": {
            "value": "${VAR_DATA_INTERVAL}",
            "text": "${VAR_DATA_INTERVAL}",
            "selected": false
          },
          "options": [
            {
              "value": "${VAR_DATA_INTERVAL}",
              "text": "${VAR_DATA_INTERVAL}",
              "selected": false
            }
          ]
        }
      ]
    },
    "time": {
      "from": "now-24h",
      "to": "now"
    },
    "timepicker": {},
    "timezone": "browser",
    "title": "FRITZ!Box Router Status",
    "uid": "FritzFlux",
    "version": 1
  }

This looks really good!
The only thing I see is that the daily traffic only shows today and no other day:

The rest looks good.
And if I didn't said it before: Awesome work! I would never have gotten the dashboard running like that in that small time. Not to mention the influxDBv2 integration!

since when are you collecting data? It will grow over time. I didn't get the query to report past "half" days.

I'm collecting since 15.02.

mmhh. I will have a look.

I'm collecting since 15.02.

I tried but failed to display the data properly.
https://github.com/influxdata/flux/issues/2203
This issue describes it quite right and I was unsuccessful to get the daily data right.

Hello,
is the version with InfluxDB 2.0/2.1 support "production ready" or is this still under heavy development. And does this work with influxdb_client 1.26 or do I really need the version 1.14?
Thanks
Manuel

Hi, haven't looked into it since really. I guess I should try again.
The issue was that the values are off for the daily usage

Hey guys,
just want to let u know that u can enable influxql on influxdb2: https://docs.influxdata.com/influxdb/v2.1/query-data/influxql/
So, it would be pretty cool if fritzinfluxdb could support influxdb2, for people like me who are using it for other things too, then the grafana dashboard wouldn't change if ur enabling influxql. Just change/create the datasource adding a custom header with Authorization : Token {API_TOKEN} and there u go: https://docs.influxdata.com/influxdb/v2.1/query-data/execute-queries/influx-api/
love the project! ❤

Hey,
Thank you for this input.
This looks great. There is already a branch with influx2 support. Maybe you can check this out and give it a go.
This would also maintaining the dashboard a lot easier.
Hope I find some time to test and integrate it the next few days. Then finally we can support Influxdb 2 fully.

Thank you. Got my test setup running now. Need to wait two days and see if the issue with the daily data (https://github.com/karrot-dev/fritzinfluxdb/issues/18#issuecomment-785106900) is still there.

I checked the data and it looks perfect. I get the same data via InfluxQL from a InfluxDB 2 and a InfluxDB 1.
I updated the dashboard as well. Needs a Grafana 8.4. Can you give it a try? https://github.com/karrot-dev/fritzinfluxdb/blob/add-influx2.0-support/grafana_dashboard_fritzbox.json
Thank you

I checked the data and it looks perfect. I get the same data via InfluxQL from a InfluxDB 2 and a InfluxDB 1.
I updated the dashboard as well. Needs a Grafana 8.4. Can you give it a try? https://github.com/karrot-dev/fritzinfluxdb/blob/add-influx2.0-support/grafana_dashboard_fritzbox.json
Thank you

Hi Ricardo
Whant to give a try. But when I try to clone the influx2.0 branch, I get the message
fatal: Repository... nicht gefunden...
Which URL I have to use...
I tried:
https://github.com/karrot-dev/fritzinfluxdb/tree/add-influx2.0-support
and
https://github.com/karrot-dev/fritzinfluxdb/blob/add-influx2.0-support/
Kind Regards
Ronald

@ronaldn1969 try somethink like this
git clone https://github.com/karrot-dev/fritzinfluxdb/
git checkout add-influx2.0-support

@T0biii
Thanks...
I got the main brach and git checkout add-influx2.0-support
Response:
fatal: Kein Git-Repository (oder irgendeines der Elternverzeichnisse): .git

@ronaldn1969 ah after cloning you need to switch in the new folder "fritzinfluxdb"

@T0biii ups... Okay... Learned something new... 😁

Just a ping. After I checked the InfluxDB 2 integration again I opted for a rewrite.
Would you mind testing this new version and let me know what you think?: https://github.com/karrot-dev/fritzinfluxdb/tree/rewrite-adding-async
Thank you

Hey @bb-Ricardo
just checked out that version and getting an error while starting a docker container with new built image.
Traceback (most recent call last):   File "/app/./fritzinfluxdb.py", line 21, in <module>     from fritzinfluxdb.cli_parser import parse_command_line   File "/app/fritzinfluxdb.py", line 21, in <module>     from fritzinfluxdb.cli_parser import parse_command_line ModuleNotFoundError: No module named 'fritzinfluxdb.cli_parser'; 'fritzinfluxdb' is not a package
I first thought that the old config maybe not compatible, but with edited sample-config it wont work too. I tried using python 3.9 in the dockerfile.
Maybe u have an idea?
Thanks!

Thank you very much for testing and your time. Will fix it tonight and get back to you.
Yes the old config should still be compatible. But the default var name for a few options has changed to be more consistent with the whole config.

Hey @ekoschmi,
I just fixed and tested the  Dockerfile. Could you give it another spin?
Thank you.

Just a ping. After I checked the InfluxDB 2 integration again I opted for a rewrite.
Would you mind testing this new version and let me know what you think?: https://github.com/karrot-dev/fritzinfluxdb/tree/rewrite-adding-async
Thank you

Hi Ricardo
I saw, that the ini-file didn't include the metrics any more. Where I have to set this now, so that I will collect the same data as before?
BR
Ronald

Hi,
What did you query? can We include that in the queries in general? The File moved to here: https://github.com/karrot-dev/fritzinfluxdb/blob/rewrite-adding-async/fritzinfluxdb/classes/fritzbox/services.py

Ahhh... Okay... Not sure, what I added... will check and post the delta list ;o)
So I have to modify this file, if I want to add or remove metrics from the collection? anything what I have to take care?

I like to try all available metrics. The new script does a services discovery on first connection and disables requesting services which have an issue.

Heyho @bb-Ricardo ,
just tried the new version. Docker container now starts without problems. I had to create a new influxdb token with read & write permission to the bucket. Before that, a token with only write permissions was enough.
After starting the container i get an error while writing to the influxdb. For me it looks like u changed the type of the field "totalbytessent" from integer to string, and with already data in the bucket it gets an error:
2022-03-30 16:42:10,123 - ERROR: Failed to write to InfluxDB 'influx': (422)
Reason: Unprocessable Entity
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json; charset=utf-8', 'X-Influxdb-Build': 'OSS', 'X-Influxdb-Version': '2.1.1', 'X-Platform-Error-Code': 'unprocessable entity', 'Date': 'Wed, 30 Mar 2022 16:42:10 GMT', 'Content-Length': '231'})
HTTP response body: {"code":"unprocessable entity","message":"failure writing points to database: partial write: field type conflict: input field \"totalbytessent\" on measurement \"fritzbox\" is type string, already exists as type integer dropped=3"}
@ronaldn1969 double check the token and the permissions it got. also check if the organisation name is correct. i created a new token with read & write permissions and got no error connecting to influxdb... maybe that could help ^^
Greetings

Hi @ekoschmi
you are correct about the token. I will change the behaviour so it won't complain about insufficient read permissions.
And good point about the type mixture. I will add a type casting.
This is a big help, Thank you very much.

@ekoschmi thanks for your advice... I double check bucket, token and organisation name in the ini file. and created a new user with access to all buckets. before I used the initial user, I had to setup at first influxdb start. but also without success. will take closer look on Friday.
Do you used Docker for InfluxDB? I have a second problem. I can't run the container with persistent storage. The way I used with v1.8 is not working anymore and the other tips I found also didn't work... like mapping /root/.influxdbv2

Heyho @bb-Ricardo ,
just tried the new version. Docker container now starts without problems. I had to create a new influxdb token with read & write permission to the bucket. Before that, a token with only write permissions was enough.
After starting the container i get an error while writing to the influxdb. For me it looks like u changed the type of the field "totalbytessent" from integer to string, and with already data in the bucket it gets an error:
2022-03-30 16:42:10,123 - ERROR: Failed to write to InfluxDB 'influx': (422) Reason: Unprocessable Entity HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json; charset=utf-8', 'X-Influxdb-Build': 'OSS', 'X-Influxdb-Version': '2.1.1', 'X-Platform-Error-Code': 'unprocessable entity', 'Date': 'Wed, 30 Mar 2022 16:42:10 GMT', 'Content-Length': '231'}) HTTP response body: {"code":"unprocessable entity","message":"failure writing points to database: partial write: field type conflict: input field \"totalbytessent\" on measurement \"fritzbox\" is type string, already exists as type integer dropped=3"}
@ronaldn1969 double check the token and the permissions it got. also check if the organisation name is correct. i created a new token with read & write permissions and got no error connecting to influxdb... maybe that could help ^^
Greetings

Hey @ekoschmi,
I fixed the issues you had with the previous commit: https://github.com/karrot-dev/fritzinfluxdb/pull/33/commits/fd45f0e53c6bfae6abdfdc031fe41465a39e0e42
can you pull the branch again and test it out?
Thank you.

Hey @bb-Ricardo ,
just tested it and getting following error:
2022-03-31 16:08:45,808 - ERROR: Failed to write to InfluxDB 'influx': (422)
Reason: Unprocessable Entity
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json; charset=utf-8', 'X-Influxdb-Build': 'OSS', 'X-Influxdb-Version': '2.1.1', 'X-Platform-Error-Code': 'unprocessable entity', 'Date': 'Thu, 31 Mar 2022 16:08:45 GMT', 'Content-Length': '235'})
HTTP response body: {"code":"unprocessable entity","message":"failure writing points to database: partial write: field type conflict: input field \"upgrade_available\" on measurement \"fritzbox\" is type boolean, already exists as type integer dropped=4"}
looks like there is another type mixture. ^^
Greets and thanks for ur fast reply!

Hey @ekoschmi,
This seems like a historical baggage which can only be solved by defining types in the config.
Or start with a completely new database. But this would cost the historical data.
"upgrade_available" definitely sounds like a boolen to me but was stored as an int before with the old version.
What do you think?

"upgrade_available" definitely sounds like a boolen to me but was stored as an int before with the old version.
Yes i think so too, sounds definitive like a boolean ^^.
I have no problem to recreate the bucket and losing all historical data. There are maybe users who used the add-influx2.0-support branch and may complain about that while updating to your new rewrite, but that should be not a big problem because its not on master ^^.
So i recreated the bucket, created a new write token for fritzinfluxdb & a new read token for grafana. I also mapped the new bucket with a databasename & retention policy (like i wrote in my first comment above) and now it works without problems so far.
Thanks for your great work! I will let u know if i encounter an error the next days!
Have a nice evening!

I checked... This are my add on
Most of it are error counter. but actually I didn't integrate it into the dash board, so not really a need. But what I will add is
NewDownstreamPower : power_downstream NewUpstreamPower : power_upstream
because its part of the SNR/Attenuation/Power graph.
service = WANDSLLinkConfig1 actions = GetInfo GetStatistics value_instances = NewATMEncapsulation: ATMEncapsulation NewATMPeakCellRate: ATMPeakCellRate NewATMQoS: ATMQoS NewATMSustainableCellRate: ATMSustainableCellRate NewLinkStatus: LinkStatus NewLinkType: LinkType NewAAL5CRCErrors: AAL5CRCErrors NewATMCRCErrors: ATMCRCErrors NewATMReceivedBlocks: ATMReceivedBlocks NewATMTransmittedBlocks: ATMTransmittedBlocks
service = WANDSLInterfaceConfig actions = GetInfo GetStatisticsTotal X_AVM-DE_GetDSLInfo value_instances = NewDownstreamPower : power_downstream NewUpstreamPower : power_upstream NewATUCCRCErrors: ATUCCRCErrors NewATUCFECErrors: ATUCFECErrors NewATUCHECErrors: ATUCHECErrors NewCellDelin: CellDelin NewFECErrors: FECErrors NewHECErrors: HECErrors NewInitErrors: InitErrors NewInitTimeouts: InitTimeouts NewLinkRetrain: LinkRetrain NewLossOfFraming: LossOfFraming NewReceiveBlocks: ReceiveBlocks NewTransmitBlocks: TransmitBlocks NewCurrentProfile: CurrentProfile NewModulationType: ModulationType

Thank you for the Infos. Will have a look at it.

@bb-Ricardo @ekoschmi
I don't know why... But now its running...
2022-04-01 10:50:57,729 - INFO: Starting fritzinfluxdb v0.4.0 (2020-08-03)
2022-04-01 10:50:57,733 - INFO: Done reading config files
2022-04-01 10:50:57,886 - INFO: Successfully parsed config
2022-04-01 10:50:58,124 - INFO: Connection to InfluxDB 2 established
2022-04-01 10:50:58,937 - INFO: Successfully connected to FritzBox Lua session
2022-04-01 10:51:01,960 - INFO: Successfully connected to FritzBox TR-069 session
2022-04-01 10:51:01,966 - INFO: Starting main loop
Will know check the data and modify my dashboard... Thanks a lot for your work!!

@bb-Ricardo @ekoschmi
Ups... It looks like, that only the "Lua" values find the way inside the bucket... Or did I miss something?

Hi, well, in my last commit I forgot to activate the TR069 handler.
Just do a git pull and start it again, then you should see loads more.

But actually, I can't connect with Grafana onto the database... Running as version 2... think, I need more time to explore the v2 environment. Maybe because influxDB an Grafana are running in separat container.
Will try as version 1, than I can use my old influx-grafana container...
nice weekend

thank you.
yes the Grafana 2 Setup is a bit different in order to use it with the same dashboard. Thank you for testing as well

@bb-Ricardo my old dashboard is running well with your new services in my InfluxDB v1.8 and Grafana 8.4.4 environment. only have to rename 4 values. now I can add the new lua values like cpu, ram and energy...
When I find a bit more time, I will give v2 a try again. collecting was not the problem only the connection between Influx and Grafana...

The Auth header part where you have to add the token is a bit tricky.
We need to write a propper documentation to help users connecting to influxdb 2 via grafana. But @ekoschmi describtion above is quite complete on this matter.
You had to rename values? At least the TR069 should all be the same.

@bb-Ricardo yes... I don't remember, but my totalbytesreceived and totalbytessend have a 64 at the end... Found out that I have both 32 an 64 bit in my old ini. No problem...

BTW, you made an awesome job...

 Hi Ricardo, I saw that the value are in the service list, but not in my database... I'm using the new version an Influx v1.

on the other hand I found out, that the DB structure is different from your old way of collecting data...
old version:

new version:

Cheers
Ronald

Hi, yes the timestamping has changed. Now single services can have different intervals. So the measurement gets the timestamp at when it actually was taken. This is resulting in different timestamp.
Except for log entries. They get timestamped with their log time entry.
This also gives me some trouble with Grafana and how it presents data but it should be possible to solve. Otherwise I have to come up with a fix for that.
Btw. Just testing the logs panel in Grafana and it is working beautifully.

by now I saw no problems in Grafana with the graphs. everything looks fine.
Where, with which data, did you have trouble in Grafana...
I found out, why power_down- and upstream didn't find the way to my database. It's not included in services_tr069.py also I cloned the repository before I build the container... So, I have to do it again...

@bb-Ricardo @ekoschmi
After some trouble (I missed the "Token" in front of the token) to connect Grafana via InfluxQL to my database its now running. But unfortunately I'm not able to use my old dashboard. Everything is black...

and when I edit a panel... datasource is set to -- Grafana -- even, my old datasource "InfluxDB Home" exist.

It looks like, that I have to renew all panels. After I set the datasource to "InfluxDB Home" and copy & paste the select from the old dashboard, the data will displayed...

Then I found out, that the uid is different. after I exchanged all in the dashboard json, it looking good, but still some panels to modify
     "datasource": {
        "type": "influxdb",
        "uid": "yIntkjy7k"

So thanks a lot for your great work... Now running v2 with InfluxQL and can update my dashboard with the new Lua values and can upgrade Influx when a new version is out...

Hi @ronaldn1969 @ekoschmi,
Anyone willing to test the new/update dashboards?
-> https://github.com/karrot-dev/fritzinfluxdb/tree/rewrite-adding-async/grafana

@bb-Ricardo of course I will... ;)
Have some trouble with the old fritzbox info table. Didn't get the data. And have to move it on my pi4, because it looks like that my pi3 is not fast enough or have lack of ram... Some times fritzinfluxdb is not possible to write into influxdb and than it displayed at timeout in the log...
On the other side I try to convert my dashboard to Flux. But it looks like, that this is not a short way...

I had trouble with Flux language. It was not consistent in a few places, breaking the metrics.
Have a look here: https://github.com/karrot-dev/fritzinfluxdb/blob/6b5b41944d02123578fa1f88b315bca60bf9dc69/grafana_dashboard_fritzbox_influxdb2.json

@bb-Ricardo after my first coffee, I imported your both dashboards... what should I say... INCREDIBLE...!!
running without any problems and display all. If you don't mind, I will snoop around and copy & paste some of the panels to my dashboard. Definitely I will use the separation with drop-down.
later I will take a look on your Flux dashboard. Maybe it's a task, when I get retired... :o)

thank you.
There are still missing metrics:

WLAN associations, channel, name, ...
VPN Users
Home automation
DECT handsets

Hey @bb-Ricardo
I just pulled the repo and now getting following errors:
2022-04-06 14:18:34,225 - INFO: Starting main loop
2022-04-06 14:18:56,209 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:18:56,209 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:19:07,405 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:19:07,405 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:19:14,443 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:19:14,444 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:19:24,221 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:19:24,221 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:19:31,105 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:19:31,106 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:19:39,966 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:19:39,966 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:19:52,813 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:19:52,813 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
2022-04-06 14:20:05,632 - ERROR: Unable to perform request to 'http://<IP_ADDRESS>/data.lua': HTTPConnectionPool(host='<IP_ADDRESS>', port=80): Read timed out. (read timeout=5)
2022-04-06 14:20:05,633 - ERROR: Unable to request FritzBox Lua service 'Passive network hosts'
I also get data very infrequently and not all values...
I looked up logs on the fritzbox which saying something about the session is broken?!

Thank you!

mmmmh, the ungültige Sitzungskennung should not happen. Does a -v reveal more?

Hey, thanks for that nice tip with the verbose flag: I think my Fritzbox needed a restart ^^
now it works fine and there are no more "ungültige Sitzungskennung", although it still cant get the 'Passive network hosts'

Do you get a timeout? Do you have a lot of passive hosts? Maybe try to increase thw timeout value to 10 seconds.

 Now it works, thank you! There are 35 passive hosts, i increased the timeout to 20 seconds. Maybe 5 seconds are not enough.
Thank you!

Great. Please also try out the two Dashboards and see if they work for you.
Thank you.

if anyone is interested in testing the new version, comments are highly appreciated: https://github.com/karrot-dev/fritzinfluxdb/tree/rewrite-adding-async
This branch contains a complete rewrite including two new dashboards.

version 1.0.0 has been released.


Mac ollama install and run results in template error

OS: macOS 14.1.1 (23B81)
RAM: 32GB
Steps to reproduce:

Download https://ollama.ai/download/Ollama-darwin.zip
Open zip
Move app to Applications
Install model from GUI prompt
Open terminal and run ollama run llama2

Observed:
Error: template: :2:11: executing "" at <.Context>: can't evaluate field Context in type struct { First bool; System string; Prompt string }
Expected:
No error, working prompt.

Indeed, it did, thank you! I propose to add a hint somewhere in the app so users know to update the model in case of errors.


docs: fix Update 0.setup.md

@unhead/vite-plugin is not exist.

🔗 Linked issue

❓ Type of change

[x] 📖 Documentation (updates to the documentation, readme, or JSdoc annotations)
[ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
[ ] 👌 Enhancement (improving an existing functionality like performance)
[ ] ✨ New feature (a non-breaking change that adds functionality)
[ ] 🧹 Chore (updates to the build process or auxiliary tools and libraries)
[ ] ⚠ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

📝 Checklist

[ ] I have linked an issue or discussion.
[ ] I have updated the documentation accordingly.

Thanks!


ARROW-10049: [C++/Python] Sync conda recipe with conda-forge

@github-actions crossbow submit -g conda

@github-actions crossbow submit
conda-linux-gcc-py36-cpu

@github-actions crossbow submit conda-linux-gcc-py36-cpu

@github-actions crossbow submit -g conda


Wrong argument passed to FAST_InitializeAll_T

Bug description
The definition of the function FAST_InitializeAll_T has TurbId as it's second argument. The call sites: https://github.com/OpenFAST/openfast/blob/main/modules/openfast-library/src/FAST_Library.f90#L144 and https://github.com/OpenFAST/openfast/blob/main/modules/openfast-library/src/FAST_Library.f90#L148 pass in iTurb to that argument and not TurbId.
To Reproduce
I am calling openfast from amr-wind but this isn't specific to that and I don't build stand-alone openfast so I am not sure what the steps are to reproduce.
Expected behavior
I would expect TurbId to be passed to FAST_InitializeAll_T and not iTurb since that is what it expects in the argument list.
OpenFAST Version
3.5.2
System Information (please complete the following information):

OS: NAME="Rocky Linux" VERSION="8.9 (Green Obsidian)" ID="rocky" ID_LIKE="rhel centos fedora" VERSION_ID="8.9"
Compiler: GNU Fortran (Spack GCC) 10.4.0

The problem appears to be due to a discrepency in how the TurbId is used in FAST.Farm vs with AMR-Wind.  When used with FAST.Farm, the turbine id ranges from 1:NumTurbines, but when coupled to a C code, the turbine id ranges from 0:NumTurbines-1.

Looking at the code, the FAST_Sizes routine does not have a variable TurbID.  Are you referring to another call to FAST_InitializeAll_T from the FAST_OpFM_Init routine (https://github.com/OpenFAST/openfast/blob/main/modules/openfast-library/src/FAST_Library.f90#L589)?
For reasons completely unknown to me, the FAST_OpFM_Initroutine contains both TurbID and iTurb in its input argument list.  I don't actually know why both arguments are there, or if they would ever be different.  However the use of iTurb appears to be consistent in this routine -- it must match the index of the Turbine data structure getting passed to FAST_InitializeAll_T and all uses of the Turbine data structure that follows.  So I propose we remove either TurbID or iTurb from the argument list in FAST_OpFM_Init as those appear redundant.

I am referring to this FAST_InitializeAll_T: https://github.com/OpenFAST/openfast/blob/main/modules/openfast-library/src/FAST_Subs.f90#L37. It uses TurbId in the argument list.
I don't know why there are 2 IDs being passed into FAST_OpFM_Init. In AMR-Wind we seem to pass a local and a global ID to those arguments: https://github.com/Exawind/amr-wind/blob/main/amr-wind/wind_energy/actuator/turbine/fast/FastIface.cpp#L224. I don't know why. Maybe @gantech or @psakievich have a historical perspective on this?

Originally, Turbine was not an array, but there was a TurbID for file naming purposes. The iTurb variable was introduced in https://github.com/OpenFAST/openfast/pull/20

I'm going to close this issue in deference to the underlying issue outlined in #2096.