https://github.com/axiscommunications/opc-ua-gaugereader-acap
Small example ACAP application that reads analog gauges with video analytics and exposes the value via OPC UA.
https://github.com/axiscommunications/opc-ua-gaugereader-acap
acap axis industry-4 industry-40 industry40 opc opc-ua opcua opencv video-analytics
Last synced: 12 months ago
JSON representation
Small example ACAP application that reads analog gauges with video analytics and exposes the value via OPC UA.
- Host: GitHub
- URL: https://github.com/axiscommunications/opc-ua-gaugereader-acap
- Owner: AxisCommunications
- License: apache-2.0
- Created: 2022-09-16T08:15:00.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-03-03T15:38:08.000Z (over 1 year ago)
- Last Synced: 2025-03-03T16:25:49.446Z (over 1 year ago)
- Topics: acap, axis, industry-4, industry-40, industry40, opc, opc-ua, opcua, opencv, video-analytics
- Language: C++
- Homepage: https://www.axis.com/developer-community/industry-4-0-integration
- Size: 2.45 MB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
*Copyright (C) 2025, Axis Communications AB, Lund, Sweden. All Rights Reserved.*
# OPC UA Gauge Reader ACAP
[](https://github.com/AxisCommunications/opc-ua-gaugereader-acap/actions/workflows/build.yml)
[](https://github.com/AxisCommunications/opc-ua-gaugereader-acap/actions/workflows/super-linter.yml)

This repository contains the source code to build a small example
[ACAP version 4](https://axiscommunications.github.io/acap-documentation/)
(native) application that reads an analog gauge using video analytics with
[OpenCV](https://opencv.org/)
and exposes the value through a built-in
[OPC UA](https://en.wikipedia.org/wiki/OPC_Unified_Architecture)
([open62541](https://open62541.org/)) server.

The exposed value is in percent.
> [!NOTE]
> Even if this application would fit right into your usecase, its purpose is
> above all to serve as an example and boilerplate rather than being ready for
> production.
## Example Use Cases
> The following examples assume that you have a [SCADA](https://en.wikipedia.org/wiki/SCADA) (Supervisory
Control And Data Acquisition) system or a [PLC](https://en.wikipedia.org/wiki/Programmable_logic_controller) (Programmable Logic Controller) system with OPC UA as the communication protocol and you want to take advantage of the Axis device capabilities to enrich or complement your operations.
Analog gauges are common in the industry, and it is often impossible to add
digital sensors due to regulations or warranty restrictions. However, having a
human operator monitor these gauges (which is what is done today) is
inconvenient and error-prone. Instead, we can use an IP camera with very basic
video analysis to automatically capture the digital reading and feed it into
the industrial system. Automating the capture of digital values from analog
gauges opens up a multitude of possibilities.
For example:
- shutdown or start a PLC process if a gauge reading exceeds or falls below a specified threshold
- generate alarms when the gauge reading goes outside a predefined range
- display real-time gauge values within the SCADA server's operational interface
- maintain historical logs of gauge values to track changes over time
> [!WARNING]
> Please note that any analytic process can never be 100% accurate and the system designer has to account for this.
## Build
The build process uses the
[ACAP SDK build container](https://hub.docker.com/r/axisecp/acap-sdk)
and Docker or Podman.
The Docker and Podman commands are integrated in the [Makefile](Makefile), so
if you have Docker or Podman and `make` on your computer all you need to do is:
```sh
make dockerbuild
```
or
```sh
make podmanbuild
```
or perhaps build in parallel:
```sh
make -j dockerbuild
```
alternatively
```sh
make -j podmanbuild
```
If you do have Docker but no `make` on your system:
```sh
# 32-bit ARM, e.g. ARTPEC-6- and ARTPEC-7-based devices
DOCKER_BUILDKIT=1 docker build --build-arg ARCH=armv7hf -o type=local,dest=. .
# 64-bit ARM, e.g. ARTPEC-8 and ARTPEC-9-based devices
DOCKER_BUILDKIT=1 docker build --build-arg ARCH=aarch64 -o type=local,dest=. .
```
If you do have Podman but no `make` on your system:
```sh
# 32-bit ARM, e.g. ARTPEC-6- and ARTPEC-7-based devices
podman build --build-arg ARCH=armv7hf -o type=local,dest=. .
# 64-bit ARM, e.g. ARTPEC-8 and ARTPEC-9-based devices
podman build --build-arg ARCH=aarch64 -o type=local,dest=. .
```
## Debug
If you would like the application to store the images from each step in the
video analysis to disk for debugging, set the `DEBUG_WRITE` variable for the
build:
```sh
DEBUG_WRITE=y make -j dockerbuild
```
or
```sh
# 32-bit ARM, e.g. ARTPEC-6- and ARTPEC-7-based devices
DOCKER_BUILDKIT=1 docker build --build-arg DEBUG_WRITE=y --build-arg ARCH=armv7hf -o type=local,dest=. .
# 64-bit ARM, e.g. ARTPEC-8 and ARTPEC-9-based devices
DOCKER_BUILDKIT=1 docker build --build-arg DEBUG_WRITE=y --build-arg ARCH=aarch64 -o type=local,dest=. .
```
> [!TIP]
> For Podman, use the same commands using `podman` instead of `docker`.
## Setup
### Manual installation and configuration
Upload the ACAP application file (the file with the `.eap` extension for the
camera's architecture) through the camera's web UI: *Apps->Add app*
When installed, start the application.

Open the application's settings page in the web interface (available when the
application is running) by clicking the *Open* button.

In the settings page, simply click in the image to set up the calibration
points in the following order:
1. Center of the gauge
1. Minimum value of the gauge
1. Maximum value of the gauge
The calibration points can also, along with the OPC UA Server port (default is
4840) and clockwise/counterclockwise (default is clockwise), be set directly
through the application's parameter settings, found in the three vertical dots menu:


### Scripted installation and configuration
Use the camera's
[applications/upload.cgi](https://www.axis.com/vapix-library/subjects/t10102231/section/t10036126/display?section=t10036126-t10010609)
to upload the ACAP application file (the file with the `.eap` extension for the
camera's architecture):
```sh
curl -k --anyauth -u root: \
-F packfil=@OPC_UA_Gauge_Reader__.eap \
https:///axis-cgi/applications/upload.cgi
```
To
[start (or stop/restart/remove)](https://www.axis.com/vapix-library/subjects/t10102231/section/t10036126/display?section=t10036126-t10010606)
the application, you can make a call like this:
```sh
curl -k --anyauth -u root: \
'https:///axis-cgi/applications/control.cgi?package=opcuagaugereader&action=start'
```
Use the camera's
[param.cgi](https://www.axis.com/vapix-library/subjects/t10175981/section/t10036014/display)
to set the center/min/max points, as well as clockwise/counterclockwise and the
OPC UA server port number.
The call
```sh
curl -k --anyauth -u root: \
'https:///axis-cgi/param.cgi?action=list&group=opcuagaugereader'
```
will list the current settings:
```sh
root.Opcuagaugereader.DynamicStringNumber=1
root.Opcuagaugereader.centerX=479
root.Opcuagaugereader.centerY=355
root.Opcuagaugereader.clockwise=1
root.Opcuagaugereader.maxX=678
root.Opcuagaugereader.maxY=165
root.Opcuagaugereader.minX=283
root.Opcuagaugereader.minY=167
root.Opcuagaugereader.port=4840
```
If you want to set the OPC UA server port to e.g. 4842:
```sh
curl -k --anyauth -u root: \
'https:///axis-cgi/param.cgi?action=update&opcuagaugereader.port=4842'
```
## Usage
Attach an OPC UA client to the port set in ACAP. The client will then be able
to read the value (and its timestamp) from the application's OPC UA server.
> [!NOTE]
> The application will also log the gauge value in the camera's syslog.
### Bonus
In addition to the above, the application will write the extracted gauge
reading as a
[dynamic text overlay](https://www.axis.com/vapix-library/subjects/t10175981/section/t10007638/display?section=t10007638-t10003585)
string. It can then be displayed as camera text overlay—or used by graph
widgets—with the modifier **#D***N*, where *N* is set by the application
parameter `DynamicStringNumber`.
## License
[Apache 2.0](LICENSE)