Skip to content

Commit e9f88ed

Browse files
lukasz-serafinLukasz SerafinLukasz SerafinStiv-workSeyfullah Ari
committed
Create nexus directory with examples
Co-authored-by: Lukasz Serafin <lukaszs@axis.com> Co-authored-by: Lukasz Serafin <lukasz.serafin@axis.com> Co-authored-by: Stiv Abdullwahed <stiva@axis.com> Co-authored-by: Seyfullah Ari <seyfulla@axis.com> Co-authored-by: Johan Hultberg <johanol@axis.com>
1 parent 25fc5fd commit e9f88ed

23 files changed

Lines changed: 1320 additions & 0 deletions

File tree

.github/workflows/nexus.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Build nexus applications
2+
on:
3+
workflow_dispatch:
4+
push:
5+
paths:
6+
- 'nexus/**'
7+
- '!nexus/README.md'
8+
- '.github/workflows/nexus.yml'
9+
jobs:
10+
test-app:
11+
name: Test app
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
axis-os: ["12.8.54"]
17+
arch: ["armv7hf", "aarch64"]
18+
env:
19+
EXREPO: acap-native-examples
20+
EXNAME: nexus
21+
steps:
22+
- uses: actions/checkout@v5
23+
- uses: docker/setup-buildx-action@v3
24+
25+
- name: Build ${{ env.example }} application
26+
env:
27+
example: object-detector
28+
imagetag: ${{ env.EXREPO }}_object-detector:${{ matrix.arch }}
29+
run: |
30+
docker image rm -f $imagetag
31+
cd $EXNAME/acap-communication/$example
32+
docker build --no-cache --tag $imagetag --build-arg ARCH=${{ matrix.arch }} .
33+
docker cp $(docker create $imagetag):/opt/app ./build
34+
cd ../../..
35+
docker image rm -f $imagetag
36+
37+
- name: Build ${{ env.example }} application
38+
env:
39+
example: object-consumer
40+
imagetag: ${{ env.EXREPO }}_object-consumer:${{ matrix.arch }}
41+
run: |
42+
docker image rm -f $imagetag
43+
cd $EXNAME/acap-communication/$example
44+
docker build --no-cache --tag $imagetag --build-arg ARCH=${{ matrix.arch }} .
45+
docker cp $(docker create $imagetag):/opt/app ./build
46+
cd ../../..
47+
docker image rm -f $imagetag
48+
49+
- name: Build ${{ env.example }} application
50+
env:
51+
example: memory-cpu-utilization
52+
imagetag: ${{ env.EXREPO }}_memory-cpu-utilization:${{ matrix.arch }}
53+
run: |
54+
docker image rm -f $imagetag
55+
cd $EXNAME/$example
56+
docker build --no-cache --tag $imagetag --build-arg ARCH=${{ matrix.arch }} .
57+
docker cp $(docker create $imagetag):/opt/app ./build
58+
cd ../..
59+
docker image rm -f $imagetag

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ The examples are organized into logical groups to help you find the most relevan
118118
- An example in C that illustrates how to check the licensekey status.
119119
- [message-broker](./message-broker/)
120120
- Examples that showcase how to use the Message Broker API.
121+
- [nexus](./nexus/)
122+
- Examples that showcase how to use the Nexus API.
121123
- [reproducible-package](./reproducible-package/)
122124
- An example of how to create a reproducible application package.
123125
- [shell-script-example](./shell-script-example)

nexus/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Axis Communications AB
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

nexus/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
*Copyright (C) 2025, Axis Communications AB, Lund, Sweden. All Rights Reserved.*
2+
3+
# ACAP applications using the Nexus API
4+
5+
This directory contains ACAP application examples that interact with the Nexus API.
6+
7+
## About the Nexus API
8+
9+
Nexus is a publish/subscribe system in AXIS OS. It uses a model which focuses on the data as
10+
the primary element of interaction. This model enables asynchronous communication and decoupling
11+
of producers and consumers. Nexus is not intended to be used for streaming binary data.
12+
13+
An example of a real-world scenario where Nexus would be used is when clients are interested in
14+
information on objects detected by the camera. Information such as object type, position, shape
15+
and color can be published on Nexus, and clients interested in this type of information can
16+
subscribe on Nexus to get this information.
17+
18+
## Example applications
19+
20+
Each example has a README file in its directory which gives an introduction to the
21+
example, shows the directory structure and gives step-by-step instructions on how
22+
to run the application on an Axis device.
23+
24+
- [ACAP Communication](./acap-communication/README.md)
25+
- This example consists of two applications that communicate with each other.
26+
- [Memory and CPU Utilization](./memory-cpu-utilization/README.md)
27+
- This example subscribes to two topics and prints the memory and CPU utilization.
28+
29+
## Nexus API documentation
30+
31+
[Link to documentation](https://developer.axis.com/acap/api/src/api/nexus-client-cpp/html/index.html)
32+
33+
## License
34+
35+
**[MIT License](./LICENSE)**

nexus/acap-communication/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
*Copyright (C) 2025, Axis Communications AB, Lund, Sweden. All Rights Reserved.*
2+
3+
# Asynchronous communication between two applications
4+
5+
This is an example that shows the communication between two applications, one that
6+
writes data to a topic and another that receives the data written to the topic. The two
7+
applications in this example are *object_detector* and *object_consumer*.
8+
9+
## Introduction
10+
11+
The purpose of this example is to show the communication between two applications that
12+
use the Nexus library. The application *object_detector* will create a topic and then
13+
write data to the topic if there are any consumers. The application *object_consumer*
14+
will subscribe to the topic and print the received data to the system log.
15+
16+
[Link to *object_detector*](./object-detector/README.md)
17+
18+
[Link to *object_consumer*](./object-consumer/README.md)
19+
20+
## How to run this example
21+
22+
1. First, read and build [object_detector](./object-detector/README.md) - this creates the topic and publishes data.
23+
2. Then, read and build [object_consumer](./object-consumer/README.md) - this subscribes and receives data.
24+
3. Install both applications on the same Axis device.
25+
4. Start the applications.
26+
27+
## Directory structure
28+
29+
The files for building the example are organized in the following structure.
30+
31+
```sh
32+
acap-communication
33+
├── object-consumer
34+
│ ├── app
35+
│ │ ├── LICENSE
36+
│ │ ├── Makefile
37+
│ │ ├── manifest.json
38+
│ │ └── object_consumer.cpp
39+
│ ├── Dockerfile
40+
│ └── README.md
41+
├── object-detector
42+
│ ├── app
43+
│ │ ├── LICENSE
44+
│ │ ├── Makefile
45+
│ │ ├── manifest.json
46+
│ │ └── object_detector.cpp
47+
│ ├── Dockerfile
48+
│ └── README.md
49+
└── README.md
50+
```
51+
52+
- **object-consumer/app/LICENSE** - List of all open source licensed source code distributed with the specified application.
53+
- **object-consumer/app/Makefile** - Build and link instructions for the specified application.
54+
- **object-consumer/app/manifest.json** - Definition of the *object_consumer* application and its configuration.
55+
- **object-consumer/app/object_consumer.cpp** - Source code for the *object_consumer* application.
56+
- **object-consumer/Dockerfile** - Dockerfile with the specified Axis toolchain and API container to build the application specified.
57+
- **object-consumer/README.md** - Step by step instructions on how to run the *object_consumer* application.
58+
- **object-detector/app/LICENSE** - List of all open source licensed source code distributed with the specified application.
59+
- **object-detector/app/Makefile** - Build and link instructions for the specified application.
60+
- **object-detector/app/manifest.json** - Definition of the *object_detector* application and its configuration.
61+
- **object-detector/app/object_detector.cpp** - Source code for the *object_detector* application.
62+
- **object-detector/Dockerfile** - Dockerfile with the specified Axis toolchain and API container to build the application specified.
63+
- **object-detector/README.md** - Step by step instructions on how to run the *object_detector* application.
64+
- **README.md** - Information about the *acap-communication example*.
65+
66+
## Nexus API documentation
67+
68+
[Link to documentation](https://developer.axis.com/acap/api/src/api/nexus-client-cpp/html/index.html)
69+
70+
## License
71+
72+
**[MIT License](../LICENSE)**
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ARG ARCH=armv7hf
2+
ARG VERSION=12.8.0-rc.1
3+
ARG UBUNTU_VERSION=24.04
4+
ARG REPO=axisecp
5+
ARG SDK=acap-native-sdk
6+
7+
FROM ${REPO}/${SDK}:${VERSION}-${ARCH}-ubuntu${UBUNTU_VERSION}
8+
9+
# Build the ACAP application
10+
COPY ./app /opt/app/
11+
WORKDIR /opt/app
12+
RUN . /opt/axis/acapsdk/environment-setup* && acap-build .
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
*Copyright (C) 2025, Axis Communications AB, Lund, Sweden. All Rights Reserved.*
2+
3+
# ACAP application that subscribes on Nexus
4+
5+
This application is part of the *acap-communication* example. It is recommended to first
6+
read the README file of the *object_detector* application.
7+
8+
## Introduction
9+
10+
This application subscribes to a topic created by another application and logs the received data.
11+
12+
### Connecting to Nexus
13+
14+
The application creates a client and connects. The `Connect` function uses the current Linux user as
15+
the username, which in this case is *acap-object_consumer*.
16+
17+
### Subscribing to a topic
18+
19+
The application creates a `TopicDataSubscriber` to subscribe to *acap.object_detector*.
20+
The `ObjectLogger` listener class handles incoming data by logging it.
21+
22+
> [!NOTE]
23+
> You can subscribe to topics that don't exist yet. Data will arrive once the topic is created and
24+
> published to.
25+
26+
## Access rights
27+
28+
By default, an ACAP application can only access its own topics (prefixed with `acap.<appname>`) and
29+
public topics. Since *acap.object_detector* belongs to another application, this application needs
30+
permission to read from it.
31+
32+
The *object_detector* application grants this permission in its manifest,
33+
giving *acap-object_consumer* read access to *acap.object_detector* and all sub-topics.
34+
35+
## The manifest
36+
37+
To be able to connect to Nexus, enable Nexus in the manifest:
38+
39+
```json
40+
"resources": {
41+
"nexus_beta1": {
42+
"enabled": true
43+
}
44+
}
45+
```
46+
47+
The application will get access rights to create, delete, write to and subscribe to the topic
48+
*acap.object_consumer* and all topics that have this topic as a prefix. However, this
49+
application never creates any such topic. Instead, the application subscribes to the topic
50+
*acap.object_detector*. The access rights to read data from that topic is given to this
51+
application by the *object_detector* application.
52+
53+
## Nexus API documentation
54+
55+
[Link to documentation](https://developer.axis.com/acap/api/src/api/nexus-client-cpp/html/index.html)
56+
57+
## Build the application
58+
59+
> [!NOTE]
60+
>
61+
> 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/).
62+
>
63+
> Depending on the network your local build machine is connected to, you may need to add proxy
64+
> settings for Docker. See
65+
> [Proxy in build time](https://developer.axis.com/acap/develop/proxy/#proxy-in-build-time).
66+
67+
Standing in your working directory, run the following commands:
68+
69+
```sh
70+
docker build --platform=linux/amd64 --build-arg ARCH=<ARCH> --tag <APP_IMAGE> .
71+
```
72+
73+
- `<ARCH>` is the SDK architecture, `armv7hf` or `aarch64`.
74+
- `<APP_IMAGE>` is the name to tag the image with, e.g., `consumer:1.0`
75+
76+
Copy the result from the container image to a local directory `build`:
77+
78+
```sh
79+
docker cp $(docker create --platform=linux/amd64 <APP_IMAGE>):/opt/app ./build
80+
```
81+
82+
The `build` directory contains the build artifacts, where the ACAP application
83+
is found with the suffix `.eap`. Depending on which SDK architecture that was
84+
chosen, one of following files should be found:
85+
86+
- `object_consumer_1_0_0_aarch64.eap`
87+
- `object_consumer_1_0_0_armv7hf.eap`
88+
89+
## Install and start the application
90+
91+
Browse to the application page of the Axis device:
92+
93+
```sh
94+
http://<AXIS_DEVICE_IP>/index.html#apps
95+
```
96+
97+
- Click on the tab `Apps` in the device GUI
98+
- Enable `Allow unsigned apps` toggle
99+
- Click `(+ Add app)` button to upload the application file
100+
- Browse to the newly built ACAP application, and select it
101+
- Click `Install`
102+
- Run the application by enabling the `Start` switch
103+
104+
## Expected output
105+
106+
To find the application log, browse to the *Apps* page, click on the
107+
three dots to the right of the application and select `App log`.
108+
109+
If the *object_detector* application has also started, you will see
110+
messages about the received data in the log. Each message contains an object
111+
(human, bird or dog) and a distance.
112+
113+
The log output may look like this:
114+
115+
```text
116+
[log prefix] object_consumer[429721]: Application started
117+
[log prefix] object_consumer[429721]: Received data: {"distance":90,"object":"human"}
118+
[log prefix] object_consumer[429721]: Received data: {"distance":150,"object":"bird"}
119+
[log prefix] object_consumer[429721]: Received data: {"distance":120,"object":"dog"}
120+
[log prefix] object_consumer[429721]: Received data: {"distance":89,"object":"human"}
121+
[log prefix] object_consumer[429721]: Received data: {"distance":155,"object":"bird"}
122+
[log prefix] object_consumer[429721]: Received data: {"distance":122,"object":"dog"}
123+
[log prefix] object_consumer[429721]: Application terminated
124+
```
125+
126+
## License
127+
128+
**[MIT License](./app/LICENSE)**
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Axis Communications AB
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
PROG1 = $(shell jq -r '.acapPackageConf.setup.appName' manifest.json)
2+
OBJS1 = $(PROG1).cpp
3+
PROGS = $(PROG1)
4+
DEBUG_DIR = debug
5+
6+
PKGS = nexus-client-cpp
7+
8+
CXXFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags $(PKGS))
9+
LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs $(PKGS))
10+
11+
CXXFLAGS += -Wall \
12+
-Wextra \
13+
-Wpedantic \
14+
-Wfloat-equal \
15+
-Winline \
16+
-Wstack-protector \
17+
-Wpointer-arith \
18+
-Werror \
19+
-std=c++23
20+
21+
all: $(PROGS)
22+
23+
$(PROG1): $(OBJS1)
24+
# Create debug directory and build binary with debug symbols
25+
install -d $(DEBUG_DIR)
26+
27+
$(CXX) $^ $(CXXFLAGS) $(LIBS) $(LDFLAGS) $(LDLIBS) -o $(DEBUG_DIR)/$@
28+
cp $(DEBUG_DIR)/$@ .
29+
$(STRIP) $@
30+
31+
clean:
32+
rm -rf $(PROGS) *.o *.eap* *_LICENSE.txt package.conf* param.conf tmp* $(DEBUG_DIR)

0 commit comments

Comments
 (0)