Copyright (C) 2025, Axis Communications AB, Lund, Sweden. All Rights Reserved.
This repository contains the source code to build a small example ACAP version 4 (native) application that reads an analog gauge using video analytics with OpenCV and exposes the value through a built-in OPC UA (open62541) 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.
The following examples assume that you have a SCADA (Supervisory Control And Data Acquisition) system or a PLC (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.
The build process uses the ACAP SDK build container and Docker or Podman.
The Docker and Podman commands are integrated in the Makefile, so
if you have Docker or Podman and make on your computer all you need to do is:
make dockerbuildor
make podmanbuildor perhaps build in parallel:
make -j dockerbuildalternatively
make -j podmanbuildIf you do have Docker but no make on your system:
# 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:
# 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=. .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:
DEBUG_WRITE=y make -j dockerbuildor
# 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.
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:
- Center of the gauge
- Minimum value of the gauge
- 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:
In addition, the settings allow you to limit the amount of decimals for the output gauge value. The default value of -1 indicates no limit, 0 means no decimals (effectively an integer), 1 means one decimal, and so forth.
Use the camera's
applications/upload.cgi
to upload the ACAP application file (the file with the .eap extension for the
camera's architecture):
curl -k --anyauth -u root:<password> \
-F packfil=@OPC_UA_Gauge_Reader_<version>_<architecture>.eap \
https://<camera hostname/ip>/axis-cgi/applications/upload.cgiTo start (or stop/restart/remove) the application, you can make a call like this:
curl -k --anyauth -u root:<password> \
'https://<camera hostname/ip>/axis-cgi/applications/control.cgi?package=opcuagaugereader&action=start'Use the camera's param.cgi to set the center/min/max points, as well as clockwise/counterclockwise and the OPC UA server port number.
The call
curl -k --anyauth -u root:<password> \
'https://<camera hostname/ip>/axis-cgi/param.cgi?action=list&group=opcuagaugereader'will list the current settings:
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
root.Opcuagaugereader.RoundToDecimals=-1If you want to set the OPC UA server port to e.g. 4842:
curl -k --anyauth -u root:<password> \
'https://<camera hostname/ip>/axis-cgi/param.cgi?action=update&opcuagaugereader.port=4842'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.
In addition to the above, the application will write the extracted gauge
reading as a
dynamic text overlay
string. It can then be displayed as camera text overlay—or used by graph
widgets—with the modifier #DN, where N is set by the application
parameter DynamicStringNumber.




