# MQTT API

## MQTT Topics

Using the MQTT end-point publishes these topics:

|PATH |Description|
|-----|-----------|
|`sensor/[ID]/telemetry`&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|EnOcean device telemetry of a specific [ID]. Publishing is done every time a valid telegram was processed. Payload consists of JSON file described in [here](#sensor-telemetry).|
|`sensor/[ID]/meta/event/`|Event information of a specific [ID]. Publishing is done with a specific event. Reference of possible events and content of JSON files cab be found [here](#sensor-meta).|
|`sensor/[ID]/meta/stats/`|Statical information about traffic of a specific [ID]. Publishing is done in predefined time internal e.g. 10 min. Interval can be configured. This feature is optional. Configuration is done via [ENV](deployment-notes.md#overview-of-environment-variables) variables. Published JSON Payload can be reviewed [here](#sensor-meta).|
|`gateway/[MAC]/meta/event/`|Event information of a specific gateway [MAC]. Publishing is done with a specific event. Reference of possible events and more can be found [here](#gateway-meta).|
|`gateway/[MAC]/meta/stats/`|Statical information about traffic of a specific gateway [MAC]. Publishing is done in predefined time internal e.g. 10 min. Interval can be configured. This feature is optional. Configuration is done via [ENV](deployment-notes.md#overview-of-environment-variables) variables. Published JSON Payload can be reviewed [here](#gateway-meta).|
|`system/health/`|Statical information about IoTC health status. Publishing is done in predefined time internal e.g. 10 min. Interval can be configured via [ENV](./deployment-notes.md#overview-of-environment-variables) variables. Published JSON Payload can be reviewed [here](#system-health).|
|`device/[ID]/rpc/command`|Topic for queueing new commands. Detailed information can be found [here](./bidirectional/mqtt-interface.md)|
|`device/[ID]/rpc/cancel`|Topic for deleting waiting commands. Detailed information can be found [here](./bidirectional/mqtt-interface.md)|
|`device/[ID]/rpc/result`|Topic for results of requests. Detailed information can be found [here](./bidirectional/mqtt-interface.md)|

<!-- ### Customize MQTT

The above described topic PATHs can be customized to fit the target topic space. Customization is done via [ENV](deployment-notes.md#overview-of-environment-variables) variables at deployment time. -->

## JSON Output Format

All Schemas of all JSON outputs can be found in the [download](./downloads.md) section.

!!! Note
    All timestamps in IoTC are in the Unix epoch (or Unix time or POSIX time or Unix timestamp). It is the number of seconds that have elapsed since January 1, 1970. It can be converted into human-readable version quite easy. e.g. use an [online convertor](https://www.epochconverter.com/).

    `timestamp = 1624367607`  equals to `GMT: Tuesday, June 22, 2021 1:13:27 PM`

### Sensor telemetry

Each output JSON consist of these sections:

- `sensor` - stored information about the sensor provided at [onboarding](./deploy-the-iotc.md#3-onboard-devices-using-the-api) via the API
- `telemetry` - information interpreted by the engine
    - `data` - sensor data included in the message and encoded via the [EEP](http://tools.enocean-alliance.org/EEPViewer/)
    - `signal` - meta information about the sensor and encoded as [signal telegram](https://www.enocean-alliance.org/st/)
    - `meta/stats` - meta information about the message added by the engine
- `raw` - raw message information
    - `rssi` - radio signal strength information. Important to track radio quality



#### telemetry -> data

The data is included in a JSON file as `key-value` pairs following the [EnOcean Alliance IP Specification](http://tools.enocean-alliance.org/EEPViewer/). Example JSON outputs from selected devices are available below.

=== "Multisensor"

    EnOcean IoT [Multisensor](https://www.enocean.com/en/products/enocean_modules/iot-multisensor-emsia-oem/)
    
    ```json
    {
        "sensor": {
            "friendlyId": "Multisensor 1",
            "id": "04138bb4",
            "location": "Cloud center"
        },
        "telemetry": {
            "data": [{
                "key": "temperature",
                "value": 23.9,
                "unit": "°C"
            }, {
                "key": "humidity",
                "value": 29.0,
                "unit": "%"
            }, {
                "key": "illumination",
                "value": 67.0,
                "unit": "lx"
            }, {
                "key": "accelerationStatus",
                "value": "heartbeat",
                "meaning": "Heartbeat"
            }, {
                "key": "accelerationX",
                "value": -0.13,
                "unit": "g"
            }, {
                "key": "accelerationY",
                "value": 0.08,
                "unit": "g"
            }, {
                "key": "accelerationZ",
                "value": -0.97,
                "unit": "g"
            }, {
                "key": "contact",
                "value": "open",
                "meaning": "Window opened"
            }],
            "signal": [],
            "meta": {
                "stats": [{
                    "egressTime": "1611927479.169171",
                    "notProcessed": 0,
                    "succesfullyProcessed": 6,
                    "totalTelegramCount": 6
                }]
            }
        },
        "raw": {
            "data": "d29fce800863b502a620",
            "sender": "04138bb4",
            "status": "80",
            "subTelNum": 0,
            "destination": "ffffffff",
            "rssi": 77,
            "securityLevel": 0,
            "timestamp": "1611927479.166352"
        }
    }
    ```

=== "CO2 sensor"

    ```json
    {
        "sensor": {
            "friendlyId": "co2_Hardware2",
            "id": "051b03c9",
            "location": "Hardware 2"
        },
        "telemetry": {
            "data": [{
                "key": "co2",
                "value": 627.45,
                "unit": "ppm"
            }, {
                "key": "learn",
                "value": "notPressed",
                "meaning": "Data telegram"
            }, {
                "key": "powerFailureDetected",
                "value": "False",
                "meaning": "Power failure not detected"
            }],
            "signal": [],
            "meta": {
                "stats": [{
                    "egressTime": "1611927535.0731573",
                    "notProcessed": 0,
                    "succesfullyProcessed": 6,
                    "totalTelegramCount": 6
                }]
            }
        },
        "raw": {
            "data": "a500005008",
            "sender": "051b03c9",
            "status": "01",
            "subTelNum": 0,
            "destination": "ffffffff",
            "rssi": 80,
            "securityLevel": 0,
            "timestamp": "1611927535.0714777"
        }
    }
    ```

=== "Switch Module"
    [PTM215](https://www.enocean.com/en/products/enocean_modules/ptm-210ptm-215/) battery-less switch module

    ```json
    {
        "sensor": {
            "friendlyId": "switch1",
            "id": "feee14ab",
            "location": "Entrance"
        },
        "telemetry": {
            "data":
            [{
                "key": "energybow",
                "value": "released",
                "meaning": "Energy Bow released"
            }],
            "signal": [],
            "meta": {
                "stats": [{
                    "egressTime": "1611927462.4711452",
                    "notProcessed": 0,
                    "succesfullyProcessed": 6,
                    "totalTelegramCount": 6
                }]
            }
        },
        "raw": {
            "data": "f600",
            "sender": "feee14ab",
            "status": "20",
            "subTelNum": 0,
            "destination": "ffffffff",
            "rssi": 71,
            "securityLevel": 0,
            "timestamp": "1611927462.469978"
        }
    }
    ```

#### telemetry -> signal

Selected devices from EnOcean transmit additionally to their data messages also messages about their internal states or events. This messages are known as signal telegrams. [Signal telegrams](https://www.enocean-alliance.org/st/) include information about the:

- percentage of remaining energy available in the energy storage
- how much energy is provided via the energy harvester
- availability and status of a back up energy store
- for additional information see the [signal telegrams](https://www.enocean-alliance.org/st/) specification and data sheet of your EnOcean product

Example of an energy `MID: 6` signal telegram is below:

```json
{
    "sensor": {
        "friendlyID": "0413D759 D2-14-41 SIMU Multisensor",
        "id": "0413d759",
        "location": "Office 265",
        "eep": "d2-14-41",
        "customTag": ""
    },
    "telemetry": {
        "data": [],
        "signal": [{
            "key": "signalIdentifier",
            "value": "0x6",
            "meaning": "Energy status of device"
        }, {
            "key": "energy",
            "value": 56.0,
            "unit": "%"
        }],
        "meta": {
            "stats": [{
                "egressTime": "1638876910.137704",
                "notProcessed": 0,
                "succesfullyProcessed": 6,
                "totalTelegramCount": 6
            }]
        }
    },
    "raw": {
        "uuid": "f521f37c-3a82-42cb-b1cc-c889e946cef3",
        "data": "d00638",
        "sender": "0413d759",
        "status": 128,
        "subTelNum": 1,
        "destination": "ffffffff",
        "rssi": -64,
        "securityLevel": 0,
        "timestamp": "1638876903",
        "subTimestamp": 0,
        "subtelegrams": []
    }
}
```
#### telemetry -> meta
The `meta` section is complementary to `data` and `signal`. The meta section includes the `stats` section as provided by the [API](#sensor-gateway-telegram-statistics) for the referenced device. Additionally the egress timestamp is included.

Examples are visible with the above examples with `data` and `signal`.

#### raw -> rssi

The `raw` element includes the radio telegram Information as received by the IoTC. They are mostly included for tracking and debug purposes. The `rssi` is the only one of interest.

The `rssi` radio signal strength information provides important information about connectivity. We recommend to track it and raise and alarm if the level drops or changes significantly.

### Sensor meta

#### event
The IoT Connector provides important information about events that were detected in regard to the sensor status, data transmission or behavior.

There are these types of events:

|Type| Event | Description|
|-|-|-|
|Security |`MAC_VALIDATION_ERROR`&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|A received message could not be authentificated with the included CMAC. This could be an indication for a security attack.|
||`RLC_REPLAY`|A received message has a lower message sequence counter then the previous. This could e an indication for an replay attack.|
||`DEVICE_SEND_NOW_UNSECURE`|A device which was onboarded as secure is now transmitting as non secure. This is an indication of compromision the set security level, possible attack.|
|Health |`FIRST_TIME_SEND`|An onboarded device transmitted for the first time.
|Processing|`EEP_DECODE_ERROR`|The receive message could not be decoded with the specified EEP. This is an indication for an corrupted radio message (if occuring on limited basis) or wrong specified EEP (if occuring pernament).
||`EEP_NOT_FOUND_ERROR`|The specified EEP of an device is not know to the IoTC. Please contact [support](./support.md) in such case.|

Example of an Health `FIRST_TIME_SEND` message is below:

```json
{
  "sensor": {
    "friendlyID": "Multisensor 1",
    "id": "04138d23",
    "location": "Cloud center",
    "eep": "d2-14-41",
    "customTag": ""
  },
  "meta": {
    "events": {
      "security": [],
      "health": [
        {
          "code": "FIRST_TIME_SEND",
          "message": "First time send of device with id=04138d23."
        }
      ],
      "transcoding": []
    },
     "stats": {
         "timestamp": "1637770981"
    }
  }
}
```

#### stats

The telegrams `stats` of individual EnOcean devices are posted periodically. This should indicate their operational status and additionally provide operational updates.

Example of an stats message is listed below:

```json
{
  "sensor": {
    "friendlyID": "Multisensor 1",
    "id": "04138d23",
    "location": "Cloud center",
    "eep": "d2-14-41",
    "customTag": ""
  },
  "meta": {
     "stats": {
      "lastSeen": "1637827538",
      "notProcessed": 1,
      "succesfullyProcessed": 6,
      "totalTelegramCount": 0
      }
    }
  }
}
```

The content of the `stats` section corresponds to the response of the device telegram statics [API request](#sensor-gateway-telegram-statistics).

### Gateway meta

#### event
Selected AP (e.g. Aruba AP) transmits meta information about their internal states referenced as Gateway Health Updates. The content is similar to the [console log](./support.md#console-log-messages) messages.

The purpose of this message includes these two use cases:
-	Still-alive message from the gateway. Know the gateway is operation.
-	EnOcean USB Dongle information of the gateway. Know the USB Dongle is correctly operating.

Example of an meta event of gateways is listed below:

```json
{
  "gateway_info": {
    "mac": "aabbccddeeff",
    "softwareVersion": "8.8.0.0",
    "hardwareDescriptor": "AP-505"
  },
  "stats": {
    "timestamp": "1639039720"
  },
  "usb_info": [
    {
      "usb_identifier": "ENOCEAN_USB:deb480d77718bbbe5253896b9300acfd",
      "usb_health": "healthy"
    }
  ]
}
```

#### stats

The telegrams `stats` of individual gateways are posted periodically. This should indicate their operational status and additionally provide operational updates.

Example of an stats message is listed below:

```json
{
  "gateway_info": {
    "mac": "aabbccddeeff",
    "softwareVersion": "8.8.0.0",
    "hardwareDescriptor": "AP-505"
  },
  "stats": {
      "lastSeen": "1637827538",
      "notProcessed": 0,
      "succesfullyProcessed": 6,
      "totalTelegramCount": 6
  }

}
```

The content of the `stats` section corresponds to the response of the gateway telegram statics [API request](#sensor-gateway-telegram-statistics).

### System health

IoTC periodically checks the status of the containers to validate correct operation of IoTC. After each check, a system health notification is sent on MQTT to notify the application of the IoTC status. The application should examine the health notification and notify the system administrator in case issues are observed. The application should also use the periodic health notification as a keep alive and expect issues if the health notifications are not received. 

Example of the system health event is listed below:

```json
{
  "gateway_info": [
    {
      "mac": "a1b2c3d4e5f6",
      "status": "healthy",
      "timestamp": "2022-05-18T09:25:33Z"
    }
  ],
  "system_health": {
    "api": "running",
    "ingress": "running",
    "integration": "running",
    "mqtt": "running",
    "redis": "running"
  }
}
```