Vision inspection
A camera inspection cell on a bottling line: fill level read from the frame, per bottle, with the inspection running on the Edge rather than in a cloud. One device and 15 tags, plus the video itself.
Operator view | port 4013 |
|---|---|
Protocol server | port 5023 |
Devices and tags | 1 device, 15 tags |
Litmus Edge driver | Modbus TCP |
Image | food-beverage-vision |
Scenarios
- A fill anomaly caught per bottle. The measurement is made from the picture, bottle by bottle, and published as a tag like any other reading.
- Filler drift as a forecast. The interesting number is not the bottle that failed but the trend that says the filler will start failing shortly.
- Inference on the Edge. The frames never leave the plant to be measured. What travels north is a number, and the picture only if you ask for it.
Overview
This is the one solution that uses two data paths, because the picture and the numbers suit different ones.
- Inspection readings go to DeviceHub over Modbus TCP, like every other solution here. These are the tags the Edge polls.
- Frames go to Litmus Edge DataHub over NATS, which is built for payloads of that size and shape.
A dropped frame therefore never costs you a measurement, and the tag history is not full of images.
The NATS path is optional. Leave it unconfigured and the inspection still runs and still publishes its readings.
What it creates on Litmus Edge
One DeviceHub device with 15 tags covering the fill measurement, the inspection verdict and the line state. A Digital Twin instance for the cell. Analytics groups behind the anomaly and drift figures. Frames land in DataHub when NATS is configured.
Requirements
- Litmus Edge 4.0.x, reachable over HTTPS from the host running the solution
- An API token for that Edge, or a username and password, or a client id and secret
- Docker, and Docker Compose for the compose deployment
- A network path in both directions: the solution reaches the Edge's API, and the Edge reaches this host on the protocol port
Deploy
The solution ships two ways. Use the registry if the host can reach Google Artifact Registry, and the downloaded archive if it cannot.
Option 1: pull from the registry
Requires a read-only registry credential, supplied by Litmus separately.
cat key.json | docker login -u _json_key --password-stdin https://us-docker.pkg.devSave this as docker-compose.yml:
services:
food-beverage-vision:
image: us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/food-beverage-vision:0.3.0
container_name: food-beverage-vision
restart: unless-stopped
ports:
- target: 4013
published: 4013
protocol: tcp
- target: 5023
published: 5023
protocol: tcp
environment:
# Fill these in.
EDGE_URL: "${EDGE_URL:-}"
EDGE_API_TOKEN: "${EDGE_API_TOKEN:-}"
SIM_HOST: "${SIM_HOST:-auto}"
APPLY_ON_START: "${APPLY_ON_START:-1}"
EDGE_VERIFY_TLS: "${EDGE_VERIFY_TLS:-0}"
HTTP_PORT: "4013"
MODBUS_PORT: "5023"
# Optional: frames to DataHub.
NATS_URL: "${NATS_URL:-}"
NATS_TOKEN: "${NATS_TOKEN:-}"
PUB_GROUP: "${PUB_GROUP:-fbvision}"
PUB_LAYOUT: "${PUB_LAYOUT:-datahub}"
LOG_LEVEL: "INFO"EDGE_URL=https://10.0.0.5
EDGE_API_TOKEN=your-token
SIM_HOST=10.0.0.9docker compose up -dOpen http://localhost:4013.
The page stays on its waiting panel until the Edge carries this solution's devices. That is deliberate: the simulation does not tick and no value is shown until Litmus Edge is verified to hold the devices and poll them, so nothing on screen can be mistaken for data that never made the trip. With APPLY_ON_START at its default of 1 the solution configures the Edge itself on startup, which takes 30 to 60 seconds. If you set it to 0, or the apply failed, press Apply to Edge in the page header.
This is the largest image of the set, about 219 MB, because it carries the vision libraries. The others are around 50 MB.
Option 2: load the downloaded archive
Download food-beverage-vision-0.3.0-amd64.tar.gz from the solution's page on portal.litmus.io. The archive is the container image, not a source bundle, and needs no registry access.
docker load -i food-beverage-vision-0.3.0-amd64.tar.gzdocker load prints the image it added:
Loaded image: us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/food-beverage-vision:0.3.0That reference is the one the compose file above already names, so the same docker-compose.yml and .env now work offline with no docker login:
docker compose up -dTo run it without Compose, pass the same three values on the command line:
docker run -d \
--name food-beverage-vision \
--restart unless-stopped \
-p 4013:4013 \
-p 5023:5023 \
-e EDGE_URL=https://10.0.0.5 \
-e EDGE_API_TOKEN=your-token \
-e SIM_HOST=10.0.0.9 \
us-docker.pkg.dev/litmus-customer-facing/litmus-solutions/food-beverage-vision:0.3.0Configuration
Variable | Default | What it does |
|---|---|---|
EDGE_URL | unset | Litmus Edge to configure |
EDGE_API_TOKEN | unset | token for that Edge. Or a username and password |
SIM_HOST | auto | address the Edge polls to reach this solution |
APPLY_ON_START | 1 | configure the Edge on startup |
EDGE_VERIFY_TLS | 0 | 1 checks the Edge's certificate |
NATS_URL | unset | Litmus Edge DataHub, for frames. Optional |
NATS_TOKEN | unset | a DataHub token. Not the same string as the API token above |
PUB_GROUP | fbvision | topic group frames are published under |
PUB_LAYOUT | datahub | topic layout. flat matches the upstream frame streamer convention |
LINE_SPEED | 4 | how fast bottles pass the camera |
When running as an application hosted by Litmus Edge, NATS_URL is 10.30.50.1, which is the Edge as seen from a container it hosts. Running beside the Edge, it is the Edge's own address.
Operator view
The camera view with the inspection overlay, the measured fill level per bottle, and the verdict. Beside it, the trend that the drift forecast is taken from.
Faults let you drift the filler, introduce a fill anomaly, and degrade the image so you can see what the inspection does with a poor frame.
Apply and remove
docker compose downUse Clean up in the Solutions provisioner to remove what it created on the Edge.