|
| 1 | +*Copyright (C) 2026, Axis Communications AB, Lund, Sweden. All Rights Reserved.* |
| 2 | + |
| 3 | +# ACAP application that subscribes to Device Data Hub |
| 4 | + |
| 5 | +This application subscribes to a topic using the [Device Data Hub API](https://developer.axis.com/acap/api/#device-data-hub-api) created by another application and logs the received data. |
| 6 | +It is part of the acap-communication example. For context, start by reading the README for the object_detector application. |
| 7 | + |
| 8 | +## Project structure |
| 9 | + |
| 10 | +The files for building the application are organized in the following structure. |
| 11 | + |
| 12 | +```sh |
| 13 | +object-consumer |
| 14 | +├── app |
| 15 | +│ ├── LICENSE |
| 16 | +│ ├── Makefile |
| 17 | +│ ├── manifest.json |
| 18 | +│ └── object_consumer.c |
| 19 | +├── Dockerfile |
| 20 | +└── README.md |
| 21 | +``` |
| 22 | + |
| 23 | +- **app/LICENSE** - Open source licensed source code distributed with the specified application. |
| 24 | +- **app/Makefile** - Build and link instructions for the specified application. |
| 25 | +- **app/manifest.json** - Definition of the *object_consumer* application and its configuration. |
| 26 | +- **app/object_consumer.c** - Source code for the *object_consumer* application. |
| 27 | +- **Dockerfile** - Dockerfile with the specified Axis toolchain and API container to build the application specified. |
| 28 | +- **README.md** - Step by step instructions on how to run the *object_consumer* application. |
| 29 | + |
| 30 | +## Program structure and behavior |
| 31 | + |
| 32 | +### Connecting to Device Data Hub |
| 33 | + |
| 34 | +The application creates a Device Data Hub client and connects to the service. The `dh_client_connect` function uses the current Linux user as the username, which in this case is *acap-object_consumer*. |
| 35 | + |
| 36 | +### Subscribing to a topic |
| 37 | + |
| 38 | +The application creates a `DHSubscriber` to subscribe to *acap.object_detector*. |
| 39 | +The functions of `DHSubscriberListener` listener struct handles incoming data by logging it. |
| 40 | + |
| 41 | +> [!NOTE] |
| 42 | +> You can subscribe to topics that don't exist yet. Data will arrive once the topic is created and |
| 43 | +> published to. |
| 44 | +
|
| 45 | +## Access rights |
| 46 | + |
| 47 | +By default, an ACAP application can only access its own topics (prefixed with `acap.<appname>`) and |
| 48 | +public topics. Since *acap.object_detector* belongs to another application, this application needs |
| 49 | +permission to read from it. |
| 50 | + |
| 51 | +The *object_detector* application grants this permission in its manifest, |
| 52 | +giving *acap-object_consumer* read access to *acap.object_detector* and all sub-topics. |
| 53 | + |
| 54 | +## The manifest |
| 55 | + |
| 56 | +To be able to connect to Device Data Hub, enable Device Data Hub in the manifest: |
| 57 | + |
| 58 | +```json |
| 59 | +"resources": { |
| 60 | + "deviceDataHub_beta2": { |
| 61 | + "enabled": true |
| 62 | + } |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +The application will get access rights to create, delete, write to and subscribe to the topic |
| 67 | +*acap.object_consumer* and all topics that have this topic as a prefix. However, this |
| 68 | +application never creates any such topic. Instead, the application subscribes to the topic |
| 69 | +*acap.object_detector*. The access rights to read data from that topic is given to this |
| 70 | +application by the *object_detector* application. |
| 71 | + |
| 72 | +## Build the application |
| 73 | + |
| 74 | +> [!NOTE] |
| 75 | +> |
| 76 | +> For detailed information on how to build, install, and run ACAP applications, refer to the official ACAP documentation: [Build, install, and run](https://developer.axis.com/acap/develop/build-install-run/). |
| 77 | +> |
| 78 | +> Depending on the network your local build machine is connected to, you may need to add proxy |
| 79 | +> settings for Docker. See |
| 80 | +> [Proxy in build time](https://developer.axis.com/acap/develop/proxy/#proxy-in-build-time). |
| 81 | +
|
| 82 | +Standing in your working directory, run the following commands: |
| 83 | + |
| 84 | +```sh |
| 85 | +docker build --platform=linux/amd64 --build-arg ARCH=<ARCH> --tag <APP_IMAGE> . |
| 86 | +``` |
| 87 | + |
| 88 | +- `<ARCH>` is the SDK architecture, `armv7hf` or `aarch64`. |
| 89 | +- `<APP_IMAGE>` is the name to tag the image with, e.g., `consumer:1.0` |
| 90 | + |
| 91 | +Copy the result from the container image to a local directory `build`: |
| 92 | + |
| 93 | +```sh |
| 94 | +docker cp $(docker create --platform=linux/amd64 <APP_IMAGE>):/opt/app ./build |
| 95 | +``` |
| 96 | + |
| 97 | +The `build` directory contains the build artifacts, where the ACAP application |
| 98 | +is found with the suffix `.eap`. Depending on which SDK architecture that was |
| 99 | +chosen, one of the following files should be found: |
| 100 | + |
| 101 | +- `object_consumer_1_0_0_aarch64.eap` |
| 102 | +- `object_consumer_1_0_0_armv7hf.eap` |
| 103 | + |
| 104 | +## Install and start the application |
| 105 | + |
| 106 | +Browse to the application page of the Axis device: |
| 107 | + |
| 108 | +```sh |
| 109 | +http://<AXIS_DEVICE_IP>/index.html#apps |
| 110 | +``` |
| 111 | + |
| 112 | +- Click on the tab `Apps` in the device GUI |
| 113 | +- Enable `Allow unsigned apps` toggle |
| 114 | +- Click `(+ Add app)` button to upload the application file |
| 115 | +- Browse to the newly built ACAP application, and select it |
| 116 | +- Click `Install` |
| 117 | +- Run the application by enabling the `Start` switch |
| 118 | + |
| 119 | +## Expected output |
| 120 | + |
| 121 | +To find the application log, browse to the *Apps* page, click on the |
| 122 | +three dots to the right of the application and select `App log`. |
| 123 | + |
| 124 | +If the *object_detector* application has also started, you will see |
| 125 | +messages about the received data in the log. Each message contains an object |
| 126 | +(human, bird or dog) and a distance. |
| 127 | + |
| 128 | +The log output may look like this: |
| 129 | + |
| 130 | +```text |
| 131 | +[log prefix] object_consumer[429721]: Application started |
| 132 | +[log prefix] Received Object Detection data: {"distance":99,"object":"human"} |
| 133 | +[log prefix] Received Object Detection data: {"distance":105,"object":"bird"} |
| 134 | +[log prefix] Received Object Detection data: {"distance":102,"object":"dog"} |
| 135 | +[log prefix] Received Object Detection data: {"distance":98,"object":"human"} |
| 136 | +[log prefix] Received Object Detection data: {"distance":110,"object":"bird"} |
| 137 | +[log prefix] Received Object Detection data: {"distance":104,"object":"dog"} |
| 138 | +[log prefix] object_consumer[429721]: Application terminated |
| 139 | +``` |
| 140 | + |
| 141 | +## License |
| 142 | + |
| 143 | +**[MIT License](./app/LICENSE)** |
0 commit comments