适配器设计

Octopus 诞生时就考虑到了可伸缩性的必要,这种能力体现在设备模型和适配器的设计中。

由于可以通过 CRD 定义设备模型,因此设备模型可以是专用设备(例如风扇,LED 等),也可以是通用协议设备(例如 BLE,ModBus,OPC-UA 设备等)。

  1. ┌──────────────────────┐
  2. MideaAirPurifier #专用设备
  3. └──────────────────────┘
  4. ┌──────────────────────┐
  5. MideaAirConditioning #专用设备
  6. └──────────────────────┘
  7. ┌──────────────────────┐
  8. XiaoMiAirPurifier #专用设备
  9. └──────────────────────┘
  10. ╔══════════════════════╗
  11. Bluetooth #通用协议设备
  12. ╚══════════════════════╝
  13. ╔══════════════════════╗
  14. Modbus #通用协议设备
  15. ╚══════════════════════╝
  16. ╔══════════════════════╗
  17. OPC-UA #通用协议设备
  18. ╚══════════════════════╝

同时,适配器的实现可以连接到单个设备或多个设备:

  1. ┌──────────────────────┐
  2. ┌──────────│ MideaAirPurifier │──────────┐
  3. └──────────────────────┘
  4. . ┌──────────────────────┐ .
  5. ( )◀────────┤ MideaAirConditioning │──────────┴─────────▶( )
  6. ' │ └──────────────────────┘ '
  7. adaptors.smarthome.io/airpurifier adaptors.media.io/smarthome
  8. ┌──────────────────────┐
  9. └──────────│ XiaoMiAirPurifier │──────────┐
  10. └──────────────────────┘
  11. ┌──────────────────────┐ .
  12. XiaoMiWeighingScale │──────────┴──────────▶( )
  13. └──────────────────────┘ '
  14. adaptors.xiaomi.io/smarthome
  15. . ╔══════════════════════╗
  16. ( )◀═══════════════════║ Bluetooth ║
  17. ' ╚══════════════════════╝
  18. adaptors.edge.cattle.io/ble
  19. ╔══════════════════════╗ .
  20. Modbus ║═════════════════════▶( )
  21. ╚══════════════════════╝ '
  22. adaptors.edge.cattle.io/modbus

请在此处查看有关开发适配器的更多详细信息。

适配器 APIs

适配器的访问管理借鉴了Kubernetes 设备插件管理。 当前访问管理 API 的可用版本为v1alpha1

VersionsAvailableCurrent
v1alpha1

使用以下步骤使适配器与limb交互:

  1. limb在主机路径上启动带有 Unix socket 的 gRPC 服务,以接收来自适配器的注册请求:

    1. // Registration is the service advertised by the Limb,
    2. // any adaptor start its service until Limb approved this register request.
    3. service Registration {
    4. // Register is used to register the adaptor with limb.
    5. rpc Register (RegisterRequest) returns (Empty) {}
    6. }
    7. message RegisterRequest {
    8. // Name of the adaptor in the form `adaptor-vendor.com/adaptor-name`.
    9. string name = 1;
    10. // Version of the API the adaptor was built against.
    11. string version = 2;
    12. // Name of the unix socket the adaptor is listening on, it's in the form `*.sock`.
    13. string endpoint = 3;
    14. }
  2. 适配器使用主机路径/var/lib/octopus/adaptors下的 Unix socket 启动 gRPC 服务,该服务实现以下接口:

    1. // Connection is the service advertised by the adaptor.
    2. service Connection {
    3. rpc Connect (stream ConnectRequest) returns (stream ConnectResponse) {}
    4. }
    5. message ConnectRequestReferenceEntry {
    6. map<string, bytes> items = 1;
    7. }
    8. // ConnectRequest is the request used during connection
    9. // and is used to send desired device data to an adaptor.
    10. message ConnectRequest {
    11. // Model for the device.
    12. k8s.io.apimachinery.pkg.apis.meta.v1.TypeMeta model = 1;
    13. // Desired device, it's in form JSON bytes.
    14. bytes device = 2;
    15. // References for the device, i.e: Secret, ConfigMap and Downward API.
    16. map<string, ConnectRequestReferenceEntry> references = 3;
    17. }
    18. // ConnectResponse is the response used during connection
    19. // and is used to return observed device data to the limb.
    20. message ConnectResponse {
    21. // Observed device, it's in form JSON bytes.
    22. bytes device = 1;
    23. // The unhandled error message indicates that the connection cannot be interrupted
    24. // and the user needs to choose to recreate or ignore it.
    25. string errorMessage = 2;
    26. }
  3. 适配器通过 Unix socket 旨在主机路径/var/lib/octopus/adaptors/limb.sock处向limb注册。

  4. 成功注册后,适配器以服务模式运行,在此模式下,适配器将保持连接设备的状态,并在设备状态发生任何变化时向limb报告。

关于注册

注册 可以让limb发现适配器的存在,在这一阶段,limb充当服务器,而适配器充当客户端。适配器使用其名称,版本和访问端点构造一个注册请求,然后请求肢体。成功注册后,limb将继续监视适配器并通知与已注册适配器相关的那些 DeviceLink。

  • 名称是适配器的名称,强烈建议使用此模式adaptor-vendor.com/adaptor-name来命名适配器,每个适配器必须具有一个唯一的名称。如果两个适配器具有相同名称,新创建的适配器将覆盖已有的适配器。
  • 版本是访问管理的 API 版本,目前已在 v1alpha1 中修复。
  • 访问的“端点”是 UNIX 套接字的名称,每个适配器必须具有一个唯一的“端点”。如果两个适配器具有相同注册端点,在退出前一个适配器之前,第二个适配器不会成功注册。

关于链接

链接可以让limb连接到适配器,在此阶段,适配器充当服务器,而limb充当客户端。 limb使用 modeldevicereferences构造连接请求,然后向目标适配器发出请求。

  • model 是设备的模型,有助于适配器区分多个模型,或者在一个模型中存在不同版本时保持兼容性非常有用。
  • device 是设备的实例,格式为 JSON 字节,是完整的model 实例的JSON字节,并包含specstatus数据。

    适配器应根据model选择相应的反序列化接收对象,以接收该字段的数据。 由于接收对象(设备实例)是合法的 CRD 实例,因此它严格遵守 Kubernetes 的资源管理约定,因此可以通过命名空间和名称唯一地标识设备。

  • references 是设备的参考源,它允许设备在相同的名称空间或父DeviceLink实例的向下API下使用ConfigMapSecret

可用适配器列表