Hook: Stop Copy‑Pasting Numbers from a Dashboard with No API

You stare at a web‑based dashboard, manually copy‑pasting a handful of numbers every hour. The page has no API, no export button, and the data changes fast enough that a manual workflow becomes a bottleneck. What if you could let your Linux box watch a specific region of the screen, turn the pixels into text, and trigger an alert the moment a value changes?

In this post I walk through the exact setup I use on my home server: a PipeWire screen capture, a tiny grim script to grab a region, Tesseract OCR to read the numbers, and a Bash loop that notifies me via notify-send when the value differs from the previous run.

1. Prerequisites

Tool Why you need it
pipewire (with pw-cli and pw-top) Modern screen‑capture backend on Wayland
grim Simple command‑line screenshot utility that works with PipeWire
tesseract-ocr OCR engine that can read the captured image
imagemagick (optional) Pre‑process the image for better OCR accuracy
jq (optional) Parse JSON if you decide to log results
notify-send (or any other notifier) Show a desktop notification when the value changes

All of these packages are available in the default repositories of most distros:

# Debian/Ubuntu sudo apt install pipewire grim tesseract-ocr imagemagick jq libnotify-bin # Fedora sudo dnf install pipewire grim tesseract imagemagick jq libnotify 

2. Capture a Fixed Region with grim

grim can capture the whole screen or a rectangle defined by geometry. I store the geometry in a variable so I can tweak it without editing the script.

# Geometry: X,Y,W,H (pixels) REGION="1200,300,250,80" # Adjust to the exact location of the number on your dashboard IMG_PATH="/tmp/dashboard.png" capture_region() { grim -g "$REGION" "$IMG_PATH" } 

Run grim -g "$REGION" - to preview the region in a viewer like feh if you need to fine‑tune the coordinates.

3. Pre‑process the Image (Optional but Recommended)

Tesseract works best with high‑contrast, binarized images. A quick ImageMagick pipeline removes noise and boosts contrast.

preprocess_image() { convert "$IMG_PATH" \ -colorspace Gray \ -level 20%,80% \ -type Bilevel \ "$IMG_PATH" } 

If the dashboard already uses a clean font on a solid background you can skip this step.

4. Run Tesseract and Extract the Number

We only need the plain text output, so we tell Tesseract to write to stdout (-). The --psm 7 mode treats the image as a single line of text, which speeds up processing.

extract_number() { tesseract "$IMG_PATH" stdout --psm 7 2>/dev/null | tr -d '\n' | tr -d ' ' } 

The tr commands strip newlines and spaces, leaving a compact string like 42.7.

5. Detect Changes and Notify

The core loop stores the previous reading in a temporary file. When the new reading differs, we fire a notification.

STATE_FILE="/tmp/dashboard_last.txt" check_change() { local current=$(extract_number) local previous="" [ -f "$STATE_FILE" ] && previous=$(cat "$STATE_FILE") if [[ "$current" != "$previous" ]]; then notify-send "Dashboard Update" "Value changed: $previous → $current" echo "$current" > "$STATE_FILE" fi } 

6. Glue It All Together

A simple infinite loop with a sleep interval does the job. I run this as a systemd user service so it survives reboots and logs to journalctl.

#!/usr/bin/env bash while true; do capture_region preprocess_image # comment out if you skipped pre‑processing check_change sleep 60 # check once per minute; adjust as needed done 

Save the script as ~/bin/dashboard-watcher.sh, make it executable (chmod +x), and test it manually before creating the service.

7. Optional: Systemd User Service

Create ~/.config/systemd/user/dashboard-watcher.service:

[Unit] Description=Watch dashboard region and alert on change After=network.target [Service] ExecStart=%h/bin/dashboard-watcher.sh Restart=on-failure [Install] WantedBy=default.target 

Enable and start it:

systemctl --user daemon-reload systemctl --user enable --now dashboard-watcher.service 

You can view logs with journalctl --user -u dashboard-watcher.service.

8. Tweaking for Accuracy

  • Font size & DPI – Larger fonts and higher DPI screenshots improve OCR confidence.
  • Whitelist characters – If you only expect numbers and a decimal point, add tesseract config tessedit_char_whitelist 0123456789.
  • Language data – Use tesseract-ocr-eng (default) unless the dashboard uses a different script.

9. What This Solves

  • Zero manual copying – The script runs unattended.
  • Immediate alerts – Get a desktop pop‑up (or replace notify-send with an email/SMS hook) the moment a KPI shifts.
  • Low overhead – Each cycle consumes < 0.2 s of CPU on a modest VM.

You can extend the pattern to multiple regions, feed the numbers into a time‑series database, or trigger a Home Assistant automation.

I build sites and automations for small businesses at dreamfuturestech.com.