Telegraf KNX 输入插件(knx_listener)接入指南:从 KNX 家庭自动化总线采集指标到 InfluxDB
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
导读
knx_listener是 Telegraf 提供的一个服务型输入插件(Service Input),它通过 KNX-IP 接口连接到 KNX 家庭自动化总线,实时监听总线上的组地址(Group-Address)消息,并将解析后的数值、单位与来源物理地址写入指定 measurement。阅读本文后,你将掌握该插件的完整配置语法(service_type、service_address、measurement子表)、DPT(Datapoint-Type)到测量值的映射规则、输出字段与标签结构,以及其底层基于knx-go的连接、解包与断线重连机制。
插件概览
- 功能定位:服务型输入插件,通过 KNX-IP 接口(隧道或路由模式)连接 KNX 总线,接收组事件并转换为 Telegraf 指标。
- 引入版本:Telegraf v1.19.0 起提供(见 README.md 顶部徽标)。
- 类别标识:🏷️ iot(物联网场景),💻 all(支持所有平台)。
- 实现位置:knx_listener.go,注册名称为
inputs.knx_listener(见 plugins/inputs/all/knx_listener.go)。 - 底层依赖:KNX 协议交互由开源库
knx-go(github.com/vapourismo/knx-go/knx与.../knx/dpt)完成,支持的 DPT 类型以该库的实现为准。
服务型输入插件(Service Input)的特殊性
该插件属于服务型输入插件。与普通插件按固定interval轮询采集不同,服务型插件会启动一个后台服务持续监听总线事件。根据 docs/includes/service_input.md 的说明,它有两点关键差异:
interval设置可能不生效:无论是全局还是插件级别的interval,都不会驱动该插件采集数据——数据的产生完全由 KNX 总线上的消息触发。--test、--test-wait、--once命令行选项可能无输出:这些选项通常要求插件在限定时间内完成一次采集,而服务型插件需要等待外部事件,因此调试时应改用真实总线数据或测试环境(仓库提供了dummy接口类型供本地验证,见下文源码分析)。
此外,所有插件都支持一些通用配置项(如修改指标、标签、字段、设置别名、调整插件顺序等),详见 docs/CONFIGURATION.md#plugins。
配置详解
完整配置示例位于 sample.conf,该文件同时被//go:embed嵌入二进制作为插件默认样例配置(见 knx_listener.go 的SampleConfig()实现)。
# Listener capable of handling KNX bus messages provided through a KNX-IP Interface. [[inputs.knx_listener]] ## Type of KNX-IP interface. ## Can be either "tunnel_udp", "tunnel_tcp", "tunnel" (alias for tunnel_udp) or "router". # service_type = "tunnel" ## Address of the KNX-IP interface. service_address = "localhost:3671" ## Measurement definition(s) # [[inputs.knx_listener.measurement]] # ## Name of the measurement # name = "temperature" # ## Datapoint-Type (DPT) of the KNX messages # dpt = "9.001" # ## Use the string representation instead of the numerical value for the # ## datapoint-type and the addresses below # # as_string = false # ## List of Group-Addresses (GAs) assigned to the measurement # addresses = ["5/5/1"] # [[inputs.knx_listener.measurement]] # name = "illumination" # dpt = "9.004" # addresses = ["5/5/3"]顶层参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
service_type | string | "tunnel" | KNX-IP 接口类型,可选tunnel_udp、tunnel_tcp、tunnel(tunnel_udp的别名)或router。另有非公开值dummy用于本地测试。 |
service_address | string | (必填) | KNX-IP 接口地址,格式为host:port,默认示例为localhost:3671(KNXnet/IP 标准端口 3671)。 |
在源码 knx_listener.go 中,Start()根据service_type分支建立连接:
tunnel/tunnel_udp:使用knx.DefaultTunnelConfig且UseTCP = false,调用knx.NewGroupTunnel()建立UDP 隧道连接;tunnel_tcp:同样使用knx.DefaultTunnelConfig但UseTCP = true,建立TCP 隧道连接;router:调用knx.NewGroupRouter()建立组路由连接;dummy:创建内存模拟接口knxDummyInterface(见 knx_dummy_interface.go),仅用于单元测试;- 其他值:返回错误
invalid interface type。
插件实例默认以ServiceType: "tunnel"初始化(见 knx_listener.go 的init()注册逻辑),与样例配置注释中的默认值一致。
measurement 子表参数
每个[[inputs.knx_listener.measurement]]子表定义一组测量规则:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | string | 必填 | 生成的 measurement 名称(即写入 InfluxDB 的测量名)。 |
dpt | string | 必填 | 该测量对应的 KNX Datapoint-Type(如9.001表示 2 字节浮点温度值)。仅能声明一个 DPT。 |
as_string | bool | false | 为true时,字段值输出 DPT 的字符串表示(如On/Off、Enable/Disable)而非数值;同时组地址也按字符串处理。 |
addresses | []string | 必填 | 归属该测量的 KNX 组地址(GA)列表,格式如5/5/1(两段式)或1/0/1(三段式)。 |
测量配置要点与约束
- 每个 measurement 只包含一个DPT,并为该 DPT 绑定一组地址。例如可以把所有温度传感器消息归入
temperaturemeasurement。 - 你可以自由地将同一个 DPT 的消息拆分到多个 measurement中,以便按房间、按传感器类型分表。
- 重要约束:README 明确警告——不应将同一个组地址(GA)分配到多个 measurement!这一约束在源码层面被强制执行:
Init()在构建gaTargetMap(GA → measurement/DPT 映射)时,若发现重复地址会直接返回错误duplicate specification of address(见 knx_listener.go)。
相关辅助工具
- knx-telegraf-config-generator:一个外部社区工具,可从 KNX 项目文件(ETS 导出)自动生成 Telegraf 配置,省去手工编写大量
measurement子表的工作(README 相关章节)。
指标输出:字段与标签
收到 KNX 消息后,插件将其写入配置指定的 measurement,字段名为value,并附带以下标签(见 knx_listener.go):
| 标签 | 说明 |
|---|---|
groupaddress | KNX 组地址(对应数值来源) |
unit | 数值的单位(取自 DPT 元数据,例如°C、lux) |
source | 发送该值的 KNX 物理地址 |
关于字段类型:源码中listen()在解包数据帧后会通过反射(reflect.Indirect)把knx-go的dpt.DatapointValue接口值还原为基础类型(bool / int / uint / float / string),以避免指标被静默丢弃(见 knx_listener.go)。当as_string = true时则直接使用target.datapoint.String()输出字符串表示。
关于字段类型归属:若需确认某个 DPT 对应的具体数据类型与单位,可查阅你的 KNX 项目(ETS)、KNX 规范或knx-go项目中对应 DPT 的实现(如 knx_listener_test.go 中的测试用例覆盖了 1.001、5.001、9.001、13.xxx、14.xxx、16.000 等常见 DPT)。
示例输出(Line Protocol)
illumination,groupaddress=5/5/4,host=Hugin,source=1.1.12,unit=lux value=17.889999389648438 1582132674999013274 temperature,groupaddress=5/5/1,host=Hugin,source=1.1.8,unit=°C value=17.799999237060547 1582132663427587361 windowopen,groupaddress=1/0/1,host=Hugin,source=1.1.3 value=true 1582132630425581320从示例可见:
temperature(DPT 9.001)输出带unit=°C的浮点值;illumination(DPT 9.004)输出带unit=lux的浮点值;windowopen(布尔类 DPT)输出value=true,且因布尔类型无单位,示例中没有unit标签(unit标签来自 DPT 元数据的Unit()方法)。host标签由 Telegraf 全局配置自动添加。
底层实现与运行机制
启动与监听流程
Start()(knx_listener.go)完成连接后,会启动一个 goroutine 调用listen(acc)持续消费knxInterface.Inbound()通道中的knx.GroupEvent。核心处理逻辑:
- 忽略读请求:
GroupValue_Read请求被直接跳过——原因是此类消息要么因数据长度无效(非 DPT1)而解包失败,要么因数据恒为0而产生错误的false值(DPT1)(见 knx_listener.go)。 - 地址匹配:以消息目标地址(
msg.Destination.String())查gaTargetMap;未配置的 GA 会被忽略,且通过gaLogbook记录以避免日志刷屏(仅首次出现时输出一条Ignoring message ... for unknown GA日志)。 - 数据解包:调用
target.datapoint.Unpack(msg.Data)按 DPT 解析原始字节,失败则记录错误并跳过。 - 类型还原与输出:按上文所述还原为基础类型后,以
acc.AddFields(measurement, fields, tags)写入指标。
断线自动重连
插件具备自动重连能力:
- 监听 goroutine 一旦退出(如总线断开),会置
connected标志为false并向 accumulator 报告disconnected from bus错误(knx_listener.go)。 - 随后的每个
Gather()周期都会检查connected标志,若发现断开则调用Start()重新连接,直至成功(knx_listener.go)。 Stop()负责关闭底层接口并等待监听 goroutine 退出(knx_listener.go)。
TestReconnect(knx_listener_test.go)通过dummy接口验证了完整链路:发送消息 → 关闭接口触发断连 → 断言disconnected from bus错误 → 调用Gather()触发重连 → 再次发送消息并成功采集。
测试验证与 DPT 覆盖
knx_listener_test.go 中的TestRegularReceives_DPT覆盖了超过 30 种地址/DPT 组合,包括:
- 布尔类(1.xxx):
1.001(开/关,字符串表示On/Off)、1.002(True/False)、1.003(Enable/Disable)、1.009(Close/Open)、1.010(Start/Stop); - 浮点与百分比(5.xxx、9.xxx):
5.001、5.003、5.004、9.001(温度)、9.004(照度 lux)、9.005、9.007; - 有符号/无符号整数(13.xxx):
13.001、13.002、13.010~13.015; - 物理量(14.xxx):
14.000~14.004、14.010、14.011; - 字符串(16.000):
hello world。
TestRegularReceives_MultipleMessages验证了同一地址重复消息、以及未配置地址(1/1/2)的消息被忽略的行为,与 README 中"不应重复分配 GA"的约束形成闭环。
使用前提与限制
- KNX 基础设施:需要一个可达的 KNX-IP 接口(如 IP 网关/接口,端口 3671),或具备组路由能力的 KNX-IP 路由器。
- KNX 知识:需要了解 KNX 组地址(GA)与 Datapoint-Type(DPT)概念,通常可从 ETS 项目文件获取对应关系。
- 平台兼容:插件标记为
all,跨平台可用;dummy接口仅存在于测试代码路径,不影响生产使用。 - 事件驱动:指标只在总线上出现消息时产生,空闲时段不会有新数据写入。
小结
knx_listener将 KNX 家庭自动化总线与 Telegraf 指标管道无缝衔接:通过简单的measurement子表即可完成 GA→DPT→measurement 的映射,自动附带组地址、单位与来源物理地址标签;底层由knx-go负责 KNXnet/IP 协议交互,并内置断线自动重连。结合 sample.conf、knx_listener.go 与 knx_listener_test.go 的源码证据,你可以快速将温度、照度、开关状态等 KNX 总线数据接入 InfluxDB,构建完整的智能家居监控体系。
【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考