asyncapi: 3.0.0
info:
  title: CoreCharge Cabinet Protocol v1.51 MQTT Contract
  version: 1.51.0
  description: >-
    Public protocol semantics for CoreCharge-compatible shared power bank cabinets.
    The server entry is non-operational and uses a reserved hostname; request an
    authorized production connectivity profile separately.
  tags:
    - name: cabinet-protocol
      description: Public device integration contract.
    - name: synthetic-examples
      description: All examples use non-production identifiers.
servers:
  integration-placeholder:
    host: mqtt.example.invalid
    protocol: mqtts
    description: Reserved non-operational hostname. Replace only in an authorized profile.
channels:
  deviceDownlink:
    address: /{ProductKey}/{DeviceName}/user/get
    description: Commands sent by the server and subscribed to by the cabinet.
    parameters:
      ProductKey:
        $ref: '#/components/parameters/ProductKey'
      DeviceName:
        $ref: '#/components/parameters/DeviceName'
    messages:
      cabinetDownlinkFrame:
        $ref: '#/components/messages/CabinetDownlinkFrame'
  deviceUplink:
    address: /{ProductKey}/{DeviceName}/user/update
    description: Reports published by the cabinet and consumed by the server.
    parameters:
      ProductKey:
        $ref: '#/components/parameters/ProductKey'
      DeviceName:
        $ref: '#/components/parameters/DeviceName'
    messages:
      cabinetUplinkFrame:
        $ref: '#/components/messages/CabinetUplinkFrame'
operations:
  sendCabinetCommand:
    action: send
    channel:
      $ref: '#/channels/deviceDownlink'
    summary: Send a v1.51 downlink frame.
    messages:
      - $ref: '#/channels/deviceDownlink/messages/cabinetDownlinkFrame'
  receiveCabinetReport:
    action: receive
    channel:
      $ref: '#/channels/deviceUplink'
    summary: Receive a v1.51 uplink frame.
    messages:
      - $ref: '#/channels/deviceUplink/messages/cabinetUplinkFrame'
components:
  parameters:
    ProductKey:
      description: Topic namespace assigned by the authorized connectivity profile.
    DeviceName:
      description: Device name assigned by the authorized connectivity profile.
  messages:
    CabinetDownlinkFrame:
      name: CabinetDownlinkFrame
      title: Server-to-cabinet ASCII frame
      summary: CN acknowledgement or CS/GN/CQ/CM/CC/BW/KW/FB/BR/RS/FA/FL/OT/SQ/NI command.
      contentType: text/plain
      payload:
        $ref: '#/components/schemas/ProtocolFrame'
      examples:
        - name: synthetic-all-slot-query
          payload: '{CQ,17000000,0,6F75}'
    CabinetUplinkFrame:
      name: CabinetUplinkFrame
      title: Cabinet-to-server ASCII frame
      summary: CN/CS/GN/DS/AC/CQ/AE/CM/CC/BW/KW/FB/RS/FR/FA/FL/OT/SQ/NI/KU report.
      contentType: text/plain
      payload:
        $ref: '#/components/schemas/ProtocolFrame'
      examples:
        - name: synthetic-return
          payload: '{RS,17000007,DEVICE-000001,1,2,PB-000001,88,1,1,D1B9}'
  schemas:
    ProtocolFrame:
      type: string
      pattern: '^\\{[A-Z]{2}(?:,[ -~]*)?,[0-9A-F]{4}\\}$'
      description: >-
        ASCII frame using {COMMAND,field1,...,CRC}. Field count and semantics are
        command-specific; see protocol-v1.51-command-catalog.json. CRC uses the
        authorized PW suffix, which is not sent in the frame.
      examples:
        - '{CQ,17000000,0,6F75}'
