You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

太阳能加热能耗统计技术问询:PostgreSQL与Grafana数据处理

解决方案:基于PostgreSQL的能耗统计(补全变化值的持续时间)

你之前尝试的Grafana分组填充方法精度不足,本质是因为它需要生成每一秒的冗余点,而实际数据仅记录功率变化节点。更高效准确的方式是直接计算每个功率值的持续时长,再累加得到能耗,以下是具体实现方案:


1. PostgreSQL SQL 核心解决方案

能耗的本质是「功率(W) × 时间(s)」,我们通过窗口函数获取每条记录的下一个时间戳,计算当前功率的持续时长,再完成能耗计算与维度统计,同时支持单位转换。

基础逻辑:单设备全周期能耗统计

WITH device_data AS (
    SELECT
        id,
        ts,
        val AS power_w,
        -- 获取下一条记录的时间戳,最后一条用当前时间作为结束节点(可替换为固定结束时间)
        LEAD(ts, 1, EXTRACT(EPOCH FROM NOW())*1000) OVER (PARTITION BY id ORDER BY ts) AS next_ts
    FROM ts_number
    -- 可选:过滤指定设备 WHERE id = 23
    -- 可选:适配Grafana时间范围 WHERE ts >= $__unixEpochFrom()*1000 AND ts <= $__unixEpochTo()*1000
),
energy_calculations AS (
    SELECT
        id,
        -- 计算当前功率的持续秒数
        (next_ts - ts)/1000 AS duration_s,
        -- 单段能耗:W × s = Ws(瓦秒)
        power_w * ((next_ts - ts)/1000) AS energy_ws
    FROM device_data
)
-- 汇总并转换单位
SELECT
    id,
    SUM(energy_ws) AS total_ws,
    SUM(energy_ws)/3600 AS total_wh,   -- 1Wh = 3600Ws
    SUM(energy_ws)/3600000 AS total_kwh -- 1kWh = 3.6×10^6Ws
FROM energy_calculations
GROUP BY id;

按日/月/年统计能耗

以按日统计为例,只需将时间戳转换为日期维度后分组:

WITH device_data AS (
    SELECT
        id,
        ts,
        val AS power_w,
        LEAD(ts, 1, EXTRACT(EPOCH FROM NOW())*1000) OVER (PARTITION BY id ORDER BY ts) AS next_ts,
        -- 将毫秒时间戳转换为日期
        DATE_TRUNC('day', TO_TIMESTAMP(ts/1000)) AS record_date
    FROM ts_number
    -- 适配Grafana时间范围 WHERE ts >= $__unixEpochFrom()*1000 AND ts <= $__unixEpochTo()*1000
),
energy_calculations AS (
    SELECT
        id,
        record_date,
        power_w * ((next_ts - ts)/1000) AS energy_ws
    FROM device_data
)
SELECT
    id,
    record_date,
    SUM(energy_ws) AS daily_ws,
    SUM(energy_ws)/3600 AS daily_wh,
    SUM(energy_ws)/3600000 AS daily_kwh
FROM energy_calculations
GROUP BY id, record_date
ORDER BY record_date;

关键说明

  • LEAD()窗口函数:自动获取同设备下的下一条记录时间戳,解决了「缺失记录的持续时间」问题
  • 单位转换:严格遵循物理单位换算规则,避免统计误差
  • Grafana适配:直接替换为$__unixEpochFrom()/$__unixEpochTo()变量,实现时间选择器联动

2. 自定义代码预处理方案(Docker兼容)

如果SQL灵活性无法满足需求,可编写脚本定时预处理数据,生成全量时间粒度的统计结果,存储到新表供Grafana快速查询:

步骤1:创建统计结果表

CREATE TABLE IF NOT EXISTS energy_daily (
    id INTEGER NOT NULL,
    record_date DATE NOT NULL,
    total_kwh REAL NOT NULL,
    PRIMARY KEY (id, record_date)
);

步骤2:Python预处理脚本(示例)

import psycopg2
from datetime import datetime, timedelta

# Docker容器间连接:用PostgreSQL容器名/IP作为host
conn = psycopg2.connect(
    dbname="iobroker",
    user="your_db_user",
    password="your_db_pass",
    host="postgres-container"
)
cur = conn.cursor()

# 处理指定设备(可循环遍历所有设备id)
device_id = 23
start_date = datetime(2023, 1, 1)
end_date = datetime.now()

current_date = start_date
while current_date <= end_date:
    # 获取当日的所有功率变化记录
    cur.execute("""
        SELECT ts, val FROM ts_number
        WHERE id = %s AND ts >= %s AND ts <= %s
        ORDER BY ts
    """, (
        device_id,
        int(current_date.timestamp())*1000,
        int((current_date + timedelta(days=1)).timestamp())*1000 - 1
    ))
    records = cur.fetchall()
    
    total_ws = 0
    prev_ts, prev_power = None, None
    for ts, power in records:
        if prev_ts is not None:
            duration_s = (ts - prev_ts)/1000
            total_ws += prev_power * duration_s
        prev_ts, prev_power = ts, power
    
    # 处理最后一条记录到当日结束的时长
    if prev_ts is not None:
        end_of_day_ts = int((current_date + timedelta(days=1)).timestamp())*1000 - 1
        duration_s = (end_of_day_ts - prev_ts)/1000
        total_ws += prev_power * duration_s
    
    # 转换为kWh并存入统计表(存在则更新)
    total_kwh = total_ws / 3600000
    cur.execute("""
        INSERT INTO energy_daily (id, record_date, total_kwh)
        VALUES (%s, %s, %s)
        ON CONFLICT (id, record_date) DO UPDATE SET total_kwh = EXCLUDED.total_kwh
    """, (device_id, current_date.date(), total_kwh))
    
    current_date += timedelta(days=1)

conn.commit()
cur.close()
conn.close()

步骤3:Docker部署

将脚本打包为镜像,用cron调度(例如每天凌晨运行一次),实现自动化预处理。


3. 精度优化建议

  • 将ts_number表的val字段从REAL改为NUMERIC,避免浮点精度损失
  • 统计时保留至少3位小数,确保kWh级别的统计精度

内容的提问来源于stack exchange,提问作者IceBoosteR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 02:31:32