Releases: wleonhardt/ha-escl-scan
Release list
v0.4.3
Fixed
- HP MFPs answer 404 for
GET /eSCL/ScanJobs/{uuid}and only report job
state insideScannerStatus/Jobs. JobInfo now falls back to that list, so
these devices get live page progress,state_reasons
(JobCompletedSuccessfully, …), the final Aborted check, and correct
"job still alive" detection when NextDocument answers 503 between sheets. - Page count no longer doubles when the device counter and the document pull
both count the same page; the assembled PDF's page count is authoritative. - 503 purge skips jobs the device already lists as finished (HP keeps them
as history).
v0.4.2
Live-tested against an HP Color LaserJet MFP M283fdw on HA 2026.9.1.
Fixed
- Starting a scan right after a cancel failed with "scanner busy": HP MFPs
answer 503 and report Processing for a few seconds while the cancelled
job winds down.create_jobnow waits (up to 15 s) for the device to go
Idle before purging stale jobs and retrying; only a device that stays busy
is reported as busy. - Zeroconf: TXT keys are matched case-insensitively (HP advertises
uuid,
notUUID), so discovered HP devices get their UUID as unique id.
Added
- jsdom test suite for the Lovelace card (
npm run test:card) in CI: start /
cancel / 409, hass-setter progress rendering incl. the latched "Open scan"
link, renamed-sensor auto-detection, error-card healing, editor events.
v0.4.1
Fixed
- Options flow crashed on Home Assistant 2024.8–2024.11:
self.config_entry
only exists onOptionsFlowfrom 2024.12. Minimum supported version is now
2024.12 (declared inhacs.json).
Changed
- Legacy cipher option uses
SECLEVEL=1instead ofSECLEVEL=0: still admits
the non-PFS AES suites some HP MFPs need, without export/NULL-grade suites. hacs.json:hide_default_branch, so HACS offers only tagged releases.- CI:
node --checkon the card.
v0.4.0
Added
- Zeroconf/mDNS discovery (
_uscan._tcp,_uscans._tcp): scanners show up
under Discovered; the TXTrsresource path is honoured for devices
that don't serve/eSCL. escl_scan.start(with response) andescl_scan.cancelservices, plus a
button.<scanner>_scan_nowentity, so automations and stock cards can
trigger scans without the REST API.- Translated sensor states and entity names (
translation_key), icons. - Copy to folder option: every finished scan is atomically copied to a
directory of your choice (Paperless-ngx consume folder), validated against
allowlist_external_dirs. Newfile_path/copied_toattributes. - Diagnostics download (capabilities, scans, redacted entry data).
- Card is available in the dashboard card picker with a visual editor
(title, sensor entity) and a preview. ScannerCapabilitiesis read at setup: device page shows the real make,
model and serial; the config entry's unique id is the serial/UUID (survives
DHCP changes); the scan region is the reported bed size per source (A4 and
Legal are no longer cropped to Letter); a requested DPI snaps to the nearest
supported resolution.- Duplex scanning for Feeder scans on duplex-capable ADFs:
duplexin the
start body and a "scan both sides by default" option. - Card
entity:option; the card also auto-detects a renamed scan sensor.
Fixed
- Creating a job while another client is scanning no longer deletes that
client's job; the start fails with "scanner busy" instead. - Per-page ADF scanners that answer 503 between sheets no longer get their
batch truncated: NextDocument retries while JobInfo reports the job alive. - Failed/canceled scans are dropped from memory after the retention TTL.
Removed
pages_totalattribute (was never populated).
v0.3.0
Added
- Multi-document ADF scans are merged into a single PDF (issue #1). Scanners
that return one PDF per page are now handled; bundle-mode scanners keep the
single-file fast path. Adds apypdfrequirement. pages_donereports the real page count of the resulting PDF for
bundle-mode scanners.
Changed
- Test suite (pytest +
pytest-homeassistant-custom-component) and ruff lint
run in CI alongside hassfest and HACS validation. - Card colours follow the active HA theme;
single_config_entrydeclared;
sensor grouped under a device.
v0.1.7 — Narrow-width layout + duplicate error-card fix
Fixed
- Status text overlapping the title on narrow screens. Mid-scan and completion messages wrap to multiple lines on phone widths, pushing the cancel link off the card. Card now uses
min-height(grows to fit) and container queries to shrink the title/icon at narrow card widths — fires on the card's own width, not the viewport, so a horizontal-stack with two narrow cards on a large desktop also benefits. - Duplicate 'Configuration error' card appearing alongside the real card after a reload. Lovelace's own
whenDefined()callback inserts the real card alongside the existing error card; my v0.1.3+ heal logic was creating a separate fresh element instead of replacing the error in-place. Now the heal logic removes the error sibling when a real card is already present.
v0.1.6 — Fix duplicate static-route on reload
Bug fix for a regression introduced in v0.1.5.
Fixed
- Integration setup failed on reload with
Added route will never be executed. v0.1.5 made options changes properly trigger a reload, but every reload re-attempted to register the card.js static path — and aiohttp rejects duplicate GET URLs. The reload would half-complete, leaving the integration in a broken state until full HA restart. Now we track registered URLs in hass.data and skip already-registered ones.
v0.1.5 — Bug fixes from comprehensive integration testing
Several bug fixes uncovered during end-to-end testing against an HP M283fdw.
Fixed
- Options flow changes now actually take effect. The OptionsFlow used a deprecated
__init__(config_entry)pattern that silently broke the update-listener wiring, so saved options were stored to disk but the running integration kept using old values. - Views now resolve the coordinator dynamically. Previously, views captured the coordinator at registration time; after an options-flow reload, a fresh coordinator was built but views kept calling the dead one.
- PDF EOF validation. HP MFPs sometimes return malformed PDFs (catalog header only, ~58 bytes; or no
%%EOFtrailer) for unsupported DPI/color combos. We now mark these asfailedwith a clear error rather than reporting success. - HP 503 retry.
NextDocumentreturning 503 is sometimes transient ("retry me") rather than terminal ("no more documents"). Now retries with backoff before giving up. - Server-side job cleanup on failure paths. Failed scans previously left a stale job on the device, blocking the next
ScanJobscreate with 503. - Status-code precedence for /file and /cancel. 404 (unknown), 409 (not ready / already terminal), 502 (device refused) — were all collapsing to 502 before.
- Blocking I/O eliminated.
write_bytes,glob, and the card hash read now run in the executor (HA was warning about these on every scan).
v0.1.4 — matched sister branding
Brand refresh to pair with the ha-ipp-print sister project.
Changes
- New outline-style brand icon matching the print integration's visual style. Tailwind blue-500 background + 300 accents pairs with print's emerald-500/300.
- Card translucent background harmonized to blue-300 (was blue-400) so the cards look like twins when placed side-by-side.
- README header now points at ha-ipp-print as a sister project, plus card-state screenshots embedded directly.
- New
examples/dashboard-with-print.yamlshowing both cards side-by-side on a single dashboard.
No functional changes.
v0.1.3 — Fix slow-reload race
Fixed
The card sometimes rendered as 'Configuration error' on hard reloads (especially Firefox / mobile / slow connections). HA recently changed where hui-error-card stores the original user-provided card config, defeating the existing self-healing logic.
Root cause: the error card's _config no longer holds the original {type: 'custom:escl-scan-card', title: ...} — that now lives on the parent <hui-card> element's _elementConfig.
New heal logic:
- Sources the original config from the correct location
- Falls back to older HA layouts
- Last-resort: parses the missing tag from the error message to build a default card
- MutationObserver catches error cards appearing after the initial retry window
- Wider staggered retry schedule
Reproduced and verified across a stress-test of consecutive hard reloads.