Read the number, stop at N

Every job on the Status Board shows its status as plain text on the same grey chip. Error is not red, Complete is not green, so there is no colour to shortcut. The macro has to OCR-read the word and branch: retry the ones that read Error, archive the ones that read Complete, and leave the rest alone. Then it reads one number, the board's Actionable left count, and stops the run the moment that count hits zero. Read a word to branch, read a number to know when the work is done.

OCR text read + branch no colour shortcut Pro · free preview 15 min

Most detection leans on colour: find the red bar, click the green button. This target takes that away on purpose. With every status the same light text on the same grey chip, a pixel match cannot tell them apart, so the only way through is to read the word. That is exactly what a Text (OCR) condition does.

Open the target first. It opens in a new tab. Point QHuman at it and read its status words as you go.

Open Status Board

Eight jobs, each with a status word and a Retry and an Archive button. Retry is right only on an Error row, Archive only on a Complete row, and Queued or Processing rows want leaving alone. Anything else is a Wrong-state click. There are always two Errors and two Completes, so there are always four jobs worth doing.

Every status is the same #e7eaee text on the same #1c2230 chip, and both buttons sit on every row whether they apply or not. Nothing here to match on but the word itself.

Two keys. R resets the board, and it deals the same eight jobs back in a different order: that is the point of the rig, not a nuisance. Your read region sits over a slot on screen, and what lands in that slot changes every reset, which is exactly why a macro that memorised where the Error was cannot pass. F is focus mode, but skip it here: it hides the whole panel, including the Actionable left number this lab ends up reading.

Build the macro

  1. Open QHuman and start a detection flow Click New Detection, name it status board, and pick it under Macro:. Add two steps: Read and Retry. Put the Status Board where a full row is visible and will stay put, because every region you draw is an absolute screen box.
  2. Add a Text (OCR) condition on a transition Drag Read's bottom handle onto Retry. Set Move on: to Advanced condition (AND / OR / NOT), then click Add Text (OCR): the leaf that reads a screen region as words instead of matching its pixels.
  3. Draw the region over one status chip Tick Limit detection to a screen region, click Select region on screen..., and drag a tight box around the status word on the top row and nothing else. Snug matters: every extra pixel of chip, code or button is more for the reader to get wrong, and the word is all you want back.

    The box goes around the word, not the row. Everything else on that row is noise to an OCR read.

    The region is a fixed box, so it is really a slot: it reads whatever job lands in the top row after the next reset. You are not finding the Error row, you are reading a position and letting the word decide.
  4. Set the text check to contains Error The Match: list offers contains, equals, not_equals and regex. Leave it on contains, type Error into Text / pattern:, and leave Min OCR confidence: at 0.85. For the second branch, make an Archive step first: you can only wire a transition to a step that exists. Then add another transition from Read to it, matching contains Complete. Queued and Processing need no branch at all: matching nothing is how the flow leaves them alone.
  5. Watch it read with Try it (dry run) Hit Try it (dry run). Nothing gets clicked, but every tick is logged with what it saw and what it would do, so you can watch your box return the actual word and the right branch light up. Press R on the board and run it again: same slot, different job, different branch. That is the proof, and it is free.
  6. Tune the read if it is flaky If a word comes back wrong, tighten the box first. If it still misreads, try Settings → Detection → OCR preprocessing: it ships on Grayscale (default), which suits flat UI text like this, with Otsu (binarized) and None (raw frame) as the alternatives. It applies on the next detection run, so re-run the dry run after each change.
  7. Add the numeric stop The flow can decide, but nothing yet tells it when the work is done. Add one more step called Done and tick Terminal (entering it ends the run). Add a transition from Read to Done using Add Number (OCR), with its region over the panel's Actionable left readout. Set Read as: int, Compare: <=, Against value: 0. Put it first in the list: transitions are tried in order and the first match wins, so the stop has to be checked before the branches that keep working.
    Read a number, compare it, stop when the work is gone. Read as really does say int in lower case, and Compare really is the ASCII <=.
    One watcher, three ways out, each acting step looping straight back to read again. Edge order matters here: the count-hits-zero edge sits first, so a cleared board stops the run before any word is read.
  8. Go live and clear the board (optional, Pro) The lab is done at step 7; acting on an OCR read live is Pro. Give the Retry and Archive steps a click each on their buttons, then set it running on the slot: it reads the word and fires the matching action, an Error gets a Retry, a Complete gets an Archive, and a Queued or Processing slot correctly gets nothing. Acting on a row changes it in place rather than clearing it off the list. A Retry turns that Error into Processing, an Archive marks the Complete row Archived, and no row ever shifts. So a flow that watches one fixed slot handles the single job under it, then reads a settled slot and idles. Clearing all four actionable jobs hands-free means giving the flow a read for every row, not just the top one, which is the jump into Build a full bot.
Checkpoint

The free pass bar is the dry run, and it is about the read, not the countdown. Your box returns the real word every tick, the branch that lights up matches the word it read, and pressing R to reshuffle changes which branch fires without you touching the flow. Do that two or three times and you have proved the thing this lab is about: it is reacting to the word, not to a position it memorised.

Expect Actionable left to sit at 4 the whole time. A dry run never clicks, so no job gets done and the number never counts down. A clean 4 every pass is the correct dry-run result, and all you can prove for free.

On Pro, the live run acts for real: the slot's word decides and the matching button is clicked. Because this board changes an acted row in place instead of dealing a new one into the slot, a single reading position handles the one job under it, moves Jobs handled to 1, then reads a settled Processing or Archived and idles. Wrong-state clicks should stay 0 either way: above 0 means it acted on a word it did not really read. Driving Actionable left all the way to 0 and stopping on its own needs a flow that reads every row, which is the next lab.

Make it yours

Give the flow eyes on the whole board. Add a read for each row, a step per slot or one region per row, so it works all eight positions instead of only the top one. Now the number stop earns its keep: with every actionable job handled, Actionable left finally counts down to 0 and the run ends itself. Predict the ending first, then move Against value: from 0 to 2 and watch it quit with two jobs still on the board, because the number is the only thing that ever tells it to stop.

If it went wrong

  • Wrong-state clicks climbing It acted on a Queued or Processing row, which means the branch fired on a word it did not really read. Check the dry-run log for what came back: a misread of Complete is the usual one. Tighten the box, then re-check that the click is landing on the same row the box reads.
  • The status reads as gibberish The box is off the word, or it caught the chip edge. Redraw it tighter, then try OCR preprocessing on Otsu (binarized) or None (raw frame).
  • A real Error row gets skipped Min OCR confidence is throwing out a valid read. It ships at 0.85, so drop it to 0.7 and watch the reading come back in the dry run.
  • Every click misses after a reset R deals the same jobs in a new order, so a click aimed at a job is aimed at nothing. The fix is the lesson: aim at the slot your region reads, and let the word decide what to do there.
  • It stops immediately, before doing anything The stop read a 0 that was never real. The board ships the text Actionable left: 0 in its HTML and the script rewrites it to 4 on load, so a flow started against a page mid-load can read that placeholder and quit. Let the board finish loading before you set it running.
  • It never reaches the stop On a single-slot flow this is expected: it handles the one job under the slot and idles, because that slot never refills (see the note in the live step). Once you have extended it to read every row, a run that keeps working and never ends usually means the stop is missing or sits below the branches: transitions are tried in order and the first match wins, so an Error branch above the stop keeps winning. Move the stop to the top of the Then list, and check its region really sits on Actionable left with Compare: <= and Against value: 0.

Stuck?

Grab the finished flow. Download it and open QHuman's Import shared file... to load it, then compare its regions and branches to what you built. It is a reference to read, not a macro to run: the detection snippets inside were captured on another screen, so they will not match your display. Run with the ones you took in the lab instead.

Download the solution (.qhz)

Keep going

Want the full detail behind number and text conditions, regions, and preprocessing? Read the read text & numbers guide. Ready for the next lab? On the Play path that is Build a full bot; on the Work path it is Find the flagged rows.