在Home Assistant中用InfluxDB将两个Yield结果合并为单表
解决方案
要将两个时间偏移的聚合结果合并为包含today和tomorrow列的单表,你可以使用Flux的join函数关联两个数据集,通过调整时间戳让它们对齐。以下是实现代码:
// 先获取基础聚合数据,避免重复查询提升效率 base_agg = from(bucket: "HomeAssistant/autogen") |> range(start: 2022-11-01T00:00:00Z, stop: v.timeRangeStop) |> filter(fn: (r) => r["entity_id"] == "total_energy") |> filter(fn: (r) => r["_field"] == "total_kwh") |> aggregateWindow(every: 24h, fn: max) |> keep(columns: ["_time", "_value"]) // 处理今日数据:将聚合值重命名为today today_data = base_agg |> rename(columns: {_value: "today"}) // 处理明日数据:将时间戳前移24小时对齐今日时间,并重命名聚合值为tomorrow tomorrow_data = base_agg |> timeShift(duration: -24h) |> rename(columns: {_value: "tomorrow"}) // 按时间字段合并两个数据集,得到单表结果 join(tables: {today: today_data, tomorrow: tomorrow_data}, on: ["_time"])
代码说明
- 基础聚合:只执行一次核心聚合逻辑,减少重复查询的性能消耗。
- 时间对齐:通过
timeShift(duration: -24h)把次日数据的时间戳向前调整24小时,让它能和今日数据的时间戳匹配,确保join操作能把同一时间点对应的今日、明日值放在同一行。 - 合并数据集:
join函数基于_time字段关联两个数据集,最终输出每行包含_time、today、tomorrow三个字段的结果表。
如果偏好单管道写法(可读性稍弱),也可以这样写:
join( tables: { today: from(bucket: "HomeAssistant/autogen") |> range(start: 2022-11-01T00:00:00Z, stop: v.timeRangeStop) |> filter(fn: (r) => r["entity_id"] == "total_energy") |> filter(fn: (r) => r["_field"] == "total_kwh") |> aggregateWindow(every: 24h, fn: max) |> keep(columns: ["_time", "_value"]) |> rename(columns: {_value: "today"}), tomorrow: from(bucket: "HomeAssistant/autogen") |> range(start: 2022-11-01T00:00:00Z, stop: v.timeRangeStop) |> filter(fn: (r) => r["entity_id"] == "total_energy") |> filter(fn: (r) => r["_field"] == "total_kwh") |> aggregateWindow(every: 24h, fn: max) |> timeShift(duration: -24h) |> keep(columns: ["_time", "_value"]) |> rename(columns: {_value: "tomorrow"}) }, on: ["_time"] )
需要说明的是,Flux中没有无需关联的“直接合并为列”的语法——因为两个结果集的时间戳原本不重合,必须通过对齐时间后关联,才能将不同时间的数值合并到同一行的不同列中。
内容的提问来源于stack exchange,提问作者Marky0
相关产品推荐
相关产品推荐

