<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.1 (Ruby 2.6.10) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

<!ENTITY RFC7644 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7644.xml">
<!ENTITY I-D.ietf-scim-device-model SYSTEM "https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-scim-device-model.xml">
<!ENTITY RFC2119 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC8174 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
<!ENTITY I-D.ietf-asdf-sdf SYSTEM "https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-asdf-sdf.xml">
<!ENTITY RFC9114 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9114.xml">
<!ENTITY RFC8949 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8949.xml">
<!ENTITY RFC8610 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8610.xml">
<!ENTITY RFC8126 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml">
]>


<rfc ipr="trust200902" docName="draft-ietf-asdf-nipc-03" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="NIPC">An Application Layer Interface for Non-IP device control (NIPC)</title>

    <author initials="B." surname="Brinckman" fullname="Bart Brinckman">
      <organization>Cisco Systems</organization>
      <address>
        <postal>
          <city>Brussels</city>
          <country>Belgium</country>
        </postal>
        <email>bbrinckm@cisco.com</email>
      </address>
    </author>
    <author initials="R." surname="Mohan" fullname="Rohit Mohan">
      <organization>Cisco Systems</organization>
      <address>
        <postal>
          <street>170 West Tasman Drive</street>
          <city>San Jose</city>
          <code>95134</code>
          <country>USA</country>
        </postal>
        <email>rohitmo@cisco.com</email>
      </address>
    </author>
    <author initials="B." surname="Sanford" fullname="Braeden Sanford">
      <organization>Philips</organization>
      <address>
        <postal>
          <city>Cambridge</city>
          <country>USA</country>
        </postal>
        <email>braeden.sanford@philips.com</email>
      </address>
    </author>

    <date year="2024" month="October" day="21"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 54?>

<t>This memo specifies RESTful application layer interface for gateways 
providing operations against non-IP devices. The described interface is
extensible. This memo initially describes Bluetooth Low Energy and 
Zigbee as they are the most commonly deployed.</t>



    </abstract>



  </front>

  <middle>


<?line 61?>

<section anchor="introduction"><name>Introduction</name>

<section anchor="scope"><name>Scope</name>

<t>Low-power sensors, actuators and other connected devices introduced in
environments and use cases such as building management, healthcare, workplaces,
manufacturing, logistics and hospitality are often battery-powered. Often they
do not support wireless of wired interfaces that support the IP protocol.
Most of these environments however mainly support IP-based networking
infrastructure. Therefore, applications on the IP network that aim to
communicate or receive telemetry from these non-IP low-power devices must do
so through a gateway function on the IP network. This gateway functions then 
translates the communication to the non-IP protocol that the low-power device 
supports. Promiment examples of such protocols are <xref target="BLE53"/> and <xref target="Zigbee22"/>.</t>

<figure title="Gateway for non-IP Devices" anchor="gw"><artwork><![CDATA[
                                                               
    +-------------+              +---------+              +--------+
    | Application |<------------>| Gateway |<------------>| Non-IP |                     
    |    app      |   IP-based   |         |    Non-IP    | Device |
    +-------------+   Operation  +---------+   Operation  +--------+                 

]]></artwork></figure>

<t>There have been efforts to define Gateway functions for devices that support
a particular protocol, such as a BLE GATT REST API for BLE Gateways
(<eref target="https://www.bluetooth.com/bluetooth-resources/gatt-rest-api/"/>), however 
they have been limited to a single protocol or a particular use case. In
absence of an open standard describing how applications on an IP network
communicate with non-IP devices, bespoke and vendors specifia implementations
have proliferated. This results in parallel infrastructure of both gateways 
and non-IP networks being deployed on a case by case basis, each connecting
separately into the IP network, with a distinct set of APIs. At the same time,
wireless access points supporting IP-based wireless connectivity are deployed
ubiquitiously. Many of these wireless access points are equipped with multiple
wireless radios, of different types. These radios can transmit and receive
different frame types, such as <xref target="BLE53"/> and <xref target="Zigbee22"/>. This specification
aims to define a Gateway API for these Non-IP protocols that can be leveraged
by this wireless infrastructure in order to connect Non-IP devices into IP
networks.</t>

<t>A standardized Non-IP Gateway interface has following benefits:</t>

<t><list style="symbols">
  <t>Avoid the need for parallel Non-IP infrastructure.</t>
  <t>Avoid the need for applications to perform bespoke integrations for
different environments.</t>
  <t>Faster and more cost-effective adoption of Non-IP devices in IP network
environments.</t>
</list></t>

</section>
<section anchor="non-ip-gateway-functions"><name>Non-IP Gateway functions</name>

<t>A non-IP gateway MUST provide at least following functions:</t>

<t><list style="symbols">
  <t>Authentication and authorization of application clients that
will leverage the gateway API to communicate with Non-IP devices.</t>
  <t>The ability to onboard Non-IP devices on the Non-IP Gateway. Onboarding 
ensures that the Non-IP Gateway can identify a device and has sufficient
context about the device to service gateway API requests. It also ensures
segmentation of devices that were onboarded by particular applications.</t>
  <t>A persistent inventory of onboarded devices  mapping to the application
that onboarded them and the access point/radio that is serving them.</t>
  <t>An API that allows for bi-directional communication to non-IP devices.</t>
  <t>One or more channels to process requests, responses, and asymmetric
communications with the non-IP radio resources (Access Points)
in its inventory.</t>
  <t>The ability to stream telemetry received from non-IP devices in real-time
to applications on the IP network.</t>
</list></t>

<t>The onboarding function is out of scope of this document, but can be provided
by a provisioning interface such as <xref target="RFC7644"/> leveraging 
<xref target="I-D.ietf-scim-device-model"/>. All other defined functions are
supported by Non IP-Control (NIPC).</t>

<t>The Application gateway is a network functions, so its goal is to proxy payloads 
between Non-IP and IP networks. It is not intended to be a middleware functioni
that interprets, decodes or modifies these payloads.</t>

<figure title="Basic Architecture" anchor="arch"><artwork><![CDATA[
                            +-----------------------------------+
                            |                                   |
    +-----------+   Request |  +---------+                      |
    | onboarding|------------->|  SCIM   |                      |
    |    app    |<-------------| Server  |                      |
    +-----------+  Ctrl Endpt  +---------+                      |
                            |                                   |
    +-----------+           |  +------------+  +-------+  +--+  |
    |  Control  |>...REST...|.>|            |..|  AP   |..|D |  |
    |     &     |           |  |   Gateway  |  +-------+  +--+  |
    | Telemetry |<...MQTT...|.<|            |                   |
    |    Apps   |           |  +------------+                   |
    +-----------+           |                                   |
                            |       Network Deployment          |
                            +-----------------------------------+

]]></artwork></figure>

<t><xref target="arch"/> shows us applications, the application layer gateway (ALG),
an access point (AP), and a device (D). The applications, application layer
gateway and access point are deployed on an IP-Network. The AP also has a
Non-IP interface, which it uses to communicate with the device.
The Application is deployed in a different administrative domain than the
network elements (ALG &amp; AP).
The role of the ALG is to provide a gateway function to applications wishing
to communicate with non-IP devices in the network domain served by the ALG.
Applications implementing Non-IP Control can leverage RESTful interfaces
to communicate with Non-IP devices in the network domain and subscribe to
events levering MQTT.</t>

</section>
<section anchor="interaction-flow"><name>Interaction flow</name>

<t>In order to enable a network wishing to offer NIPC ALG functions, the network
administrator authorizes application(s) to perform operations on the Gateway.
This happens out of band and may be accomplished by means of exchanging tokens
or public keys.
Authorization can be role-based. The 3 primary roles are:</t>

<t><list style="numbers">
  <t>Onboarding: Authorize an onboarding application against a SCIM server
co-located with the gateway.</t>
  <t>Control: Authorize applications that may control devices.</t>
  <t>Data: Authorize applications that may receive telemetry.<br />
It is possible to further refine roles down to an API basis.</t>
</list></t>

<t>Applications can perform the API requests they were authorized for.
In order for application to perform a NIPC operation on a device, the device
must be first onboarded, for example by means of SCIM.</t>

<t>Previous steps are prerequisites and not within the scope of this specification, 
but are provided for context.i Subsequent operations are defined by NIPC.</t>

<t><list style="numbers">
  <t>An application authorized for Control can perform NIPC calls to the
gateway in order to establish bi-directional communication to one or more
devices. Optionally, also set up a publish/subcribe topic to receive
streaming data from a device (telemetry interface).</t>
  <t>An application authorized can receive streaming data on a pub/sub 
topic configured by the control interface (telemetry interface).</t>
</list></t>

</section>
<section anchor="terminology"><name>Terminology</name>

<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all
capitals, as shown here.</t>

</section>
</section>
<section anchor="architecture"><name>Architecture</name>

<section anchor="overview"><name>Overview</name>

<t>Non-IP protocols, such as BLE or Zigbee, typically define a number of basic
operations that are similar across protocols. Examples of this are read and 
write data. NIPC leverages a unified API to support those operations.</t>

<t>NIPC defines actions, which are implemented as REST over HTTP request-response
APIs. NIPC Also defines events, which are implemented as MQTT topics.</t>

<t>In case NIPC is not leveraged in combination with a data model such as ASDF
<xref target="I-D.ietf-asdf-sdf"/>, which can define the properties of a devices,
NIPC also support registrationsr. REgistrations perform mapping of 
properties to protocol-specific attributes.</t>

<t>All operations pertain to a devices or a group of devices, which are addressed
by UUIDs. These UUID's were generated at time of onboarding and returned to 
the application, for example in a SCIM response.</t>

</section>
<section anchor="nipc-operations"><name>NIPC Operations</name>

<t>NIPC adheres to nomenclature defined by Semantic Definition Format (SDF) for
Data and Interactions of Things <xref target="I-D.ietf-asdf-sdf"/>. Therefore NIPC
defines actions and events on properties.</t>

<section anchor="actions"><name>Actions</name>

<t>NIPC supports 3 types of actions:</t>

<t><list style="symbols">
  <t>connection: Allows an application to establish to manage connections with
a device (if so required by the technology).</t>
  <t>property: Allows applications to read or write device properties. In case
the property supports streaming data, a subscription property can be
managed.</t>
  <t>broadcast: This allows the application to send a broadcast message to a
device or group of devices.</t>
</list></t>

</section>
<section anchor="registrations"><name>Registrations</name>

<t>In absence of a model such as SDF that defines device properties, NIPC allows
an application to register them. NIPC defines 2 types of registrations:</t>

<t><list style="symbols">
  <t>property: Manage registrations of properties and their protocol mappings.
For example, a property called temperature can be mapped to a BLE Service
Characteristic.</t>
  <t>event: Manage registrations of events and their MQTT properties such as 
MQTT topic definition.</t>
</list></t>

</section>
<section anchor="extensions"><name>Extensions</name>

<t>The final set of operations are not fundamental NIPC operations, but are
extensions. Extensions are compound API's. They leverage basic NIPC operations
but combine multiple operations in to one API call for efficiency.
An example of this is the the bulk operation, allowing to send multiple
operations is one operation. extension allows for extensions, either generic
extensions that anre IANA registered, or vendor specific extensions</t>

</section>
<section anchor="events"><name>Events</name>

<t>Events are published over MQTT. Events can be normal sreaming data, but also
broadcasts or connection events.</t>

</section>
</section>
<section anchor="protocols"><name>Protocols</name>

<t>NIPC actions, registrations and extensions are request/response APIs. They makes
use of a JSON schema over RESTful HTTP<xref target="RFC9114"/>.</t>

<t>NIPC events are encoded in CBOR (<xref target="RFC8949"/>) and delivered over MQTT.</t>

</section>
<section anchor="schema"><name>Schema</name>

<section anchor="device-schema"><name>Device schema</name>

<t>Most operations (except registations) are executed against a device or a group.
NIPC operations refer to either of these as "Object" with an ID as an
identifier. The common schema for Object is defined as follows:</t>

<texttable title="Definition of an Object" anchor="objectdef">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>id</c>
      <c>T</c>
      <c>uuid</c>
      <c>12345678-1234-5678-1234-56789abcdef4</c>
      <c>type</c>
      <c>T</c>
      <c>enum</c>
      <c>device, group</c>
      <c>technology</c>
      <c>F</c>
      <c>enum</c>
      <c>ble, zigbee</c>
</texttable>

<t>where-</t>

<t><list style="symbols">
  <t>id is the unique uuid of the device. This is generated when registering
the device, for example against a SCIM server. As such this ID is known
both to the application as well as the NIPC Server.</t>
  <t>type is either "group" or "device".</t>
  <t>technology is the radio technology supported by the device. The mappings
defined in this spec are "ble" or "zigbee". Mappings are extendable to 
new technologies.</t>
</list></t>

<t>Example device object:</t>

<figure title="Example device object" anchor="exdevobj"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "technology": "ble",
}
]]></artwork></figure>

</section>
<section anchor="propertymap"><name>Property mapping</name>

<t>An object can support one or more communications protocols. Even though Non-IP
communications protocols all perform operations on properties, implementations
differ between protocols. For example BLE will address a property as a service
characteristic, while a property in Zigbee is addressed as a property in a 
cluster of an endpoint.</t>

<t>In order for NIPC to support protocol-agnostic APIs, a property mapping is
required between a NIPC property and a protocol-specific property. A property
mapping can be done by means of a property registration API.</t>

<t>Property mapping allows for integration of new protocols in NIPC, new mappings 
can be created without the need to update the base schema.</t>

<figure title="Property Mapping" anchor="propmap"><artwork><![CDATA[
     - property
        |
        |> BLE
        |     - BLE property
        |
        |> Zigbee
              - Zigbee property

]]></artwork></figure>

<t>As shown in <xref target="propmap"/>, protocol-specific properties must be described in a
protocol object, for example a "ble" or a "zigbee" object.</t>

<texttable title="Protocol objects" anchor="proobj">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>ble</c>
      <c>T</c>
      <c>object</c>
      <c>an object with BLE-specific attributes</c>
      <c>zigbee</c>
      <c>T</c>
      <c>object</c>
      <c>an object with Zigbee-specific attributes</c>
</texttable>

<t>where-</t>

<t><list style="symbols">
  <t>"ble" is an object containing properties that are specific to the BLE
protocol.</t>
  <t>"zigbee" is an object containing properties that are specific to the
Zigbee protocol.</t>
  <t>Other protocol mapping objects can be added by creating a new protocol
object</t>
</list></t>

<t>Example property mapping:</t>

<figure title="Example property mapping" anchor="expropmap"><artwork><![CDATA[
{
  "propertyID": "temperature",
  "ble": {
    "serviceID": "12345678-1234-5678-1234-56789abcdef4",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
    "long": false
  }
}
]]></artwork></figure>

<t>Protocol mapping allows applications to perform a one-time registration to
a propertyID for a property, and leverage the propertyID in all API calls 
that perform an operation on this property. It might be useful for applications
to directly use protocol objects in action API's as well, therefore there are 
a limited set of API's avaialbe that have protocol objects directly embedded 
in the API, in ordur to perform operations on properties without having to 
first register them.</t>

</section>
<section anchor="response"><name>Response</name>

<t>As most operations have a common base schema, based on a device ID and a
property, so do responses. Every NIPC API returns a status in the response, as
well as a requestID, which allows for tracking and logging of requests and 
responses. If the operation was performed on a device or group, the ID is also
returned. If the operation is to read or write a property, the resulting value
is also returned.</t>

<t>Success response:</t>

<texttable title="Success response" anchor="success">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>status</c>
      <c>T</c>
      <c>enum</c>
      <c>SUCCESS</c>
      <c>id</c>
      <c>F</c>
      <c>uuid</c>
      <c>12345678-1234-5678-1234-56789abcdef4</c>
      <c>requestID</c>
      <c>F</c>
      <c>uuid</c>
      <c>abcd0987-1234-5678-1234-56789abcdef4</c>
</texttable>

<t>Example success response:</t>

<figure title="Example success response" anchor="exsuccess"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
}
]]></artwork></figure>

<t>Failure responses additionally include an error code and optionally a reason,
which contains a textual explanation of the error.</t>

<t>Failure response:</t>

<texttable title="Failure response" anchor="failure">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>status</c>
      <c>T</c>
      <c>enum</c>
      <c>SUCCESS</c>
      <c>id</c>
      <c>F</c>
      <c>uuid</c>
      <c>12345678-1234-5678-1234-56789abcdef4</c>
      <c>requestID</c>
      <c>F</c>
      <c>uuid</c>
      <c>abcd0987-1234-5678-1234-56789abcdef4</c>
      <c>errorCode</c>
      <c>T</c>
      <c>int</c>
      <c>12</c>
      <c>reason</c>
      <c>T</c>
      <c>string</c>
      <c>"Not Found"</c>
</texttable>

<t>where-</t>

<t><list style="symbols">
  <t>status is the status of the request, either "SUCCESS" or "FAILURE". 
In case of failure an error code and reason are added.</t>
  <t>id is the id the operation was executed against, found in the request</t>
  <t>requestID is a correlation ID that can be used for end-to-end 
tracing.</t>
  <t>errorCode is a numerical value representing the error.</t>
  <t>reason is a human readable explanation of why the error occurred.</t>
</list></t>

<t>Example failure response:</t>

<figure title="Example failure response" anchor="exfail"><artwork><![CDATA[
{
  "status": "FAILURE",
  "reason": "Not Found",
  "errorCode": 12,
  "requestID": "12345678-5678-1234-5578-abcdef1234"
}
]]></artwork></figure>

</section>
</section>
</section>
<section anchor="nipc-actions"><name>NIPC Actions</name>

<t>The primary goal of NIPC actions is to exchange data with a Non-IP device, by
means of reading, writing or streaming NIPC properties to applications. An
explicit connection may be required, which is also an action. An application
may also want to transmit a broadcast.</t>

<section anchor="connections"><name>Connections</name>

<t>A connection is an operation that establishes or tears down an association or
connection with a device. Optionally during connection setup properties 
supported by a device can be discovered.</t>

<t>/action/connection</t>

<t>The connection API allows an application to request to connect to 
a device.</t>

<t>Operations:</t>

<t><list style="symbols">
  <t>Connect to a device: POST</t>
  <t>Return active connections: GET</t>
  <t>Disconnect a device: DELETE</t>
</list></t>

<section anchor="connection-api"><name>Connection API</name>

<section anchor="connect"><name>Connect to a device</name>

<t>Method: POST /action/connection</t>

<t>Description: Connect to a device</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>an Object, as defined in <xref target="objectdef"/></t>
  <t>optionally a set of properties to be discovered. These are supplied
in protocol objects, as defined in <xref target="proobj"/>.
In the case of BLE, if no protocol object is included, service discovery is 
performed to discover all supported properties when connecting to
a device. Optionally, service discovery may be limited to properties 
defined in the "ble" protocol extension. The services to be 
discovered can be added in an array. Property discover can be buffered
across connections, so the API also supports caching parameters.</t>
  <t>Connection retry parameters</t>
</list></t>

<t>Example body of a connection without specific discovery of properties:</t>

<figure title="Example Connection" anchor="exconn"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "technology": "ble",
  "retries": 3,
  "retryMultipleAPs": true
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "type" and "technology" are part of the object definition (device
or group), as defined in <xref target="objectdef"/>.</t>
  <t>"retries" defines the number of retries in case the operations does not 
succeed</t>
  <t>"retryMultipleAPs" can be used in case there is an infrastructure with 
multiple access points or radios that can reach the device. If set to "true"
a different access point may be used for retries.</t>
</list></t>

<t>In case the application would like to discover specific properties of a device,
a protocol object can be added that defines what properties should be
discovered.</t>

<t>Example body of a BLE connection with specific discovery of properties:</t>

<figure title="Example Connection with explicit discovery of connections" anchor="exconnprp"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "technology": "ble",
  "ble": {
    "services": [
      {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4"
      }
    ],
    "cached": false,
    "cacheIdlePurge": 3600,
    "autoUpdate": true,
    "bonding": "default"
  },
  "retries": 3,
  "retryMultipleAPs": true
}
]]></artwork></figure>

<t>where in the BLE protocol object:</t>

<t><list style="symbols">
  <t>"services" is an array of services defined by their serviceIDs.</t>
  <t>"cached" refers to whether the services need to be cached for 
subsequent connects, in order not to perform service discovery on
each request.</t>
  <t>"cacheIdlepurge" defines how long the cache should be maintained 
before purging</t>
  <t>some devices support notifications on changes in services, 
"autoUpdate" allows the network to update services based on 
notification (on by default)</t>
  <t>"bonding" allows you to override the bonding method configured when 
onboarding the device</t>
</list></t>

<t>Response: 
Success responses include standard success response properties
as defined in <xref target="success"/> as well as a protocol object with an array of 
discovered properties, as defined in the specific protocol.
For example, for BLE, this is an array of supported services, which in turn
contains an array of charateristics, which in turn contains an array of
descriptors, as shown in <xref target="BLEservices"/>.</t>

<figure title="BLE Services" anchor="BLEservices"><artwork><![CDATA[
    services
     - serviceID
        |
        |> characteristics
            - charactericID
            - flags
               |
               |> Descriptors
                   - descriptorID
]]></artwork></figure>

<t>Example of a BLE connection response with BLE discovered properties:</t>

<figure title="Example Connection response" anchor="exconnresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "ble": [
    {
      "serviceID": "12345678-1234-5678-1234-56789abcdef4",
      "characteristics": [
        {
          "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
          "flags": [
            "read",
            "write"
          ],
          "descriptors": [
            {
              "descriptorID": "12345678-1234-5678-1234-56789abcdef4"
            }
          ]
        }
      ]
    }
  ]
}
]]></artwork></figure>

<t>where in the BLE protocol object:</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of hte standard <xref target="success"/> definition</t>
  <t>"ble" protocol object conatins an Array of BLE services as shown in
<xref target="BLEservices"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="return-active-connections"><name>Return active connections</name>

<t>Method: GET /action/connection</t>

<t>Description: Returns one or more active connections, based on ids 
provided in parameters (none = return all connections).</t>

<t>Parameters, in query: 
One of following options-</t>

<t><list style="symbols">
  <t>None: return all active connections for this application</t>
  <t>single id: return connection status for this id</t>
  <t>comma separated ids: return connection status for multiple ids</t>
</list></t>

<t>Response: 
A standard success (<xref target="exsuccess"/>)i or failure (<xref target="exfail"/>) response, including
an array of device objects and their connection status. Success if the device
is connected, failure if the device is not connected.</t>

<t>Example get connection response:</t>

<figure title="Example Connection response" anchor="exgetresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "connections": [
    {
      "status": "SUCCESS",
      "requestID": "12345678-5678-1234-5578-abcdef1234",
      "id": "12345678-1234-5678-1234-56789abcdef4"
    },
    {
      "status": "FAILURE",
      "reason": "Not Found",
      "errorCode": 12,
      "requestID": "12345678-5678-1234-5578-abcdef1234"
    }
  ]
}
]]></artwork></figure>

<t>In this example, status of 2 connections was requested. The request was
successfully executed, 1 of the 2 connections was found active, the other
one not.</t>

</section>
<section anchor="disconnect-a-device"><name>Disconnect a device</name>

<t>Method: DELETE /action/connection</t>

<t>Description: Disconnect one or more devices, based on ids provided in
parameters</t>

<t>Parameters, in query: 
One of following options-</t>

<t><list style="symbols">
  <t>None: Disconnect all devices for connections this application made</t>
  <t>single id: disconnect device with id</t>
  <t>comma separated ids: disconnect multiple devices with ids</t>
</list></t>

<t>Response: 
The response for the DELETE function is the same as the response for the GET
function. See <xref target="exsuccess"/> for success response, and <xref target="exconnresp"/> for failed
responses.</t>

</section>
</section>
</section>
<section anchor="properties"><name>Properties</name>

<t>Property APIs allow applictions to read and write property values from/to
devices.</t>

<t>/action/property</t>

<t>Operations:</t>

<t><list style="symbols">
  <t>Write value: POST</t>
  <t>Update value: PUT</t>
  <t>Read value: GET</t>
  <t>Delete value: DELETE</t>
</list></t>

<section anchor="property-api"><name>Property API</name>

<section anchor="write"><name>Writing a value</name>

<t>Method: POST /action/property/</t>

<t>Description: Writes a value to a property</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>an Object, as defined in <xref target="objectdef"/></t>
  <t>A propertyID to write to</t>
  <t>A value to be written</t>
  <t>optional parameters</t>
</list></t>

<t>Example body writing a property:</t>

<figure title="Example writing a property" anchor="exwrite"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "technology": "ble",
  "propertyID": "temperature",
  "value": "1",
  "forcedResponse": true
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "type" and "technology" are part of the object definition (device
or group), as defined in <xref target="objectdef"/></t>
  <t>"propertyID" is the ID of a previously registered property mapping</t>
  <t>"value" is the value to be written</t>
  <t>"forcedresponse" requests a specific response behavior of the device
that is not the default</t>
</list></t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as the propertyID and the value written.</t>

<t>Example of a write property response:</t>

<figure title="Example write property response" anchor="exwrresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "propertyID": "temperature",
  "value": "1"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/> definition</t>
  <t>"propertyID" is the ID of a previously registered property mapping</t>
  <t>"value" is the value to be written</t>
  <t>"propertyID" is the proper</t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="update"><name>Updating a value</name>

<t>Method: PUT /action/property</t>

<t>Description: Updates a value of a property</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>an Object, as defined in <xref target="objectdef"/></t>
  <t>A propertyID to write to</t>
  <t>A value to be written</t>
  <t>optional parameters</t>
</list></t>

<t>Example body updating a property:</t>

<figure title="Example updating a property" anchor="exupd"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "technology": "ble",
  "propertyID": "temperature",
  "value": "1",
  "forcedResponse": true
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "type" and "technology" are part of the object definition (device
or group), as defined in <xref target="objectdef"/></t>
  <t>"propertyID" is the ID of a previously registered property mapping</t>
  <t>"value" is the value to be updated</t>
  <t>"forcedresponse" requests a specific response behavior of the device
that is not the default</t>
</list></t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as the propertyID and the value updated.</t>

<t>Example of a write property response:</t>

<figure title="Example update property response" anchor="exupresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "propertyID": "temperature",
  "value": "1"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/> definition</t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="read-a-property"><name>Read a property</name>

<t>Method: GET /action/property/{property}</t>

<t>Description: Read a property from a device</t>

<t>Parameters, in path: 
A propertyID {property} that needs to be read.</t>

<t>Parameters, in query: 
An id of a device on which the property has to be read.</t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as the propertyID and the value read.</t>

<t>Example of a read property response:</t>

<figure title="Example read property response" anchor="exreresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",                   
  "id": "12345678-1234-5678-1234-56789abcdef4",                        
  "propertyID": "temperature",
  "value": "1"
}
]]></artwork></figure>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="delete-a-property-value"><name>Delete a property value</name>

<t>Method: DELETE /action/property/{property}</t>

<t>Description: Delete a property value from a device</t>

<t>Parameters, in path:
A propertyID {property} that needs to be deleted..</t>

<t>Parameters, in query:
An id of a device on which the property has to be deleted.</t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as the propertyID and the value deleted.</t>

<t>Example of a delete property response:</t>

<figure title="Example delete property response" anchor="exdelresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "propertyID": "temperature",
  "value": "1"
}
]]></artwork></figure>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
</section>
</section>
<section anchor="subscriptions"><name>Subscriptions</name>

<t>/action/property/subscription</t>

<t>Subscriptions are properties that deliver a data stream instead of a single
value. The property subscription API allows an application to manage these 
data streams.</t>

<t>Operations:</t>

<t><list style="symbols">
  <t>Start a subscription data stream: POST</t>
  <t>Get status of a subscription data stream: GET</t>
  <t>Stop a subscription data stream: DELETE</t>
</list></t>

<section anchor="property-subscription-api"><name>Property subscription API</name>

<section anchor="starting-a-subscription-data-stream"><name>Starting a subscription data stream</name>

<t>Method: POST /action/property/subscription</t>

<t>Description: Start a subcription data stream pertaining to a specific 
property</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>an Object, as defined in <xref target="objectdef"/></t>
  <t>A propertyID for which to start the subscription</t>
  <t>optional parameters</t>
</list></t>

<t>Example body for starting a subscription of a property:</t>

<figure title="Example starting a subscription for a property" anchor="exstartsub"><artwork><![CDATA[
{
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "technology": "ble",
  "propertyID": "temperature",
  "forcedAck": true
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "type" and "technology" are part of the object definition (device
or group), as defined in <xref target="objectdef"/></t>
  <t>"propertyID" is the ID of a previously registered property mapping</t>
  <t>"forcedAck" requests a specific response behavior of the device
that is not the default</t>
</list></t>

<t>Response:
Success responses is a standard success response when the
subscription is started, as defined in <xref target="success"/>.</t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="get-status-of-a-subscription-data-stream"><name>Get status of a subscription data stream</name>

<t>Method: GET /action/property/subscription/{property}</t>

<t>Description: Gets the status of a subscription data stream, success if
active, failure if not active</t>

<t>Parameters, in path:
A propertyID {property} for the subscription.</t>

<t>Parameters, in query:
An id of a device on which the subscription has to be started.</t>

<t>Response:
Success responses is a standard success response when the
subscription is started, as defined in <xref target="success"/>.</t>

<t>A failure to find the subscription will generate a standard failed response. 
Please refer to <xref target="failure"/> definition of failed response.</t>

</section>
<section anchor="stop-a-subscription-data-stream"><name>stop a subscription data stream</name>

<t>Method: DELETE /action/property/subscription/{property}</t>

<t>Description: stops a subscription data stream</t>

<t>Parameters, in path:
A propertyID {property} for the subscription.</t>

<t>Parameters, in query:
An id of a device on which the subscription has to be started.</t>

<t>Response:
Success response is a standard success response when the
subscription is deleted, as defined in <xref target="success"/>.</t>

<t>A failure to delete the subscription will generate a standard failed response.
Please refer to <xref target="failure"/> definition of failed response.</t>

</section>
</section>
</section>
</section>
<section anchor="nipc-registrations"><name>NIPC Registrations</name>

<t>NIPC allows an application to register properties to use in action API's. NIPC
supports 2 types of registrations: Registrations for properties and 
registrations for events.</t>

<section anchor="event-registration"><name>Event registration</name>

<t>/registration/event</t>

<t>The event registration API allows an application to register an event for a
data application to a specified property. This event is mapped to an MQTT
pub/sub topic. By activating a subscription on one or more device(s) for that
property, streaming data will get published to the associated pub/sub topic
on MQTT.</t>

<t>Operations:</t>

<t><list style="symbols">
  <t>Register an event: POST</t>
  <t>Update an event: PUT</t>
  <t>Get configuration of one or more events: GET</t>
  <t>Delete an event: DELETE</t>
</list></t>

<section anchor="event-registration-api"><name>Event registration API</name>

<section anchor="registering-an-event"><name>Registering an event</name>

<t>Method: POST /registration/event</t>

<t>Description: Register an event to a property</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>An event name that matches to an MQTT pub/sub topic</t>
  <t>The data format the event should be delivered in</t>
  <t>The device or group id the event is valid for</t>
  <t>Whether the event needs to be cached for replay</t>
  <t>the data applications that can consume the events</t>
</list></t>

<t>Example body registering an event:</t>

<figure title="Example registering an event" anchor="exregeve"><artwork><![CDATA[
{
  "event": "enterprise/hospital/pulse_oximeter",
  "eventFormat": "default",
  "replay": false,
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "dataApps": [
    {
      "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
      "mqtt": {
        "brokerURI": "mqtt.broker.com:8883",
        "username": "user1",
        "password": "password1",
        "brokerCACert": "string"
      }
    }
  ],
  "propertyID": "temperature"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"event" is the event identifier, which also maps to the MQTT topic name</t>
  <t>"eventFormat" is the format the data stream is delivered in, either default
(decorated with id and property) or just the payload</t>
  <t>"replay" defines whether the event should be cached for replay or not</t>
  <t>"id" is hte id of the device or group the event is valid for</t>
  <t>"type" is the type if the id, either device or group</t>
  <t>"dataApps" is an array of data appplications that can subscribe to the event</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to activate
this event</t>
</list></t>

<t>The dataApps array consists of following-</t>

<t><list style="symbols">
  <t>"dataAppID" is the identity of the data application either configured 
administratively or through SCIM.</t>
  <t>"mqtt" optional MQTT broker connection parameters, in case an external MQTT
needs to be configured</t>
</list></t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as all the attributes that were configured
from the request.</t>

<t>Example of a register event response:</t>

<figure title="Example register event response" anchor="exregeveresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "event": "enterprise/hospital/pulse_oximeter",
  "eventFormat": "default",
  "replay": false,
  "type": "device",
  "dataApps": [
    {
      "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
      "mqtt": {
        "brokerURI": "mqtt.broker.com:8883",
        "username": "user1",
        "password": "password1",
        "brokerCACert": "string"
      }
    }
  ],
  "propertyID": "temperature"
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/> definition</t>
  <t>"event" is the event identifier, which also maps to the MQTT topic name</t>
  <t>"eventFormat" is the format the data stream is delivered in, either default 
(decorated with id and property) or just the payload</t>
  <t>"replay" defines whether the event should be cached for replay or not</t>
  <t>"dataApps" is an array of data appplications that can subscribe to the event</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to activate
this event</t>
</list></t>

<t>The dataApps array consists of following-</t>

<t><list style="symbols">
  <t>"dataAppID" is the identity of the data application either configured 
administratively or through SCIM.</t>
  <t>"mqtt" optional MQTT broker connection parameters, in case an external MQTT
needs to be configured</t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="updating-a-topic"><name>Updating a topic</name>

<t>Method: PUT /registration/event</t>

<t>Description: Update an existing event</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>An event name that matches to an MQTT pub/sub topic</t>
  <t>The data format the event should be delivered in</t>
  <t>The device or group id the event is valid for</t>
  <t>Whether the event needs to be cached for replay</t>
  <t>the data applications that can consume the events</t>
</list></t>

<t>Example body updating an event:</t>

<figure title="Example updating an event" anchor="exupdeve"><artwork><![CDATA[
{
  "event": "enterprise/hospital/pulse_oximeter",
  "eventFormat": "default",
  "replay": false,
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "type": "device",
  "dataApps": [
    {
      "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
      "mqtt": {
        "brokerURI": "mqtt.broker.com:8883",
        "username": "user1",
        "password": "password1",
        "brokerCACert": "string"
      }
    }
  ],
  "propertyID": "temperature"
  "ble": {
    "type": "gatt",
    "serviceID": "12345678-1234-5678-1234-56789abcdef0",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef1"
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"event" is the event identifier, which also maps to the MQTT topic name</t>
  <t>"eventFormat" is the format the data stream is delivered in, either default
(decorated with id and property) or just the payload</t>
  <t>"replay" defines whether the event should be cached for replay or not</t>
  <t>"id" is hte id of the device or group the event is valid for</t>
  <t>"type" is the type if the id, either device or group</t>
  <t>"dataApps" is an array of data appplications that can subscribe to the event</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to activate
this event</t>
</list></t>

<t>The dataApps array consists of following-</t>

<t><list style="symbols">
  <t>"dataAppID" is the identity of the data application either configured
administratively or through SCIM.</t>
  <t>"mqtt" optional MQTT broker connection parameters, in case an external MQTT
needs to be configured</t>
</list></t>

<t>The propertyID gets mapped to a protocol-specific property with a 
property mapping, through a protocol object-</t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as all the attributes that were configured
from the request.</t>

<t>Example of an update register event response:</t>

<figure title="Example update event response" anchor="exupdeveresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "id": "12345678-1234-5678-1234-56789abcdef4",
  "event": "enterprise/hospital/pulse_oximeter",
  "eventFormat": "default",
  "replay": false,
  "type": "device",
  "dataApps": [
    {
      "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
      "mqtt": {
        "brokerURI": "mqtt.broker.com:8883",
        "username": "user1",
        "password": "password1",
        "brokerCACert": "string"
      }
    }
  ],
  "propertyID": "temperature"
  "ble": {
    "type": "gatt",
    "serviceID": "12345678-1234-5678-1234-56789abcdef0",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef1"
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/> 
definition</t>
  <t>"event" is the event identifier, which also maps to the MQTT topic name</t>
  <t>"eventFormat" is the format the data stream is delivered in, either default
(decorated with id and property) or just the payload</t>
  <t>"replay" defines whether the event should be cached for replay or not</t>
  <t>"dataApps" is an array of data appplications that can subscribe to the event</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to activate
this event</t>
</list></t>

<t>The dataApps array consists of following-</t>

<t><list style="symbols">
  <t>"dataAppID" is the identity of the data application either configured
administratively or through SCIM.</t>
  <t>"mqtt" optional MQTT broker connection parameters, in case an external MQTT
needs to be configured</t>
</list></t>

<t>The propertyID gets mapped to a protocol-specific property with a
property mapping, through a protocol object-</t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="get-configuration-of-one-or-more-events"><name>Get configuration of one or more events</name>

<t>Method: GET /registration/event</t>

<t>Description: Gets the configuration of one or more events</t>

<t>Parameters: An event name. Multiple events can be added by comma-separated
attributes. If no parameters are present, all events are returned.</t>

<t>Response: A success response as in <xref target="success"/> with a "events" object
containing an array of returned event names with attributes defined in
<xref target="exupdeve"/>.</t>

<t>Example of a get event response:</t>

<figure title="Example get event response" anchor="exgeteveresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "events": [
    {
      "ble": {
        "type": "gatt",
        "serviceID": "12345678-1234-5678-1234-56789abcdef0",
        "characteristicID": "12345678-1234-5678-1234-56789abcdef1"
      },
      "event": "enterprise/hospital/pulse_oximeter",
      "propertyID": "temperature",
      "eventFormat": "default",
      "replay": false,
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "type": "device",
      "dataApps": [
        {
          "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
          "mqtt": {
            "brokerURI": "mqtt.broker.com:8883",
            "username": "user1",
            "password": "password1",
            "brokerCACert": "string"
          }
        }
      ],
      "technology": "ble"
    },
    {
      "zigbee": {
        "endpointID": 1,
        "clusterID": 6,
        "propertyID": 16,
        "type": 1
      },
      "event": "enterprise/hospital/pulse_oximeter",
      "propertyID": "temperature",
      "eventFormat": "default",
      "replay": false,
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "type": "device",
      "dataApps": [
        {
          "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
          "mqtt": {
            "brokerURI": "mqtt.broker.com:8883",
            "username": "user1",
            "password": "password1",
            "brokerCACert": "string"
          }
        }
      ],
      "technology": "ble"
    }
  ]
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"events" is an array of events</t>
</list></t>

<t>where an event-</t>

<t><list style="symbols">
  <t>"event" is the event identifier, which also maps to the MQTT topic name</t>
  <t>"eventFormat" is the format the data stream is delivered in, either default
(decorated with id and property) or just the payload</t>
  <t>"replay" defines whether the event should be cached for replay or not</t>
  <t>"id" is hte id of the device or group the event is valid for</t>
  <t>"type" is the type if the id, either device or group</t>
  <t>"dataApps" is an array of data appplications that can subscribe to the event</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to activate
this event</t>
</list></t>

<t>The dataApps array consists of following-</t>

<t><list style="symbols">
  <t>"dataAppID" is the identity of the data application either configured
administratively or through SCIM.</t>
  <t>"mqtt" optional MQTT broker connection parameters, in case an external MQTT
needs to be configured</t>
</list></t>

<t>The propertyID gets mapped to a protocol-specific property with a
property mapping, through a protocol object-</t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="delete-one-or-more-topics"><name>Delete one or more topics</name>

<t>Method: DELETE /registration/event</t>

<t>Description: Delete one or more events</t>

<t>Parameters: An event name. Multiple events can be added by comma-separated
attributes. If no parameters are present, all events are returned.</t>

<t>Response: A success response as in <xref target="success"/> with a "events" object
containing an array of returned event names with attributes defined in
<xref target="exupdeve"/>.</t>

<t>Example of a delete event response:</t>

<figure title="Example delete event response" anchor="exdeleveresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "events": [
    {
      "ble": {
        "type": "gatt",
        "serviceID": "12345678-1234-5678-1234-56789abcdef0",
        "characteristicID": "12345678-1234-5678-1234-56789abcdef1"
      },
      "event": "enterprise/hospital/pulse_oximeter",
      "propertyID": "temperature",
      "eventFormat": "default",
      "replay": false,
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "type": "device",
      "dataApps": [
        {
          "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
          "mqtt": {
            "brokerURI": "mqtt.broker.com:8883",
            "username": "user1",
            "password": "password1",
            "brokerCACert": "string"
          }
        }
      ],
      "technology": "ble"
    },
    {
      "zigbee": {
        "endpointID": 1,
        "clusterID": 6,
        "propertyID": 16,
        "type": 1
      },
      "event": "enterprise/hospital/pulse_oximeter",
      "propertyID": "temperature",
      "eventFormat": "default",
      "replay": false,
      "id": "12345678-1234-5678-1234-56789abcdef4",
      "type": "device",
      "dataApps": [
        {
          "dataAppID": "12345678-1234-5678-1234-56789abcdef4",
          "mqtt": {
            "brokerURI": "mqtt.broker.com:8883",
            "username": "user1",
            "password": "password1",
            "brokerCACert": "string"
          }
        }
      ],
      "technology": "ble"
    }
  ]
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"events" is an array of events</t>
</list></t>

<t>where an event-</t>

<t><list style="symbols">
  <t>"event" is the event identifier, which also maps to the MQTT topic name</t>
  <t>"eventFormat" is the format the data stream is delivered in, either default
(decorated with id and property) or just the payload</t>
  <t>"replay" defines whether the event should be cached for replay or not</t>
  <t>"id" is hte id of the device or group the event is valid for</t>
  <t>"type" is the type if the id, either device or group</t>
  <t>"dataApps" is an array of data appplications that can subscribe to the event</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to activate
this event</t>
</list></t>

<t>The dataApps array consists of following-</t>

<t><list style="symbols">
  <t>"dataAppID" is the identity of the data application either configured
administratively or through SCIM.</t>
  <t>"mqtt" optional MQTT broker connection parameters, in case an external MQTT
needs to be configured</t>
</list></t>

<t>The propertyID gets mapped to a protocol-specific property with a
property mapping, through a protocol object-</t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
</section>
</section>
<section anchor="property-registration"><name>Property registration</name>

<t>/registration/property</t>

<t>The property registration API allows an application to register a property
mapping against a protocol-specific property as decribed in <xref target="propertymap"/></t>

<t>Operations:</t>

<t><list style="symbols">
  <t>Register a property: POST</t>
  <t>Update a property: PUT</t>
  <t>Get a property: GET</t>
  <t>Delete a property: DELETE</t>
</list></t>

<section anchor="property-registration-api"><name>Property registration API</name>

<section anchor="registering-a-property"><name>Registering a property</name>

<t>Method: POST /registration/property</t>

<t>Description: Register a property mapping to a protocol-specific property</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>a property ID</t>
  <t>a protocol object containing a protocol mapping</t>
</list></t>

<t>Example body registering a property:</t>

<figure title="Example registering a property" anchor="exregprop"><artwork><![CDATA[
{
  "propertyID": "temperature",
  "ble": {
    "serviceID": "12345678-1234-5678-1234-56789abcdef4",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
    "long": false
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"propertyID" is the propertyID that will be used in action APIs to refer
to this property mapping</t>
  <t>A protocol object with a protocol-specific property map, as decribed in
<xref target="propertymap"/></t>
</list></t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as all the attributes that were configured
from the request.</t>

<t>Example of a register property response:</t>

<figure title="Example register property response" anchor="exregpropresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "propertyID": "temperature",
  "ble": {
    "serviceID": "12345678-1234-5678-1234-56789abcdef4",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
    "long": false
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to refer
to this property mapping</t>
  <t>A protocol object with a protocol-specific property map, as decribed in
<xref target="propertymap"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="updating-a-property"><name>Updating a property</name>

<t>Method: PUT /registration/property</t>

<t>Description: Update a property mapping to a protocol-specific property</t>

<t>Parameters: None</t>

<t>Request Body:</t>

<t><list style="symbols">
  <t>a property ID</t>
  <t>a protocol object containing a protocol mapping</t>
</list></t>

<t>Example body updating a property:</t>

<figure title="Example registering a property" anchor="exupdprop"><artwork><![CDATA[
{
  "propertyID": "temperature",
  "ble": {
    "serviceID": "12345678-1234-5678-1234-56789abcdef4",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
    "long": false
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"propertyID" is the propertyID that will be used in action APIs to refer
to this property mapping</t>
  <t>A protocol object with a protocol-specific property map, as decribed in
<xref target="propertymap"/></t>
</list></t>

<t>Response:
Success responses include standard success response properties
as defined in <xref target="success"/> as well as all the attributes that were configured
from the request.</t>

<t>Example of an update property response:</t>

<figure title="Example register property response" anchor="exupdpropresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "propertyID": "temperature",
  "ble": {
    "serviceID": "12345678-1234-5678-1234-56789abcdef4",
    "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
    "long": false
  }
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to refer
to this property mapping</t>
  <t>A protocol object with a protocol-specific property map, as decribed in
<xref target="propertymap"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="get-property-mapping-of-one-or-more-properties"><name>Get property mapping of one or more properties</name>

<t>Method: GET /registration/property</t>

<t>Description: Gets the property mapping of one or more properties</t>

<t>Parameters: A property name. Multiple properties can be added by
comma-separated parameters. If no parameters are present, all properties
are returned.</t>

<t>Response: A success response as in <xref target="success"/> with an array of properties,
containing propertyID with protocol object containing a protocol-specific 
property mapping</t>

<t>Example of a get property response:</t>

<figure title="Example get property response" anchor="exgetpropresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "properties": [
    {
      "ble": {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
        "long": false
      },
      "propertyID": "temperature"
    },
    {
      "zigbee": {
        "endpointID": 1,
        "clusterID": 6,
        "propertyID": 16,
        "type": 1
      },
      "propertyID": "temperature"
    }
  ]
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"properties" is an array of properties</t>
</list></t>

<t>where a property-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to refer
to this property mapping</t>
  <t>A protocol object with a protocol-specific property map, as decribed in
<xref target="propertymap"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
<section anchor="delete-property-mapping-of-one-or-more-properties"><name>Delete property mapping of one or more properties</name>

<t>Method: DELETE /registration/property</t>

<t>Description: Deletes the property mapping of one or more properties</t>

<t>Parameters: A property name. Multiple properties can be added by 
comma-separated parameters. If no parameters are present, all properties
are deleted.</t>

<t>Response: A success response as in <xref target="success"/> with an array of properties, 
containing propertyID with protocol object containing a protocol-specific <br />
property mapping</t>

<t>Example of a delete property response:</t>

<figure title="Example delete property response" anchor="exdelpropresp"><artwork><![CDATA[
{
  "status": "SUCCESS",
  "requestID": "12345678-5678-1234-5578-abcdef1234",
  "properties": [
    {
      "ble": {
        "serviceID": "12345678-1234-5678-1234-56789abcdef4",
        "characteristicID": "12345678-1234-5678-1234-56789abcdef4",
        "long": false
      },
      "propertyID": "temperature"
    },
    {
      "zigbee": {
        "endpointID": 1,
        "clusterID": 6,
        "propertyID": 16,
        "type": 1
      },
      "propertyID": "temperature"
    }
  ]
}
]]></artwork></figure>

<t>where-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"properties" is an array of properties</t>
</list></t>

<t>where a property-</t>

<t><list style="symbols">
  <t>"id", "requestID" and "technology" are part of the standard <xref target="success"/>
definition</t>
  <t>"propertyID" is the propertyID that will be used in action APIs to refer
to this property mapping</t>
  <t>A protocol object with a protocol-specific property map, as decribed in
<xref target="propertymap"/></t>
</list></t>

<t>A failure will generate a standard failed response. Please refer to <xref target="failure"/>
definition of failed response.</t>

</section>
</section>
</section>
</section>
<section anchor="nipc-extensibility"><name>NIPC Extensibility</name>

<t>NIPC is extensible in two ways:</t>

<t><list style="symbols">
  <t>Protocol mapping: New protocol mapping can extend NIPC with support
for new non-IP protocols</t>
  <t>API extensions: API extensions leverage compound statements of basic NIPC
action APIs to simplify common operations for applications.</t>
</list></t>

<section anchor="protocol-extensions"><name>Protocol extensions</name>

<t>As described in <xref target="propertymap"/> NIPC supports mapping protocol specific
mapping to NIPC properties. BLE and Zigbee are used as examples, but protocol
mapping is extensible to other protocols, so noew non-IP protocols can be 
supported by NIPC without a schema change.</t>

<figure title="Extended protocol mapping" anchor="extprotmap"><artwork><![CDATA[
     -  property
        |
        |> BLE
        |     - BLE  properties
        |
        |> Zigbee
        |     - Zigbee properties
        |
        |> New protocol 
        |     -  New protocol properties

]]></artwork></figure>

<t>As shown in <xref target="extprotmap"/>, a protocol mapping can be added by adding
a new technology specific extension to the schema.</t>

<t>This is performed by adding the new protocol to the technology enum in
the base object definition <xref target="objectdef"/></t>

<t>Furthermore, the protocol objects need to be extended with the new
protocol as well. Protocol objects will be extended as follows:</t>

<texttable title="Adding Protocol mappings" anchor="newprotext">
      <ttcol align='left'>Attribute</ttcol>
      <ttcol align='left'>Req</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>ble</c>
      <c>T</c>
      <c>object</c>
      <c>an object with BLE-specific properties</c>
      <c>zigbee</c>
      <c>T</c>
      <c>object</c>
      <c>an object with Zigbee-specific properties</c>
      <c>newProtocol</c>
      <c>T</c>
      <c>object</c>
      <c>an object with newProtocol-specific props</c>
</texttable>

<t>In the new protocol object, protocol specific properties can be added.</t>

<t>Protocol mappings need to be IANA registered.</t>

</section>
<section anchor="api-extensions"><name>API extensions</name>

<t>/extension</t>

<t>The extension APIs allow for extensibility of the APIs, either IANA 
registered extensions or vendor-specific extensions.
Extension APIs must leverage the basic NIPC defined APIs and combine them in 
compound statements in order to streamline application operation against
devices, make operations more expediant and convenient in one API call.
In principle they do not add any basic functionality. In
the OpenAPI model <xref target="openAPI"/> below, we have defined a few example 
extensions.</t>

</section>
</section>
<section anchor="publishsubscribe-interface"><name>Publish/Subscribe Interface</name>

<t>The publish/subscribe interface, or data streaming interface, is an MQTT
publishing interface. Pub/sub topics can be created and managed by means
of the /registration/event NIPC element.</t>

<t>In this memo, we propose the data format to be CBOR <xref target="RFC8949"/>.</t>

<section anchor="cddl-definition"><name>CDDL Definition</name>

<t>We have a CDDL <xref target="RFC8610"/> definition where we define the
DataSubscription struct that will be used by all the messages published 
to the MQTT broker.</t>

<t>The DataSubscription struct is a CBOR map that will contain the raw data
in bytes and a timestamp of the data. Optionally, the message will also
have a deviceId that corresponds to the SCIM ID of the device if the 
payload is associated to a known device.</t>

<t>Other fields in the CDDL such as apMacAddress and rssi can be optionally
included but these fields can expose the underlying network topology.</t>

<t>Each message also has a subscription choice group that will define the
type of data that is being published.</t>

<figure><sourcecode type="CDDL"><![CDATA[
DataSubscription = {
  data: bytes,
  timestamp: float, ; epoch in seconds
  ? deviceId: text,
  ? apMacAddress: text,
  subscription
}

subscription = (
  bleSubscription: BleSubscription //
  bleAdvertisement: BleAdvertisement //
  bleConnectionStatus: BleConnectionStatus //
  zigbeeSubscription: ZigbeeSubscription //
  rawPayload: RawPayload
)

BleSubscription = {
  serviceId: text,
  characteristicId: text
}

BleAdvertisement = {
  macAddress: text,
  ? rssi: nint,
}

BleConnectionStatus = {
  macAddress: text,
  connected: bool,
  ? reason: int
}

ZigbeeSubscription = {
  endpointId: int,
  clusterId: int,
  attributeId: int
  attributeType: int
}

RawPayload = {
  contextId: text
}
]]></sourcecode></figure>

</section>
<section anchor="cbor-examples"><name>CBOR Examples</name>

<t>This section contains a few examples of the DataSubscription struct 
depicted in CBOR diagnostic notation.</t>

<figure title="Onboarded BLE Device Advertisement"><artwork><![CDATA[
{
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "deviceId": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "bleAdvertisement": {
        "macAddress": "C1:5C:00:00:00:01",
        "rssi": -25
    }
}
]]></artwork></figure>

<figure title="Non-onboarded BLE Device Advertisement"><artwork><![CDATA[
{
    "data": h'02011A020A0C16FF4C001007721F41B0392078',
    "timestamp": 1727484393,
    "bleAdvertisement": {
        "macAddress": "C1:5C:00:00:00:01",
        "rssi": -25
    }
}
]]></artwork></figure>

<figure title="BLE GATT Notification"><artwork><![CDATA[
{
    "data": h'434630374346303739453036',
    "deviceId": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "bleSubscription": {
        "serviceId": "a4e649f4-4be5-11e5-885d-feff819cdc9f",
        "characteristicId": "c4c1f6e2-4be5-11e5-885d-feff819cdc9f"
    }
}
]]></artwork></figure>

<figure title="BLE Connection status event"><artwork><![CDATA[
{
    "data": h'434630374346303739453036',
    "deviceId": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "bleConnectionStatus": {
        "macAddress": "C1:5C:00:00:00:01",
        "connected": true
    }
}
]]></artwork></figure>

<figure title="Zigbee Attribute Notification"><artwork><![CDATA[
{
    "data": h'434630374346303739453036',
    "deviceId": "75fde96d-886f-4ac0-a1d5-df79f76e7c9c",
    "timestamp": 1727484393,
    "zigbeeSubscription": {
        "endpointId": 1,
        "clusterId": 6,
        "attributeId": 12,
        "type": 1
    }
}
]]></artwork></figure>

</section>
</section>
<section anchor="examples"><name>Examples</name>

<t>This section contains a few examples on how applications can leverage 
NIPC operations to communicate with BLE and Zigbee devices.</t>

<section anchor="ble-advertisement"><name>BLE Advertisement</name>

<t>In this example, we will onboard a device, and setup an advertisement
subscription event for that device.</t>

<t>The sequence of operations for this are:</t>

<t><list style="symbols">
  <t>Onboard a device using the SCIM Interface (out of scope of this
memo)</t>
  <t>Register an eventc with the device id to subscribe to advertisements
POST /register/event</t>
  <t>Subscribe to the topic from the data receiver app 
MQTT subscribe topic</t>
</list></t>

</section>
<section anchor="ble-property-readwrite"><name>BLE Property Read/Write</name>

<t>In this example, we will connect to a BLE device and read and write from a
property.</t>

<t>The sequence of operations for this are:</t>

<t><list style="symbols">
  <t>Onboard a device using the SCIM Interface (out of scope of this
memo)</t>
  <t>Connect to the BLE device
POST /action/connection</t>
  <t>Read a property from the BLE device
GET  /action/property</t>
  <t>Write to a property on the BLE device
POST /action/property</t>
  <t>Disconnect from the BLE device
DELETE /action/connection</t>
</list></t>

</section>
<section anchor="zigbee-property-readwrite"><name>Zigbee Property Read/Write</name>

<t>In this example, we will connect a zigbee device to a Zigbee mesh
and read and write from a property</t>

<t>The sequence of operations for this are:</t>

<t><list style="symbols">
  <t>Onboard a device using the SCIM Interface (out of scope of this
memo)</t>
  <t>Connect the Zigbee device
POST /action/connection</t>
  <t>Read a property from the Zigbee device
GET  /action/property</t>
  <t>Write to a property on the Zigbee device
POST  /action/property</t>
  <t>Disconnect from the Zigbee device
DELETE /action/connection</t>
</list></t>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>TBD.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<t>This section provides guidance to the Internet Assigned Numbers Authority
(IANA) regarding registration of values related to NIPC, in accordance
with <xref target="RFC8126"/>.</t>

<section anchor="protocol-mapping"><name>Protocol mapping</name>

</section>
<section anchor="api-extensions-1"><name>API extensions</name>

</section>
</section>


  </middle>

  <back>


    <references title='Normative References' anchor="sec-normative-references">

&RFC7644;
&I-D.ietf-scim-device-model;
&RFC2119;
&RFC8174;
&I-D.ietf-asdf-sdf;
&RFC9114;
&RFC8949;
&RFC8610;
&RFC8126;


    </references>

    <references title='Informative References' anchor="sec-informative-references">

<reference anchor="BLE53" >
  <front>
    <title>Bluetooth Core Specification, Version 5.3</title>
    <author >
      <organization>Bluetooth SIG</organization>
    </author>
    <date year="2021"/>
  </front>
</reference>
<reference anchor="Zigbee22" >
  <front>
    <title>zigbee Specification, Version 22 1.0</title>
    <author >
      <organization>Connectivity Standards Alliance</organization>
    </author>
    <date year="2017"/>
  </front>
</reference>


    </references>


<?line 2024?>

<section anchor="openapi-definition"><name>OpenAPI definition</name>

<t>The following non-normative model is provide for convenience of
the implementor.</t>

<figure anchor="openAPI"><artwork><![CDATA[
<CODE BEGINS>
file "openapi.yml"
openapi: 3.0.3
info:
  title: Non IP Device Control (NIPC) API
  description: |-
    There has been a large influx of non-IP devices supporting
    processes in manufacturing, healthcare, hospitality, retail, the
    home, and the office.  At the same time, wireless access points
    have been deployed nearly everywhere, many of which have radios
    that can transmit and receive different frame types, such as BLE,
    Zigbee. To integrate multiple of these use cases leveraging a
    single wireless infrastructure and avoid the need for parallel
    infrastructure, a Non IP device gateway function is necessary.
    The gateway provides the following functions:
       - authentication and authorization of application clients that
         will communicate with devices 
       - APIs that onboard a device on the network (out of scope for
         this specification, but covered in SCIM for devices)
       - APIs that allow an app to set up a connection with a device
       - APIs that allow an app to exchange action with a device
       - APIs that allow a device to create registrations in the
         network for a device 
    These collection of these APIs, in combination with the
    onboarding API (SCIM for devices) will allow an application to
    perform a complete set of operations on Non-IP devices.
  termsOfService: http://swagger.io/terms/
  contact:
    email: bbrinckm@cisco.com
  license:
    name: TBD
    url: TBD
  version: 0.3.5
externalDocs:
  description: NIPC IETF draft
  url: TBD
servers:
  - url: https://{gw_host}/nipc
    variables:
      gw_host:
        default: localhost
        description: Gateway Host
tags:
  - name: action
    description: APIs that allow apps to perform actions on devices. 
  - name: registrations
    description: |-
      APIs that allow apps to register properties of devices.
  - name: extensions
    description: |-
      APIs that simplify application interaction by implementing one
      or more basic API's into a single API call.

paths:
### Action
  /action/connection:
    post:
      tags:
        - action
      summary: |-
        Connect a device to the network, optionally with service
        discovery 
      description: |-
        Connect a device to the network, optionally with service
        discovery 
      operationId: Connect
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Connection'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
    
    get:
      tags:
        - action
      summary: |-
        Get connection state devices for a device or group of
        devices
      description: |-
        Get all connection status for connections made by control ap
        or connection status by object ID, multiple ids can be
        provided with comma separated strings, or a group id can be
        provided  
      operationId: GetConnections
      parameters:
        - name: id
          in: query
          description: device or group ids that need to be filtered
          required: false
          explode: false
          schema:
            type: array
            items:
              type: string
              format: uuid
              example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiConnectionsResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
                
    delete:
      tags:
        - action
      summary: Disconnect a device or group of devices
      description: |-
        Disconnect a device or device group by object ID, Multiple
        ids can be provided with comma separated strings, or a
        group id can be provided 
      operationId: DeleteConnections
      parameters:
        - name: id
          in: query
          description: device or group ids that need to be filtered
          required: false
          explode: false
          schema:
            type: array
            items:
              type: string
              format: uuid
              example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiConnectionsResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 

  /action/connection/id/{id}:
    post:
      tags:
        - action
      summary: |-
        Connect a device by device id (device technology needs to
        support connection) 
      description: |-
        Connect a device by device id, full service discovery 
        will be performed. Will fail if device has multiple 
        technologies defined. Group ids will fail.
      operationId: CreateConnectionbyID
      parameters:
        - name: id
          in: path
          description: device id that need to be filtered
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
  
    get:
      tags:
        - action
      summary: Get connection by id for a device
      description: |-
        Get connection by id for a device, success when device
        connected, failure when device not connected.
        Group ids will also fail. 
      operationId: GetConnectionbyId
      parameters:
        - name: id
          in: path
          description: device id that need to be filtered
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
                
    delete:
      tags:
        - action
      summary: Delete connection by id for a device
      description: |-
        Disconnect a device by id, success when device
        is disconnected, failure disconnect fails.
        Group ids will also fail. 
      operationId: DeleteConnectionbyID
      parameters:
        - name: id
          in: path
          description: device id that need to be filtered
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
  
  /action/services/:            
    get:
      tags:
        - action
      summary: Get all services for a device
      description: |-
        Get all services for a connected device, success
        when service discovery succeeds failure, failure when 
        Service discovery fails. This updates cache for cached
        Services. Fails when using a group id.
      operationId: GetServicesbyId
      parameters:
        - name: id
          in: query
          description: device id that need to be filtered
          required: true
          schema:
            type: string
            format: uuid
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 

  /action/services/discover:
    post:
      tags:
        - action
      summary: |-
        Selectively discover services on a device, limited 
        to services described in the parameters
      description: |-
        Selectively discover services on a device, limited 
        to services described in the parameters.
        Group ids will fail.
      operationId: GetSelectiveServices
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Service'
        required: true    
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /action/property:
    post:
      tags:
        - action
      summary: Write a value to an property on a device
      description: Write a value to an property on a device
      operationId: Write
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyValue'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request       
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
    
    put:
      tags:
        - action
      summary: Update a value of an property on a device
      description: Update a value of an property on a device
      operationId: Update
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyValue'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request       
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
  
  /action/property/{property}:
    delete:
      tags:
        - action
      summary: Delete a value from an property on a device
      description: Delete a value to an property on a device
      operationId: Delete
      parameters:
      - name: id
        in: query
        description: device id that need to be filtered
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "temperature"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 
                
    get:
      tags:
        - action
      summary: Read a value from an property on a device
      description: Read a value to an property on a device
      operationId: Read
      parameters:
      - name: id
        in: query
        description: device id that need to be filtered
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "temperature"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse' 

  /action/property/write:
    post:
      tags:
        - action
      summary: Write a value to an property using technology extensions
      description: |-
        Write a value to an property directly, addressing the property
        with technology-specific extensions, this does not require
        property registration. You cannot write to a group id.
      operationId: AttrWrite
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyValueRaw'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponseRaw'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
                
  /action/property/read:
    post:
      tags:
        - action
      summary: Read a value to an property using technology extensions
      description: |-
        Read a value to an property directly, addressing the property
        with technology-specific extensions, this does not require
        property registration. You cannot write to a group id.
      operationId: AttrRead
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyRaw'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponseRaw'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
  
  /action/property/subscription:
    post:
      tags:
        - action
      summary: |-
         Subscribe to streaming event action from an property on a device
      description: |-
        Subscribe to streaming event action from an property on a device
      operationId: Subscribe
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Subscription'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request 
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'   
  
  /action/property/subscription/{property}:
    delete:
      tags:
        - action
      summary: |-
        Unsubscribe to streaming event action from an property on a device
      description: |-
        Unsubscribe to streaming event action from an property on a device
      operationId: Unsubscribe
      parameters:
      - name: id
        in: query
        description: device id that need to be filtered
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        schema:
          type: string
          example: "temperature" 
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
                
    get:
      tags:
        - action
      summary: Get the status of an event subscription on a device
      description: Get the status of an event subscription on a device
      operationId: GetSubscription
      parameters:
      - name: id
        in: query
        description: device id that need to be filtered
        required: true
        schema:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
      - name: property
        in: path
        description: property that needs to be filtered
        required: true
        explode: true
        schema:
          type: string
          example: "temperature" 
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /action/property/subscription/event/{event}:    
    delete:
      tags:
        - action
      summary: delete all active subscriptions by event
      description: delete all active subscriptions by event
      operationId: deleteSubscriptionbyEvent
      parameters:
        - name: event
          in: path
          description: event that needs to be filtered
          required: true
          schema:
            type: string
            example: "enterprise/hospital/pulse_oximeter"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref:
                   '#/components/schemas/MultiSubscriptionResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - action
      summary: get all active subscriptions by event
      description: get all active subscriptions by event
      operationId: getSubsciptionsbyEvent
      parameters:
        - name: event
          in: path
          description: event that needs to be filtered
          required: true
          schema:
            type: string
            example: "enterprise/hospital/pulse_oximeter"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref:
                   '#/components/schemas/MultiSubscriptionResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref:
                   '#/components/schemas/MultiSubscriptionResponse'

  /action/property/subscription/id/{id}:
    delete:
      tags:
        - action
      summary: delete all event subscriptions by id
      description: delete all event subscriptions by id
      operationId: deleteSubscriptionbyID
      parameters:
        - name: id
          in: path
          description: object id that needs to be filtered
          required: true
          schema:
            type: string
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref:
                   '#/components/schemas/MultiSubscriptionResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - action
      summary: get all event subscriptions by object id
      description: get all event subscriptions by object id
      operationId: getSubscriptionbyID
      parameters:
        - name: id
          in: path
          description: object id that needs to be filtered
          required: true
          schema:
            type: string
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref:
                   '#/components/schemas/MultiSubscriptionResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /action/property/subscription/start:
    post:
      tags:
        - action
      summary: |-
         Subscribe to streaming action from an property on a device
         by directly addressing hte property (unregistered attr)
      description: |-
        Subscribe to streaming action from an property on a device
        by directly addressing hte property (unregistered attr)
      operationId: SubscriptionStart
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscriptionRaw'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request 
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'  
  
  /action/property/subscription/stop:
    post:
      tags:
        - action
      summary: |-
         Stop streaming action from an property on a device
         by directly addressing hte property (unregistered attr)
      description: |-
        Stop streaming action from an property on a device
        by directly addressing hte property (unregistered attr)
      operationId: SubscriptionStop
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscriptionRaw'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'          
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request 
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'  
 
  /action/broadcast:
    post:
      tags:
        - action
      summary: Broadcast to a device
      description: Broadcast to a device
      operationId: Broadcast
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Broadcast'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

### Registrations
  /registration/event:
    post:
      tags:
        - registrations
      summary: Register a publish/subscribe event
      description: Register a publish/subscribe event
      operationId: registerEvent
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Event'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    put:
      tags:
        - registrations
      summary: Update a publish/subscribe event
      description: Update a publish/subscribe event
      operationId: UpdateEvent
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Event'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    delete:
      tags:
        - registrations
      summary: unregister a publish/subscribe event
      description: |-
        unregister a publish/subscribe event, single topic,
        multiple events not allowed.
      operationId: unregisterEvent
      parameters:
        - name: event
          in: query
          description: event that need to be filtered
          required: false
          explode: false
          schema:
            type: string
            example: "enterprise/hospital/pulse_oximeter"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - registrations
      summary: get one or all publish/subscribe event
      description: |-
        get publish/subscribe event, if no topic is specified
        in query, all events will be returned
      operationId: getEvent
      parameters:
        - name: event
          in: query
          description: event that need to be filtered
          required: false
          explode: false
          schema:
            type: string
            example: "enterprise/hospital/pulse_oximeter"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiEventsResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /registration/event/{event}:
    delete:
      tags:
        - registrations
      summary: delete a publish/subscribe event by name
      description: unregister a publish/subscribe event by Name
      operationId: deleteEventbyName
      parameters:
        - name: event
          in: path
          description: event that needs to be filtered
          required: true
          schema:
            type: string
            example: "enterprise/hospital/pulse_oximeter"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - registrations
      summary: get a publish/subscribe event by name
      description: get a publish/subscribe event by name
      operationId: getEventbyName
      parameters:
        - name: event
          in: path
          description: event that needs to be filtered
          required: true
          schema:
            type: string
            example: "enterprise/hospital/pulse_oximeter"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /registration/event/data-app/{data-app}:
    delete:
      tags:
        - registrations
      summary: delete all publish/subscribe events by data-app
      description: |-
        unregister all publish/subscribe events by data-app
      operationId: deleteEventbyDataApp
      parameters:
        - name: data-app
          in: path
          description: action app that needs to be filtered
          required: true
          schema:
            type: string
            example: https://data-app-1
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiEventsResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - registrations
      summary: get all publish/subscribe events by data-app
      description: get all publish/subscribe events by data-app
      operationId: getEventbyDataApp
      parameters:
        - name: data-app
          in: path
          description: action app that needs to be filtered
          required: true
          schema:
            type: string
            example: https://data-app-1
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiEventsResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /registration/event/id/{id}:
    delete:
      tags:
        - registrations
      summary: delete all publish/subscribe events by object id
      description: unregister all publish/subscribe events by id
      operationId: deleteEventbyID
      parameters:
        - name: id
          in: path
          description: object id that needs to be filtered
          required: true
          schema:
            type: string
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiEventsResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - registrations
      summary: get all publish/subscribe events by object id
      description: get all publish/subscribe events by object id
      operationId: getEventbyID
      parameters:
        - name: id
          in: path
          description: object id that needs to be filtered
          required: true
          schema:
            type: string
            example: 12345678-1234-5678-1234-56789abcdef4
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiEventsResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /registration/property:
    post:
      tags:
        - registrations
      summary: Register an property
      description: |-
        Register an property for use in action APIs
      operationId: registerProperty
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyRegistration'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyRegistrationResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    put:
      tags:
        - registrations
      summary: Update an property registration
      description: |-
        Update an existing property registration
      operationId: updatePropertyRegistration
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyRegistration'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyRegistrationResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    delete:
      tags:
        - registrations
      summary: Delete an property registration
      description: Delete an property registration
      operationId: deletePropertyRegistration
      parameters:
        - name: propertyname
          in: query
          description: property name that needs to be filtered
          required: false
          explode: false
          schema:
            type: string
            example: "temperature"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyRegistrationResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - registrations
      summary: list registered properties
      description: |-
        get a registered property by name of get all 
        properties if no names supplied.
      operationId: getPropertyRegistration
      parameters:
        - name: propertyname
          in: query
          description: property name that needs to be filtered
          required: false
          explode: true
          schema:
            type: string
            example: "temperature"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MultiPropertyRegistrationResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /registration/property/{propertyname}:
    delete:
      tags:
        - registrations
      summary: delete an property registration by name
      description: delete an property registration by name
      operationId: deletePropertyRegistrationbyName
      parameters:
        - name: propertyname
          in: path
          description: property that needs to be filtered
          required: true
          schema:
            type: string
            example: "temperature"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyRegistrationResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

    get:
      tags:
        - registrations
      summary: get an property registration by name
      description: get an property registration by name
      operationId: getAttirbuteRegistrationbyName
      parameters:
        - name: propertyname
          in: path
          description: property that needs to be filtered
          required: true
          schema:
            type: string
            example: "temperature"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyRegistrationResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
                
  /registration/property/file:
    post:
      tags:
        - registrations
      summary: Register and upload a file for later use
      description: Register and upload a file for later use
      operationId: registerFile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/File'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

### Extensions

  /extension/property/write/file:
    post:
      tags:
        - extensions
      summary: Write a file to an property across multiple writes
      description: |-
        Write a file to an property across multiple writes
      operationId: WriteFile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyFile'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /extension/property/write/blob:
    post:
      tags:
        - extensions
      summary: |-
        Write a binary blob to an property across multiple writes
      description: |-
        Write a binary blob to an property across multiple writes
      operationId: WriteBlob
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyBlob'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /extension/property/read/conditional:
    post:
      tags:
        - extensions
      summary: |-
        Read a value from property on a device until it matches a
        specific value.
      description: |-
        Read a value from property on a device until it matches a
        specific value.
      operationId: ReadCond
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PropertyConditional'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PropertyValueResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

  /extension/property/firmware:
    post:
      tags:
        - extensions
      summary: Write firmware to a device
      description: |-
        Write a file to an property across multiple writes
      operationId: WriteFirmware
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Firmware'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FirmwareResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
                
    get:
      tags:
        - extensions
      summary: get the status of a firmware upgrade
      description: get the status of a firmware upgrade
      operationId: getFirmwareStatus
      parameters:
        - name: id
          in: query
          description: device id that needs to be filtered
          required: true
          schema:
            type: string
            example: "12345678-1234-5678-1234-56789abcdef4"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FirmwareResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'
                
  /extension/bulk:
    post:
      tags:
        - extensions
      summary: Compound operations on a device
      description: Compound operations on a device
      operationId: Bulk
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Bulk'
        required: true
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkResponse'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '405':
          description: Invalid request
        '500':
          description: Server-side failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailureResponse'

components:
  schemas:
# BLE objects
##  An array for BLE services
    BLEServiceslist:
      required:
        - services
      type: object
      properties:
        ble:
          type: array
          items:
            $ref: '#/components/schemas/BLEService'

## A BLE service with its characteristics
    BLEService:
      required:
        - serviceID
        - characteristics
      type: object
      properties:
        serviceID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
        characteristics:
          type: array
          items:
            $ref: '#/components/schemas/BLECharacteristic'

## A BLE characteristics with its descriptors
    BLECharacteristic:
      required:
        - characteristicID
        - flags
        - descriptors
      type: object
      properties:
        characteristicID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
        flags:
          type: array
          example:
          - read
          - write
          items:
            type: string
            enum:
              - read
              - write
              - notify
        descriptors:
          type: array
          items:
            $ref: '#/components/schemas/BLEDescriptor'

## A BLE descriptor
    BLEDescriptor:
      required:
        - descriptorID
      type: object
      properties:
        descriptorID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4

## BLE service ID only
    BLEServiceID:
      type: object
      properties:
        serviceID:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4

## Properties that define a BLE property
    BLEProperties:
      required:
        - ble
      type: object
      properties:
        ble:
          required:
            - serviceID
            - characteristicID
          type: object
          properties:
            serviceID:
              type: string
              format: uuid
              example: 12345678-1234-5678-1234-56789abcdef4
            characteristicID:
              type: string
              format: uuid
              example: 12345678-1234-5678-1234-56789abcdef4
            long:
              type: boolean
              example: false

## Defines different types of BLE events
    BLEEvent:
      required:
        - ble
      type: object
      properties:
        ble:
          oneOf:
            - $ref: '#/components/schemas/BLESubEvent'
            - $ref: '#/components/schemas/BLEConnEvent'
            - $ref: '#/components/schemas/BLEAdvEvent'

## BLE Gatt Event definition
    BLESubEvent:
      required:
        - type
        - serviceID
        - characteristicID
      type: object
      properties:
        type:
          type: string
          example: gatt
          enum:
            - gatt
        serviceID:
          type: string
          example: 12345678-1234-5678-1234-56789abcdef0
        characteristicID:
          type: string
          example: 12345678-1234-5678-1234-56789abcdef1

## BLE Connection event Event definition
    BLEConnEvent:
      required:
        - type
      type: object
      properties:
        type:
          type: string
          example: connection_events
          enum:
            - connection_events

## BLE Advertisement Event definition
    BLEAdvEvent:
      required:
        - type
      type: object
      properties:
        type:
          type: string
          example: advertisements
          enum:
            - advertisements
        filterType:
          type: string
          example: deny
          enum:
            - deny
            - allow
        filters:
          type: array
          items:
            $ref: '#/components/schemas/BLEAdvertisement'

## BLE Advertisement properties
    BLEAdvertisement:
      type: object
      properties:
        adType:
          type: string
          example: ff
        adData:
          type: string
          example: 4c00*

## Properties that define a BLE broadcast
    BLEBroadcast:
      required:
        - ble
      type: object
      properties:
        ble:
          type: object
          required:
            - advertisement
          properties:
            advertisement:
              type: string
              format: byte
              example: AgEaAgoMFv9MABAHch9BsDkgeA==

# Zigbee objects
## An array for Zigbee Endpoints
    ZigbeeEndpointlist:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          type: array
          items:
            $ref: '#/components/schemas/ZigbeeEndpoint'

## A Zigbee endpoint with its clusters
    ZigbeeEndpoint:
      required:
        - endpointID
        - clusters
      type: object
      properties:
        endpointID:
          type: integer
          format: int32
          example: 10
        clusters:
          type: array
          items:
            $ref: '#/components/schemas/ZigbeeCluster'

## A Zigbee cluster with its properties
    ZigbeeCluster:
      required:
        - clusterID
        - properties
      type: object
      properties:
        clusterID:
          type: integer
          format: int32
          example: 0
        properties:
          type: array
          items:
            $ref: '#/components/schemas/ZigbeeProperty'

## A Zigbee property
    ZigbeeProperty:
      required:
        - propertyID
        - propertyType
      type: object
      properties:
        propertyID:
          type: integer
          format: int32
          example: 1
        propertyType:
          type: integer
          format: int32
          example: 32

## Properties that define a Zigbee property
    ZigbeeProperties:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          required:
            - endpointID
            - clusterID
            - propertyID
          type: object
          properties:
            endpointID:
              type: integer
              format: int32
              example: 1
            clusterID:
              type: integer
              format: int32
              example: 6
            propertyID:
              type: integer
              format: int32
              example: 16
            type:
              type: integer
              format: int32
              example: 1

## Properties that define a Zigbee broadcast
    ZigbeeBroadcast:
      required:
        - zigbee
      type: object
      properties:
        zigbee:
          required:
            - endpointID
            - clusterID
            - propertyID
            - value
          type: object
          properties:
            endpointID:
              type: integer
              format: int32
              example: 1
            clusterID:
              type: integer
              format: int32
              example: 6
            propertyID:
              type: integer
              format: int32
              example: 16
            type:
              type: integer
              format: int32
              example: 1
            value:
              type: integer
              format: int32
              example: 15

# Common objects
## A SCIM id, can be a  device or a group
    Id:
      required:
        - id
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4

## A SCIM object, can be a  device or a group
    Object:
      allOf:
        - $ref: '#/components/schemas/Id'
      type: object
      properties:
        type:
          type: string
          example: device
          enum:
            - device
            - group
        technology:
          type: string
          example: ble
          enum:
            - ble
            - zigbee

## A Service is a device with optional service IDs
    Service:
      allOf:
        - $ref: '#/components/schemas/Object'
      type: object
      properties:
        ble:
          type: object
          properties:
            services:
              type: array
              items:
                $ref: '#/components/schemas/BLEServiceID'
            cached:
              description: |-
                If we can cache information, then device doesn't need
                to be rediscovered before every connected.
              type: boolean
              default: false
            cacheIdlePurge:
              description: cache expiry period, when device allows
              type: integer
              example: 3600 # default 1 hour
            autoUpdate:
              description: |-
                autoupdate services if device supports it (default)
              type: boolean
              example: true
            bonding: #optional, by default defined in SCIM object 
              type: string
              example: default
              enum:
                - default 
                - none
                - justworks
                - passkey
                - oob

## A Connection
    Connection:
      allOf:
        - $ref: '#/components/schemas/Service'
      type: object
      properties:
        retries:
          type: integer
          format: int32
          example: 3
        retryMultipleAPs:
          type: boolean
          example: true

## A specific property of an Device
    PropertyRaw:
      allOf:
        - $ref: '#/components/schemas/Object'
      oneOf:
        - $ref: '#/components/schemas/BLEProperties'
        - $ref: '#/components/schemas/ZigbeeProperties'
      discriminator:
        propertyName: technology
        mapping:
          ble: '#/components/schemas/BLEProperties'
          zigbee: '#/components/schemas/ZigbeeProperties'

## A value of an property of an Device
    PropertyValueRaw:
      allOf:
        - $ref: '#/components/schemas/PropertyRaw'
      required:
        - value
      type: object
      properties:
        value:
          type: string
          format: byte
          example: 0001
        forcedResponse:
          description: do or do not wait for a response?
          type: boolean
          example: true
        
## An property ID
    PropertyID:
      required:
        - propertyID
      type: object
      properties:
        propertyID:
          type: string
          example: "temperature"
          
## A specific property of an Device
    Property:
      allOf:
        - $ref: '#/components/schemas/Object'
        - $ref: '#/components/schemas/PropertyID'

## A value of an property of an Device
    PropertyValue:
      allOf:
        - $ref: '#/components/schemas/Property'
      required:
        - value
      type: object
      properties:
        value:
          type: string
          format: byte
          example: 0001
        forcedResponse:
          description: do or do not wait for a response?
          type: boolean
          example: true
          
## An property registration
    PropertyRegistration:
      allOf:
        - $ref: '#/components/schemas/PropertyID'
      oneOf:
        - $ref: '#/components/schemas/BLEProperties'
        - $ref: '#/components/schemas/ZigbeeProperties'
      discriminator:
        propertyName: technology
        mapping:
          ble: '#/components/schemas/BLEProperties'
          zigbee: '#/components/schemas/ZigbeeProperties'

## A file-based property of an Device
    PropertyFile:
      allOf:
        - $ref: '#/components/schemas/Property'
      type: object
      properties:
        chunksize:
          type: integer
        forcedResponse:
          description: do or do not wait for a response?
          type: boolean
          example: true

## A binary blob-based property of an Device
    PropertyBlob:
      allOf:
        - $ref: '#/components/schemas/Property'
      required:
        - blob
      type: object
      properties:
        blob:
          type: string
          format: binary
        chunksize:
          type: integer
        forcedResponse:
          description: do or do not wait for a response?
          type: boolean
          example: true

## Conditional read of a value (read until specific value is read)
    PropertyConditional:
      allOf:
        - $ref: '#/components/schemas/Property'
      required:
        - value
      type: object
      properties:
        value:
          type: string
          format: byte
          example: 0001
        maxTime:
          description: |-
            maximum time the conditional read should run in seconds
            (default 10 sec, max 60 sec)
          type: integer
        maxRepeat:
          description: |-
           maximum time the conditional read should repeat
           (default 5, max 60)
          type: integer
        frequency:
          description: |-
            time between reads in seconds (default 1, max 60)
          type: integer

## A subscription property of an Device
    SubscriptionRaw:
      allOf:
        - $ref: '#/components/schemas/PropertyRaw'
      type: object
      properties:
        forcedAck:
          description: |-
            When not looking at device/property support MUST we
            ackhnowledge?
          type: boolean
          example: true

## A specific property of an Device
    Subscription:
      allOf:
        - $ref: '#/components/schemas/Object'
        - $ref: '#/components/schemas/PropertyID'
      type: object
      properties:
        forcedAck:
          description: |-
            When not looking at device/property support MUST we
            ackhnowledge?
          type: boolean
          example: true

## A broadcast
    Broadcast:
      allOf:
        - $ref: '#/components/schemas/Object'
      oneOf:
        - $ref: '#/components/schemas/BLEBroadcast'
        - $ref: '#/components/schemas/ZigbeeBroadcast'
      discriminator:
        propertyName: technology
        mapping:
          ble: '#/components/schemas/BLEBroadcast'
          zigbee: '#/components/schemas/ZigbeeBroadcast'
      required:
        - cycle
      type: object
      properties:
        cycle:
          type: string
          example: single
          enum:
            - single
            - repeat
        # broadcast time in ms
        broadcastTime:
          type: integer
          example: 3000
        # interval between broadcasts in ms
        broadcastInterval:
          type: integer
          example: 500
        # optional external broker config
        mqtt:
          type: object

## Event Name
    EventName:
      required:
        - event
      type: object
      properties:
        event:
          type: string
          example: enterprise/hospital/pulse_oximeter

## DataStream Event
    Event:
      allOf:
        - $ref: '#/components/schemas/EventName'  
        - $ref: '#/components/schemas/PropertyID'
      oneOf:
        - $ref: '#/components/schemas/BLEEvent'
        - $ref: '#/components/schemas/ZigbeeProperties'
      discriminator:
        propertyName: technology
        mapping:
          ble: '#/components/schemas/BLEEvent'
          zigbee: '#/components/schemas/ZigbeeProperties'
      type: object
      properties:
        eventFormat:
          description: |-
            How is information decorated?  Default: device
            and property ids.
          type: string
          example: default
          enum:
            - default
            - payload
        replay:
          type: boolean
          example: false
          default: false
        id:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4
        type:
          type: string
          example: device
          enum:
            - device
            - group
        dataApps:
          type: array
          items:
            type: object
            properties:
              dataAppID:
                type: string
                format: uuid
                example: 12345678-1234-5678-1234-56789abcdef4
              mqtt:
                type: object
                properties: 
                  brokerURI: 
                    type: string
                    example: mqtt.broker.com:8883
                  username:
                    type: string
                    example: user1
                  password: 
                    type: string
                    example: password1
                  brokerCACert: 
                    type: string
        technology:
          type: string
          example: ble
          enum:
            - ble
            - zigbee

## FileURL
    FileURL:
      required:
        - fileURL
      type: object
      properties:
        fileURL:
          type: string
          example: "https://domain.com/firmware.dat"
          
## FileBinary        
    FileBin:
      required:
        - fileBin
      type: object
      properties:
        fileBin:
          type: string
          format: binary
          example: "firmware.dat"

## File
    File:
      allOf:
        - $ref: '#/components/schemas/PropertyID'
      oneOf:
        - $ref: '#/components/schemas/FileURL'
        - $ref: '#/components/schemas/FileBin'

## Firmware
    Firmware:
      allOf:
        - $ref: '#/components/schemas/Property'
      type: object
      properties:
        upgradeType:
          type: string
          enum:
            - nordics
            - silabs
            - wiliot

## Defines an operation in a bulk API
    Operation:
      required:
        - operation
      allOf:
        - type: object
          properties:
            path:
              type: string
              enum:
               - /action/connection
               - /action/property
               - /action/property/subscription
               - /extension/property/write/file
               - /extension/property/write/blob
               - /extension/property/read/conditional
            method:
              type: string
              enum:
               - POST
               - DELETE
               - GET
        - oneOf:
            - $ref: '#/components/schemas/Object'
            - $ref: '#/components/schemas/Property'
            - $ref: '#/components/schemas/PropertyValue'
            - $ref: '#/components/schemas/PropertyConditional'
            - $ref: '#/components/schemas/PropertyFile'
            - $ref: '#/components/schemas/PropertyBlob'
            - $ref: '#/components/schemas/Subscription'
          discriminator:
            propertyName: operation
            mapping:
              POST /action/connection:
                '#/components/schemas/Service'
              DELETE /action/connection:
                '#/components/schemas/Object'
              GET /action/connection:
                '#/components/schemas/Object'
              POST /action/property:
                '#/components/schemas/PropertyValue'
              DELETE /action/property:
                '#/components/schemas/Property'
              GET /action/property:
                '#/components/schemas/Property'
              POST /action/property/Subscription:
                '#/components/schemas/Subscription'
              DELETE /action/property/Subscription:
                '#/components/schemas/Subscription'
              GET /action/property/Subscription:
                '#/components/schemas/Subscription'
              POST /extension/property/read/conditional:
                '#/components/schemas/PropertyConditional'
              POST /extension/property/write/file:
                '#/components/schemas/PropertyFile'
              POST /extension/property/write/blob:
                '#/components/schemas/PropertyBlob'

## Bulk schema
    Bulk:
      allOf:
        - $ref: '#/components/schemas/Object'
      type: object
      properties:
        autoDisconnect:
          description: |-
            do we automatically disconnect after a RESTful operation?
          type: boolean
          example: true
          default: true
        operations:
          type: array
          items:
            $ref: '#/components/schemas/Operation'

# responses
## Baseline success reponse
    Success:
      required:
        - status
      type: object
      properties:
        status:
          type: string
          example: SUCCESS
          enum:
            - SUCCESS
        requestID:
          type: string
          example: 12345678-5678-1234-5578-abcdef1234

    SuccessResponse:
      allOf:
        - $ref: '#/components/schemas/Success'
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 12345678-1234-5678-1234-56789abcdef4

## Error 500 application Failure response
    FailureResponse:
      required:
        - status
        - errorCode
      type: object
      properties:
        status:
          type: string
          example: FAILURE
          enum:
            - FAILURE
        reason:
          type: string
          example: Not Found
        errorCode:
          type: integer
          format: int32
          example: 12
        requestID:
          type: string
          example: 12345678-5678-1234-5578-abcdef1234

## Response, success or failure
    Response:
      oneOf:
        - $ref: '#/components/schemas/SuccessResponse'
        - $ref: '#/components/schemas/FailureResponse'

 ## Returns discovered services
    PropertyResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
      oneOf:
        - $ref: '#/components/schemas/BLEServiceslist'
        - $ref: '#/components/schemas/ZigbeeEndpointlist'

## Response to multiple connections
    MultiConnectionsResponse:
      allOf:
        - $ref: '#/components/schemas/Success'
      required:
        - connections
      type: object
      properties:
        connections:
          type: array
          items:
            $ref: '#/components/schemas/Response'

## Returns an property value
    PropertyValueResponseRaw:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
      required:
       - value
      type: object
      properties:
        value:
          type: string
          example: 01
          format: byte
          
## Returns an property value with ID
    PropertyValueResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
        - $ref: '#/components/schemas/PropertyID'
      required:
       - value
      type: object
      properties:
        value:
          type: string
          example: 01
          format: byte

## Returns an property registration
    PropertyRegistrationResponse:
      allOf:
        - $ref: '#/components/schemas/Success'
        - $ref: '#/components/schemas/PropertyRegistration'
        
## Returning multiple property registrations
    MultiPropertyRegistrationResponse:
      allOf:
        - $ref: '#/components/schemas/Success'
      required:
        - properties
      type: object
      properties:
        properties:
          type: array
          items:
            $ref: '#/components/schemas/PropertyRegistration'

## Returns a event
    EventResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
        - $ref: '#/components/schemas/Event'

## Returning multiple events
    MultiEventsResponse:
      allOf:
        - $ref: '#/components/schemas/Success'
      required:
        - events
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/Event'

## Returning multiple subscriptions
    MultiSubscriptionResponse:
      allOf:
        - $ref: '#/components/schemas/Success'
      required:
        - subscriptions
      type: object
      properties:
        subscriptions:
          type: array
          items:
            $ref: '#/components/schemas/Subscription'

## Multiple returns for a bulk operation
    BulkResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
      type: object
      properties:
        operations:
          type: array
          items:
            $ref: '#/components/schemas/OperationResponse'

## Return ofr a firmware upgrade operation
    FirmwareResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessResponse'
      type: object
      properties:
        upgradeStatus:
          type: string
          enum:
            - completed
            - in-progress
            - rolled-back
            - failed

## Return for an operation
    OperationResponse:
      required:
        - operation
      allOf:
        - type: object
          properties:
            operation:
              type: string
              enum:
               - /action/connection
               - /action/property
               - /action/property/subscription
               - /extension/property/write/file
               - /extension/property/write/blob
               - /extension/property/read/conditional
            type:  
              type: string
              enum:
               - POST
               - DELETE
               - GET
        - oneOf:
            - $ref: '#/components/schemas/SuccessResponse'
            - $ref: '#/components/schemas/PropertyResponse'
            - $ref: '#/components/schemas/PropertyValueResponse'
          discriminator:
            propertyName: operation
            mapping:
              POST /action/connection:
                '#/components/schemas/ServiceResponse'
              DELETE /action/connection:
                '#/components/schemas/SuccessResponse'
              GET /action/connection:
                '#/components/schemas/SuccessResponse'
              POST /action/property:
                '#/components/schemas/PropertyValueResponse'
              DELETE /action/property:
                '#/components/schemas/PropertyValueResponse'
              GET /action/property:
                '#/components/schemas/PropertyValueResponse'
              POST /action/property/Subscription:
                '#/components/schemas/SuccessResponse'
              DELETE /action/property/Subscription:
                '#/components/schemas/SuccessResponse'
              GET /action/property/Subscription:
                '#/components/schemas/SuccessResponse'
              POST /extension/property/read/conditional:
                '#/components/schemas/PropertyValueResponse'
              POST /extension/property/write/file:
                '#/components/schemas/SuccessResponse'
              POST /extension/property/write/blob:
                '#/components/schemas/SuccessResponse'

 # API key authorization
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
# Apply the API key globally to all operations
security:
  - ApiKeyAuth: []
<CODE ENDS>
]]></artwork></figure>

</section>


  </back>

<!-- ##markdown-source:
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
U+XKpE231przjPP5rn7vklekru+qFeNJP4mLM20rgMHemmxYuJXHmFp3ugmG
m2JOGsM9Ykyaz5otryd6N+OMjZnMZk7LWILVFmzTcLDGms3WbHan2Wx2Omwm
p1lHbTluc3zJRUB09C1/dJl6x7Q1txTQV7x/ii4zlM07oGxfF0m+zzz3spJ9
v6aLWu5zWn4tIq4TrUvn0WbKB0yJQQd00VKSrCghEEirYIjxXm2WC8LePSzd
imBm2I7NzRXmJpRclpM8lW0pubWUuOtSgrJxtIxrZ/p68nB119mU6F7U2tC1
NG3SAIPLyJBN8mQRMwPbf7DtG+pxiJL6U+ejdeXe7WX+tYlwR0yElTh6mYaN
in3Nx2s+XvPxfPUdhWXYhQFsfte/XZ4qb3cKqGZOdzjHQ3CV+3IQ23X8Pny4
a76bJR4qIPFnnoRQGXNodBNi4qwsx8XOplnY7vYdFApry/4KkXsFKv4CnL5C
+xaFv2Zq+lkz9Zqp2/X9EntlLkPHz6ypX0Kzz9pHo9h/XVS/FgJrIXDNmn2h
PTPLAGjR7WvmXjP3mrnnaPjFb5VasJwtrZ5K0+ajNzWhKy0nhcQknbKed48O
dW+NRW1Hfm83foipg6V7VH/TNL01u96Nqre0+cjgOexpW8tv0Ab3ZMwC45fV
UNsmmllz6WJTW3NpE2ZvM5dewC/WN0QtwaiLNWlwfGcw5SwzWffipNDwZ25d
ixkdNlzSar7qApd7chPKmtmvEsuX6x6DS1say1VGmj1ic2XxrJK3sKHlVOe1
8WxN7TubVha8KovDLwsYDiKqpSQWgNwHGXE56fM7LiLIt17LidvladszyZHe
Ly+q3mIKzKqYWa7pgtbEwlU0M+TFrCDcEqfYXn49zR0XCGtZcPdsBtLqKzD3
Eu2qBsBuWcZ5f1LKNV+v+XrN18uctd+i84GEF7gwcdEQeyQmYObSfWQImKLm
SYjvJkWjLFiybWOg/S18bVjjZsJ3OIR7FK5bH+pwRYhtPtThwF71h4xqbtyr
3Gu6IK/WLg6sXXBK7FW5KTAc5FlR2H2q1OOiV5suDdDjY4JyC5hY66o1M6+Z
eRHENnrWrczbT7L+RZi3ge36cQqvBEK+VHZeFW6dq98AiFvC1TiUNVevuXoe
YhflarwIGNqnUYzdh8kl8bZ3my+dU9h0SKGYpGWciLgUo7CEgRciNBDMzb0E
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
AgA=

-->

</rfc>

