如下查询利用了 TimescaleDB 的特性(如 time_bucket
)和 Grafana 的宏(如 $__timeFilter
, $__interval
, 以及自定义变量)。
前提条件:
$substation
: 用于选择变电站 (Substation)。查询: SELECT DISTINCT Substation FROM DimXTU;
$xtu_id
: 用于选择 XTU。查询: SELECT DISTINCT XTU_ID FROM DimXTU WHERE Substation = '$substation';
(级联选择)$ftu_id
: 用于选择 FTU。查询: SELECT DISTINCT FTU_ID FROM DimFTU WHERE XTUKey IN (SELECT XTUKey FROM DimXTU WHERE XTU_ID = '$xtu_id') AND IsCurrent = TRUE;
(级联选择) 或 SELECT DISTINCT FTU_ID FROM DimFTU WHERE IsCurrent = TRUE;
(选择所有当前的 FTU)用于 Grafana 的 SQL 查询示例:
1. 单个 FTU 实时电压曲线 (Time Series Panel)
$ftu_id
变量来选择 FTU。SQL
SELECT
fr.ReadingTimestamp AS "time", -- Grafana 需要时间列别名为 "time"
fr.UA_Voltage AS "UA Voltage",
fr.UB_Voltage AS "UB Voltage",
fr.UC_Voltage AS "UC Voltage"
FROM FactPowerReadings fr
JOIN DimFTU df ON fr.FTUKey = df.FTUKey
WHERE
$__timeFilter(fr.ReadingTimestamp) -- 使用 Grafana 的时间范围过滤器
AND df.FTU_ID = '$ftu_id' -- 使用 Grafana 变量选择 FTU
AND df.IsCurrent = TRUE -- 确保我们使用的是当前有效的 FTU 记录
ORDER BY fr.ReadingTimestamp ASC;
$__timeFilter(fr.ReadingTimestamp)
会被 Grafana 替换为当前仪表板选择的时间范围条件,例如 fr.ReadingTimestamp BETWEEN '2023-10-26T10:00:00Z' AND '2023-10-26T11:00:00Z'
。'$ftu_id'
会被替换为 Grafana 变量下拉列表中选择的值。df.IsCurrent = TRUE
很重要,用于过滤掉该 FTU 历史上可能存在的旧记录(如果 FTU 更换过或信息变更过)。UAB_Voltage
, UBC_Voltage
, UCA_Voltage
。2. 单个 FTU 实时电流曲线 (Time Series Panel)
I0_Current
)。零序电流过高通常表示三相不平衡或接地故障。$ftu_id
变量。SQL
SELECT
fr.ReadingTimestamp AS "time",
fr.IA_Current AS "IA Current",
fr.IB_Current AS "IB Current",
fr.IC_Current AS "IC Current",
fr.I0_Current AS "I0 Current"
FROM FactPowerReadings fr
JOIN DimFTU df ON fr.FTUKey = df.FTUKey
WHERE
$__timeFilter(fr.ReadingTimestamp)
AND df.FTU_ID = '$ftu_id'
AND df.IsCurrent = TRUE
ORDER BY fr.ReadingTimestamp ASC;
3. 单个 FTU 实时功率曲线 (Time Series Panel)
$ftu_id
变量。SQL
SELECT
fr.ReadingTimestamp AS "time",
fr.ActivePower_Total AS "Total Active Power",
fr.ReactivePower_Total AS "Total Reactive Power",
fr.ApparentPower_Total AS "Total Apparent Power"
FROM FactPowerReadings fr
JOIN DimFTU df ON fr.FTUKey = df.FTUKey
WHERE
$__timeFilter(fr.ReadingTimestamp)
AND df.FTU_ID = '$ftu_id'
AND df.IsCurrent = TRUE
ORDER BY fr.ReadingTimestamp ASC;
4. 按变电站/XTU 聚合的总有功功率 (Time Series Panel)
$substation
或 $xtu_id
变量。SQL
SELECT
time_bucket('$__interval', fr.ReadingTimestamp) AS "time", -- 按 Grafana 动态计算的时间间隔聚合
AVG(fr.ActivePower_Total) AS "Average Active Power"
-- SUM(fr.ActivePower_Total) AS "Total Active Power" -- 如果想看总和
FROM FactPowerReadings fr
JOIN DimFTU df ON fr.FTUKey = df.FTUKey
JOIN DimXTU dx ON df.XTUKey = dx.XTUKey
WHERE
$__timeFilter(fr.ReadingTimestamp)
AND dx.XTU_ID = '$xtu_id' -- 根据 XTU 过滤
-- 或者按变电站过滤: AND dx.Substation = '$substation'
AND df.IsCurrent = TRUE
GROUP BY "time"
ORDER BY "time" ASC;
time_bucket('$__interval', fr.ReadingTimestamp)
是 TimescaleDB 的函数,它将时间戳分组到由 Grafana 动态确定的时间桶中 ($__interval
)。这对于在不同时间范围下保持图表的可读性至关重要。AVG()
或 SUM()
来聚合数据。5. FTU 数据新鲜度 (Table Panel or Stat Panel)
$substation
或 $xtu_id
。SQL
SELECT
df.FTU_ID,
dx.Substation, -- 可选,显示所属变电站
MAX(fr.ReadingTimestamp) AS "Last Reading Timestamp",
NOW() - MAX(fr.ReadingTimestamp) AS "Time Since Last Reading" -- 计算延迟
FROM FactPowerReadings fr
JOIN DimFTU df ON fr.FTUKey = df.FTUKey
JOIN DimXTU dx ON df.XTUKey = dx.XTUKey
WHERE
df.IsCurrent = TRUE
-- Optional filters based on Grafana variables:
-- AND dx.Substation = '$substation'
-- AND dx.XTU_ID = '$xtu_id'
-- AND df.FTU_ID = '$ftu_id'
GROUP BY df.FTU_ID, dx.Substation
ORDER BY "Last Reading Timestamp" ASC; -- 将最久未上报的排在前面
ReadingTimestamp
。NOW() - MAX(...)
计算当前时间与最后读数时间的时间差,可以直观地看到延迟。Time Since Last Reading
列进行着色,突出显示延迟过长的设备。6. FTU/XTU 状态概览 (Pie Chart or Stat Panel)
SQL
SELECT
Status,
COUNT(*) AS "Count"
FROM DimFTU
WHERE
IsCurrent = TRUE
-- Optional: Filter by substation or XTU using joins if needed
-- JOIN DimXTU dx ON DimFTU.XTUKey = dx.XTUKey
-- WHERE dx.Substation = '$substation'
GROUP BY Status;
SQL
SELECT
Status,
COUNT(*) AS "Count"
FROM DimXTU
-- Optional: Filter by substation
-- WHERE Substation = '$substation'
GROUP BY Status;
7. 电压/电流越限告警 (触发 Grafana Alerting)
SQL
SELECT
fr.ReadingTimestamp AS "time",
df.FTU_ID,
GREATEST(fr.UA_Voltage, fr.UB_Voltage, fr.UC_Voltage) AS "Max Phase Voltage" -- 找到三相中最高的电压
FROM FactPowerReadings fr
JOIN DimFTU df ON fr.FTUKey = df.FTUKey
WHERE
fr.ReadingTimestamp >= NOW() - INTERVAL '5 minutes' -- 只看最近 5 分钟的数据
AND df.IsCurrent = TRUE
AND (
fr.UA_Voltage > 240 OR fr.UB_Voltage > 240 OR fr.UC_Voltage > 240 -- 假设 240V 是上限阈值
-- 也可以检查线电压: fr.UAB_Voltage > 415 OR ...
)
ORDER BY fr.ReadingTimestamp DESC;
集成到 Grafana 的步骤:
WHERE
子句中的变量过滤)。$ftu_id
, $substation
等),确保这些变量已在仪表板设置 (Dashboard settings -> Variables) 中创建。