Octopus 提供了两种的方法与MQTT集成:

  1. modbusopcuabledummy,都支持通过 MQTT 代理同步设备状态。
  2. 如果设备支持 MQTT,则可以将MQTT 适配器用作首选。

这篇文章主要概述了第一种方法的细节,如果您想了解更多关于 MQTT 适配器的信息,请查看MQTT 适配器。 如果以上开箱即用的方式无法满足您的要求,则可以按照CONTRIBUTING提出您的想法,或开发新的适配器

说明: MQTT 集成目前仅支持**write - [publish]**的模板主题。

尽管 MQTT 的最新版本为 v5.0,但目前 Octopus 暂时不支持该修订版,主要原因是相应的开发库尚不支持paho.mqtt.golang/issues#347

目前 Octopus 支持的 MQTT 版本如下:

设备与 MQTT 集成后,可以显示设备状态、赋予设备使用 MQTT 的能力,或扩展设备的使用场景,例如设备交互和设备监视。

MQTT

MQTT 是机器对机器(M2M)物联网连接协议。 它被设计为一种非常轻量级的消息传输协议。 对于与需要较小代码占用和网络带宽非常宝贵的远程位置的连接很有用。

尽管 MQTT 的名称包含MQ,但它不是用于定义消息队列的协议,实际上,MQ是指 IBM 的 MQseries 产品,与消息队列无关。。 MQTT 是一种轻量级的二进制协议,并且由于其最小的数据包开销,与 HTTP 之类的协议相比,MQTT 在通过网络传输数据时表现出色。 MQTT 提供了一种可以像消息队列一样发布和订阅的通信方式,同时,提供了许多功能来丰富通信场景,例如 QoS,最后遗嘱和遗嘱,保留的消息等。 要了解有关 MQTT 的更多信息,强烈推荐一系列文章:MQTT Essentials

mqtt-tcp-ip-stack

惯例

MQTT 使用基于主题的消息过滤每封邮件都包含一个主题(主题),代理可以使用该主题来确定订阅客户端是否收到该邮件。

在 MQTT 中,topic是可用于过滤和路由消息的层次结构字符串, 而payload数据不可知,这意味着发布者可以发送二进制数据,文本数据甚至是 完整的 XML 或 JSON,因此设计主题树和有效负载架构是任何 MQTT 部署的重要工作。

Octopus 建议您参考MQTT Essentials 中 MQTT 主题的最佳实践来构造 topic名称,并将 payload 数据编组为 JSON。

配置选项

octopus 重组了github.com/eclipse/paho.mqtt.golang的客户端参数,然后提供了一组配置选项。

目前官方的适配器如BLEModbusopcua都支持 MQTT 协议扩展,使用相同的配置(参考以下spec.template.spec.extension.mqtt)。

  1. apiVersion: edge.cattle.io/v1alpha1
  2. kind: DeviceLink
  3. metadata:
  4. name: living-room-fan
  5. spec:
  6. adaptor:
  7. node: edge-worker
  8. name: adaptors.edge.cattle.io/dummy
  9. model:
  10. apiVersion: "devices.edge.cattle.io/v1alpha1"
  11. kind: "DummySpecialDevice"
  12. template:
  13. metadata:
  14. labels:
  15. device: living-room-fan
  16. spec:
  17. extension:
  18. mqtt:
  19. client:
  20. server: tcp://test.mosquitto.org:1883
  21. maxReconnectInterval: 20s
  22. message:
  23. topic: cattle.io/octopus/:namespace/:name
  24. qos: 1
  25. protocol:
  26. location: "living_room"
  27. gear: slow
  28. "on": true

规范

MQTT 选项的规范在所有 MQTT 扩展适配器中均有效,它们用于连接 MQTT 代理,指导连接,指示要发布/订阅的主题以及有效载 payload 的编码。

MQTTOptions

参数描述类型是否必填
client指定客户端的设置MQTTClientOptions
message指定信息的设置MQTTMessageOptions
MQTTClientOptions
参数描述类型是否必填
server指定 MQTT broker 的服务器 URI,格式为 “schema://host:port”。schema的可选值为:”ws”、”wss”、”tcp”、”unix”、”ssl”、”tls “或 “tcps “。string
protocolVersion指定集群连接到 broker 时使用的 MQTT 协议版本。可选值是3—MQTT 3.1 和4—MQTT 3.1.1,默认值是0uint
basicAuth指定客户端连接到 MQTT broker 的用户名和密码MQTTClientBasicAuth
tlsConfig指定客户端连接到 MQTT broker 的 TLS 配置MQTTClientTLS
cleanSession指定在连接消息中设置 “clean session “标志,MQTT broker 不应该,默认为truebool
store指定在 QoS 级别为 1 或 2 的情况下提供消息持久性,默认存储为 “Memory”MQTTClientStore
resumeSubs指定在连接但未重新连接时恢复存储的(未)订阅信息。只有当cleanSessionfalse时才有效。默认值是falsebool
connectTimeout指定客户端在超时和出错前尝试打开与 MQTT 代理的连接的时间。持续时间为 0,则不会超时。默认值是30smetav1.Duration
keepAlive指定客户端在向代理发送 PING 请求之前应该等待的时间。默认的 keep alive 是10smetav1.Duration
pingTimeout指定客户端向 broker 发送 PING 请求后应该等待的时间长度默认值是10smetav1.Duration
order指定消息路由以保证每个 QoS 级别内的顺序。默认值为 “true”bool
writeTimeout指定客户端成功发布消息后出现超时错误的时间,默认为 30smetav1.Duration
waitTimeout指定客户端订阅/发布消息后应超时的时间,持续时间为0永远不会超时。metav1.Duration
disconnectQuiesce指定客户端断开连接时的静止时间,默认为 “5s”metav1.Duration
autoReconnect配置使用自动重连逻辑,默认为 “true”bool
maxReconnectInterval指定客户在重新连接到经纪商之前应该等待的时间,默认为10mmetav1.Duration
messageChannelDepth指定客户端暂时离线时保存消息的内部队列大小,默认为100uint
httpHeaders指定客户端在 WebSocket 开启握手时发送的附加 HTTP 头信息。string
MQTTClientBasicAuth
参数描述类型是否必填
username指定基本认证的用户名string
usernameRef指定 DeviceLink 的引用关系,将该值作为用户名引用edgev1alpha1.DeviceLinkReferenceRelationship
password指定基本认证的密码string
passwordRef指定 DeviceLink 的引用关系,将该值作为密码引用edgev1alpha1.DeviceLinkReferenceRelationship
MQTTClientTLS
参数描述类型是否必填
caFilePEMCA 证书的 PEM 格式内容,用于验证服务器证书string
caFilePEMRef指定 DeviceLink 的引用关系,以引用值作为 CA 文件的 PEM 内容edgev1alpha1.DeviceLinkReferenceRelationship
certFilePEM证书的 PEM 格式内容,用于客户端对服务器的认证string
certFilePEMRef指定 DeviceLink 的引用关系,以引用值作为客户端证书文件的 PEM 内容edgev1alpha1.DeviceLinkReferenceRelationship
keyFilePEM密钥的 PEM 格式内容,用于客户端对服务器的认证。string
keyFilePEMRef指定 DeviceLink 的引用关系,将该值作为客户端密钥文件 PEM 内容引用。*edgev1alpha1.DeviceLinkReferenceRelationship
serverName表示服务器的名称,参考http://tools.ietf.org/html/rfc4366#section-3.1string
insecureSkipVerify不验证服务器证书,默认值为falsebool
MQTTClientStore
参数描述类型是否必填
type指定存储的类型,可选值为”memory”和 “file”,默认值是 “memory”。string
direcotryPrefix如果使用 “文件 “存储,则指定存储的目录前缀,默认值是/var/run/octopus/mqtt。默认值是/var/run/octopus/mqttstring

MQTTMessageOptions

FieldDescriptionSchemaRequired
topic指定主题true
will指定遗嘱信息MQTTWillMessage
qos指定消息的 QoS,默认值为1MQTTMessageQoSLevel
retained指定是否保留最后发布的消息,默认为 “true”bool
path指定渲染 topic 的:path关键字的路径。string
operator指定用于渲染主题的:operator关键字的操作符。*MQTTMessageTopicOperator
MQTTWillMessage
参数描述类型是否必填
topic指定遗嘱消息的主题,如果没有设置,主题将在父字段指定的主题名称后附加$will作为主题名称。如果没有设置,主题将在父字段中指定的主题名称后附加”$will “作为主题名称。string
content指定 will 消息的内容。内容的序列化形式是 Base64 编码的字符串,在这里表示任意(可能是非字符串)的内容值string
MQTTMessageQoSLevel
参数描述类型
0最多发送一次byte
1最少发送一次byte
2只发送一次byte
MQTTMessageTopicOperator
参数描述类型是否必填
read指定在订阅时渲染主题的:operator关键字的操作符stringfalse
write指定在发布时渲染主题的:operator关键字的操作符stringfalse

YAML 配置文件示例

MQTT 选项的规范在所有 MQTT 扩展适配器中均有效,它们用于连接 MQTT 代理服务器,引导连接,指示要发布/订阅的主题以及有效 Payload 的编码等。REQUIRED 是必填字段。

  1. # Specifies the client settings.
  2. client:
  3. # Specifies the server URI of MQTT broker, the format should be `schema://host:port`.
  4. # The "schema" is one of the "ws", "wss", "tcp", "unix", "ssl", "tls" or "tcps".
  5. # REQUIRED
  6. server: <string>
  7. # Specifies the MQTT protocol version that the cluster uses to connect to broker.
  8. # Legitimate values are currently 3 - MQTT 3.1 or 4 - MQTT 3.1.1.
  9. # The default value is 0, which means MQTT v3.1.1 identification is preferred.
  10. protocolVersion: <int, 0|3|4>
  11. # Specifies the username and password that the client connects
  12. # to the MQTT broker. Without the use of `tlsConfig`,
  13. # the account information will be sent in plaintext across the wire.
  14. basicAuth:
  15. # Specifies the username for basic authentication.
  16. username: <string>
  17. # Specifies the relationship of DeviceLink's references to
  18. # refer to the value as the username.
  19. usernameRef:
  20. # Specifies the name of reference.
  21. # REQUIRED
  22. name: <string>
  23. # Specifies the item name of the referred reference.
  24. # REQUIRED
  25. item: <string>
  26. # Specifies the relationship of DeviceLink's references to refer to the value as the username.
  27. passsword: <string>
  28. # Specifies the relationship of DeviceLink's references to
  29. # refer to the value as the password.
  30. passwordRef:
  31. # Specifies the name of reference.
  32. # REQUIRED
  33. name: <string>
  34. # Specifies the item name of the referred reference.
  35. # REQUIRED
  36. item: <string>
  37. # Specifies the TLS configuration that the client connects to the MQTT broker.
  38. tlsConfig:
  39. # The PEM format content of the CA certificate,
  40. # which is used for validate the server certificate with.
  41. caFilePEM: <string>
  42. # Specifies the relationship of DeviceLink's references to
  43. # refer to the value as the CA file PEM content.
  44. caFilePEMRef:
  45. # Specifies the name of reference.
  46. # REQUIRED
  47. name: <string>
  48. # Specifies the item name of the referred reference.
  49. # REQUIRED
  50. item: <string>
  51. # The PEM format content of the certificate and key,
  52. # which is used for client authenticate to the server.
  53. certFilePEM: <string>
  54. # Specifies the relationship of DeviceLink's references to
  55. # refer to the value as the client certificate file PEM content.
  56. certFilePEMRef:
  57. # Specifies the name of reference.
  58. # REQUIRED
  59. name: <string>
  60. # Specifies the item name of the referred reference.
  61. # REQUIRED
  62. item: <string>
  63. # Specifies the PEM format content of the key(private key),
  64. # which is used for client authenticate to the server.
  65. keyFilePEM: <string>
  66. # Specifies the relationship of DeviceLink's references to
  67. # refer to the value as the client key file PEM content.
  68. keyFilePEMRef:
  69. # Specifies the name of reference.
  70. # REQUIRED
  71. name: <string>
  72. # Specifies the item name of the referred reference.
  73. # REQUIRED
  74. item: <string>
  75. # Indicates the name of the server, ref to http://tools.ietf.org/html/rfc4366#section-3.1.
  76. serverName: <string>
  77. # Doesn't validate the server certificate.
  78. insecureSkipVerify: <bool>
  79. # Specifies setting the "clean session" flag in the connect message that the MQTT broker should not
  80. # save it. Any messages that were going to be sent by this client before disconnecting previously but didn't send upon connecting to the broker.
  81. # The default value is "true".
  82. cleanSession: <bool>
  83. # Specifies to provide message persistence in cases where QoS level is 1 or 2.
  84. # The default store is "memory".
  85. store:
  86. # Specifies the type of storage.
  87. # The default store is "Memory".
  88. type: <string, Memory|File>
  89. # Specifies the directory prefix of the storage, if using file store.
  90. # The default value is "/var/run/octopus/mqtt".
  91. direcotryPrefix: <string>
  92. # Specifies to enable resuming of stored (un)subscribe messages when connecting but not reconnecting.
  93. # This is only valid if `cleanSession` is false.
  94. # The default value is "false".
  95. resumeSubs: <bool>
  96. # Specifies the amount of time that the client try to open a connection
  97. # to an MQTT broker before timing out and getting error.
  98. # A duration of 0 never times out.
  99. # The default value is "30s".
  100. connectionTime: <string>
  101. # Specifies the amount of time that the client should wait
  102. # before sending a PING request to the broker. This will
  103. # allow the client to know that the connection has not been lost
  104. # with the server.
  105. # A duration of 0 never keeps alive.
  106. # The default keep alive is "30s".
  107. keepAlive: <string>
  108. # Specifies the amount of time that the client should wait
  109. # after sending a PING request to the broker. This will
  110. # allow the client to know that the connection has been lost
  111. # with the server.
  112. # A duration of 0 may cause unnecessary timeout error.
  113. # The default value is "10s".
  114. pingTimeout: <string>
  115. # Specifies the message routing to guarantee order within each QoS level. If set to false,
  116. # the message can be delivered asynchronously from the client to the application and
  117. # possibly arrive out of order.
  118. # The default value is "true".
  119. order: <bool>
  120. # Specifies the amount of time that the client publish a message successfully before
  121. # getting a timeout error.
  122. # A duration of 0 never times out.
  123. # The default value is "30s".
  124. writeTimeout: <string>
  125. # Specifies the amount of time that the client should timeout
  126. # after subscribed/published a message.
  127. # A duration of 0 never times out.
  128. waitTimeout: <string>
  129. # Specifies the quiesce when the client disconnects.
  130. # The default value is "5s".
  131. disconnectQuiesce: <string>
  132. # Configures using the automatic reconnection logic.
  133. # The default value is "true".
  134. autoReconnect: <bool>
  135. # Specifies the amount of time that the client should wait
  136. # before reconnecting to the broker. The first reconnect interval is 1 second,
  137. # and then the interval is incremented by *2 until `MaxReconnectInterval` is reached.
  138. # This is only valid if `AutoReconnect` is true.
  139. # A duration of 0 may trigger the reconnection immediately.
  140. # The default value is "10m".
  141. maxReconnectInterval: <string>
  142. # Specifies the size of the internal queue that holds messages
  143. # while the client is temporarily offline, allowing the application to publish
  144. # when the client is reconnected.
  145. # This is only valid if `autoReconnect` is true.
  146. # The default value is "100".
  147. messageChannelDepth: <int>
  148. # Specifies the additional HTTP headers that the client sends in the WebSocket opening handshake.
  149. httpHeaders: <map[string][]string>
  150. # Specifies the message settings.
  151. message:
  152. # Specifies the topic.
  153. # REQUIRED
  154. topic: <string>
  155. # Specifies the will message that the client gives it to the broker,
  156. # which can be published to any clients that are subscribed the provided topic.
  157. will:
  158. # Specifies the topic of will message.
  159. # if not set, the topic will append "$will" to the topic name specified
  160. # in parent field as its topic name.
  161. topic: <string>
  162. # Specifies the content of will message. The serialized form of the content is a
  163. # base64 encoded string, representing the arbitrary (possibly non-string) content value here.
  164. content: <string, base64-encoded>
  165. # Specifies the QoS of the will message.
  166. # 0: Send at most once.
  167. # 1: Send at least once.
  168. # 2: Send exactly once.
  169. # The default value is "1".
  170. qos: <int, 0|1|2>
  171. # Specifies the will message to be retained.
  172. # The default value is "true".
  173. retained: <bool>
  174. # Specifies the path for rendering the `:path` keyword of topic.
  175. path: <string>
  176. # Specifies the operator for rendering the `:operator` keyword of topic.
  177. operator:
  178. # Specifies the operator for rendering the `:operator` keyword of topic during subscribing.
  179. read: <string>
  180. # Specifies the operator for rendering the `:operator` keyword of topic during publishing.
  181. write: <string>

Templated Topic

Octopus 提供了一个templated topic,以适应不同的 MQTT 发布和订阅场景。templated topic 支持的关键词有五个。

  • :namespace,替换 DeviceLink 的命名空间
  • :name,替换为 DeviceLink 的名称
  • :uid,替换为 DeviceLink 的UID
  • :path,替换为自定义路径。
  • :operator,基于操作(read - subscribe, write - publish)进行替换。值得注意的是,read操作在 MQTT 扩展中不支持,但在MQTT 适配器中运行良好。

模板化主题有以下两个特点:

  • 容错的额外分隔符,path. "a///b//c"将被视为path."。"a///b///c"将作为path: "a/b/c"
  • 自动忽略没有内容的关键词。

使用案例

  1. 给定主题cattle.io/octopus/:namespace/device/:name,当 DeviceLink 命名为default/case1

    1. apiVersion: edge.cattle.io/v1alpha1
    2. kind: DeviceLink
    3. metadata:
    4. namespace: default
    5. name: case1
    6. uid: fcd1eb1b-ea42-4cb9-afb0-0ec2d0830583
    7. spec:
    8. ...
    9. template:
    10. ...
    11. spec:
    12. extension:
    13. mqtt:
    14. ...
    15. message:
    16. topic: "cattle.io/octopus/:namespace/device/:name"
    • Publish Topic: cattle.io/octopus/default/device/case1
    • Subscribe Topic: cattle.io/octopus/default/device/case1
  2. 给定主题cattle.io/octopus/device/:uid,当 DeviceLink 命名为default/case2时:

    1. apiVersion: edge.cattle.io/v1alpha1
    2. kind: DeviceLink
    3. metadata:
    4. namespace: default
    5. name: case2
    6. uid: 41478d1e-c3f8-46e3-a3b5-ba251f285277
    7. spec:
    8. ...
    9. template:
    10. ...
    11. spec:
    12. extension:
    13. mqtt:
    14. ...
    15. message:
    16. topic: "cattle.io/octopus/device/:uid"
    • Publish Topic: cattle.io/octopus/device/41478d1e-c3f8-46e3-a3b5-ba251f285277
    • Subscribe Topic: cattle.io/octopus/device/41478d1e-c3f8-46e3-a3b5-ba251f285277

    UID 是 Kubernetes 提供的代表资源的唯一标识,对外没有太多的解读意义。因此,一般情况下不建议使用这个关键字。

  3. 给定主题cattle.io/octopus/:operator/device/:namespace/:name,当 DeviceLink 命名为default/case3时:

    1. apiVersion: edge.cattle.io/v1alpha1
    2. kind: DeviceLink
    3. metadata:
    4. namespace: default
    5. name: case3
    6. uid: 835aea2e-5f80-4d14-88f5-40c4bda41aa3
    7. spec:
    8. ...
    9. template:
    10. ...
    11. spec:
    12. extension:
    13. mqtt:
    14. ...
    15. message:
    16. topic: "cattle.io/octopus/:operator/device/:namespace/:name"
    17. operator:
    18. write: "set"
    • Publish Topic: cattle.io/octopus/set/device/default/case3
    • Subscribe Topic: cattle.io/octopus/device/default/case3
  4. 给定主题cattle.io/octopus/:operator/device/:path/:uid,当 DeviceLink 命名为default/case4时。

    1. apiVersion: edge.cattle.io/v1alpha1
    2. kind: DeviceLink
    3. metadata:
    4. namespace: default
    5. name: case4
    6. uid: 014997f5-1f12-498b-8631-d2f22920e20a
    7. spec:
    8. ...
    9. template:
    10. ...
    11. spec:
    12. extension:
    13. mqtt:
    14. ...
    15. message:
    16. topic: "cattle.io/octopus/:operator/device/:path/:uid"
    17. operator:
    18. read: "status"
    19. path: "region/ap"
    • Publish Topic: cattle.io/octopus/device/region/ap/014997f5-1f12-498b-8631-d2f22920e20a
    • Subscribe Topic: cattle.io/octopus/status/device/region/ap/014997f5-1f12-498b-8631-d2f22920e20a

可用适配器列表