{
  "__comment": "Дашборд блока гидропоники. Переработан из iot-overview.json: те же переменные $node/$metric и связь с $__timeFilter, но выборка сужена до узлов фермы (node_id LIKE 'hydro-%'). Datasource — grafana_ro (только чтение). На этапе прототипа задача минимальная: данные доезжают и видны; тонкая настройка панелей/тревог — позже.",
  "annotations": { "list": [] },
  "editable": true,
  "graphTooltip": 1,
  "schemaVersion": 39,
  "tags": ["iot", "ферма", "гидропоника"],
  "title": "Ферма — обзор",
  "uid": "hydro-overview",
  "time": { "from": "now-24h", "to": "now" },
  "templating": {
    "list": [
      {
        "name": "metric",
        "label": "Метрика",
        "type": "query",
        "datasource": { "type": "grafana-postgresql-datasource" },
        "query": "SELECT DISTINCT metric FROM readings WHERE node_id LIKE 'hydro-%' ORDER BY metric;",
        "refresh": 2,
        "sort": 1,
        "includeAll": false
      },
      {
        "name": "node",
        "label": "Узел",
        "type": "query",
        "datasource": { "type": "grafana-postgresql-datasource" },
        "query": "SELECT DISTINCT node_id FROM readings WHERE node_id LIKE 'hydro-%' ORDER BY node_id;",
        "refresh": 2,
        "sort": 1,
        "includeAll": true,
        "multi": true
      }
    ]
  },
  "panels": [
    {
      "title": "$metric по времени (узлы фермы)",
      "type": "timeseries",
      "datasource": { "type": "grafana-postgresql-datasource" },
      "gridPos": { "h": 10, "w": 18, "x": 0, "y": 0 },
      "fieldConfig": { "defaults": { "custom": { "lineWidth": 2, "fillOpacity": 10 } } },
      "targets": [
        {
          "format": "time_series",
          "rawSql": "SELECT r.time AS \"time\", coalesce(d.label, r.node_id) AS \"metric\", r.value AS \"value\" FROM readings r LEFT JOIN devices d ON d.node_id = r.node_id WHERE r.metric = '$metric' AND r.node_id IN ($node) AND r.node_id LIKE 'hydro-%' AND $__timeFilter(r.time) ORDER BY r.time;"
        }
      ]
    },
    {
      "title": "Последнее значение по узлам фермы",
      "type": "table",
      "datasource": { "type": "grafana-postgresql-datasource" },
      "gridPos": { "h": 10, "w": 6, "x": 18, "y": 0 },
      "targets": [
        {
          "format": "table",
          "rawSql": "SELECT DISTINCT ON (r.node_id) coalesce(d.label, r.node_id) AS \"узел\", r.value AS \"значение\", r.time AS \"когда\" FROM readings r LEFT JOIN devices d ON d.node_id = r.node_id WHERE r.metric = '$metric' AND r.node_id LIKE 'hydro-%' ORDER BY r.node_id, r.time DESC;"
        }
      ]
    },
    {
      "title": "Свежесть: как давно узел фермы молчит",
      "type": "table",
      "datasource": { "type": "grafana-postgresql-datasource" },
      "gridPos": { "h": 8, "w": 24, "x": 0, "y": 10 },
      "targets": [
        {
          "format": "table",
          "rawSql": "SELECT coalesce(d.label, r.node_id) AS \"узел\", max(r.time) AS \"последний раз\", now() - max(r.time) AS \"молчит\" FROM readings r LEFT JOIN devices d ON d.node_id = r.node_id WHERE r.node_id LIKE 'hydro-%' GROUP BY r.node_id, d.label ORDER BY max(r.time) DESC;"
        }
      ]
    }
  ]
}
