Home Assistant projects
All projects

HP Printer

Integration · Appliances
v1.2.1 · Nov 12, 2026 HA 2025.8.0+ Marketplace

HP printers fully local, with sensors that keep their values while the printer sleeps, and scanning to PDF.

Status, ink or toner levels, pages remaining and page counters from the printer's built-in web server, and scanning to PDF, JPEG or PNG from the glass or the feeder, multi-page PDFs included. Built to replace the core HP Printer integration where it is fragile: no unavailable entities when the printer is off, nothing written when nothing changes.

Runs in the background

HP Printer has no dashboard of its own: it works on the server, with its entities, actions and notifications described in the documentation below.

Read the documentation

Highlights

  • Last values kept while the printer is off or asleep, and across a restart; only the status turns off
  • Page counters that never go down, for clean long-term statistics
  • Tiered polling, ETags and at most two requests at a time, light on the printer
  • Status never unknown, paper jams and open doors recognized, cartridge details on each level sensor
  • Scan to PDF, JPEG or PNG: glass, feeder or double-sided feeder, resolution, color mode and page size, Scan and add page
  • Last scan as a sensor and an image, files downloaded through signed links then deleted
  • Zeroconf discovery following address changes, reconfigure, firmware updates, diagnostics
  • No Python dependency; 22 languages

Works with

Install

  1. 1Open the repository in the Marketplace with the Add to Marketplace button above, or addgithub.com/juju35/ha-hp as a custom repository (category Integration).
  2. 2Download it from the Marketplace.
  3. 3Restart Home Assistant and add the integration from Settings → Devices & services.

Documentation

From the README

Features

Features

  • Never unavailable: a printer that is off keeps every value it last reported (ink levels, counters, network); only the Status turns off and the Online sensor turns off
  • Survives restarts: the last values are saved, so after a restart with the printer off the entities come back at once with them, and Home Assistant does not wait for the printer to start
  • No false "off": a lost request is tried again before the printer counts as off; a printer already off is not tried twice per poll
  • Clean statistics: page counters never go down (a lower value from the firmware is ignored instead of being taken as a reset), and counters and ink are not read while the printer starts up or shuts down, when firmwares report zeros
  • Light on the printer: the status is read at every poll (30 s by default), the page counters and ink levels every 5 minutes and right after each job, the network every 30 minutes, the identity every 6 hours and when the printer comes back
  • Nothing written when nothing changes: a poll that finds nothing new writes no entity, so the recorder stores nothing
  • Unchanged documents not downloaded again: counters, ink, identity and network are asked with their ETag, so an unchanged one costs a short 304 and no parsing (the status is always read in full, and cached documents are read in full again every 30 minutes, in case a firmware's ETags do not follow its content)
  • Unsupported documents not asked again and again: a document the printer does not publish is asked again every 6 hours only
  • At most two requests at a time to the printer's small web server
  • No dependency: no Python package to install, nothing to conflict with Home Assistant (PNG uses Pillow, which Home Assistant ships)
  • Status never unknown: a status this integration does not know is other, with the printer's own status in an attribute; paper jams and open doors are recognized
  • Scan to PDF, JPEG or PNG: a Scan button with its settings (format, source, resolution, color mode, page size) and an hp.scan action for automations; glass, document feeder and double-sided feeder; multi-page PDFs from the glass with a Scan and add page button; files saved in the local media, the last scan shown by an image and a sensor
  • Cartridge details on each level sensor: state (ok, low, very_low…), cartridge number to buy, product number, installed; a cartridge taken out keeps its last level, with installed: false
  • Zeroconf discovery, and a printer announced at a new address is followed there
  • Reconfigure the address without removing the printer; a printer that changed address is detected and keeps its values instead of mixing them with another printer's
  • Firmware updates shown on the device page
  • Diagnostics with the address and serial number redacted
  • English, French, German, Spanish, Italian, Dutch, Portuguese (European and Brazilian), Polish, Serbian (Cyrillic and Latin), Romanian, Danish, Swedish, Bulgarian, Russian, Ukrainian, Hungarian, Slovak, Czech, Slovenian, Latvian and Greek

Compared with the core HP Printer integration#

Core hp_printer hp (this integration)
Printer off or asleep Every entity unavailable Last values kept, status off; Online, Wi-Fi, Ethernet and HP cloud sensors off
Restart with the printer off Setup retried, no entity Entities at once with their last values
Unknown status unknown other + the printer's status in an attribute
Requests per poll (every minute) All documents Status only; the rest when it can have changed
Entity writes per poll Every entity None unless a value changed
Unchanged documents Downloaded and parsed again 304 with ETags
Cartridge taken out Unavailable Last level kept, installed: false
Address change Remove and add the printer again Reconfigure, or followed by discovery
Scanning No PDF (multi-page from the glass too), JPEG or PNG, glass or feeder, buttons and action
Python dependency aiohpprinter None

The two can be installed side by side (different domains), but use only one per printer.

Supported printers

Supported printers

HP printers whose built-in web server publishes the /DevMgmt/*.xml documents: OfficeJet, OfficeJet Pro, ENVY, DeskJet, Smart Tank, LaserJet and Color LaserJet with a network connection. Which sensors are created depends on the model: a printer without a scanner or fax gets no scanner or fax sensor.

To check a printer, open http://<printer address>/DevMgmt/ProductStatusDyn.xml in a browser: it should show an XML document.

Prerequisites

Prerequisites

  • Home Assistant 2025.8 or newer
  • The printer on the network, with a fixed IP address given in your router (recommended)

Configuration

Configuration

Settings → Devices & services → Add integration → HP Printer, or accept the discovered printer. The printer must be on when it is added.

Field Description
Host IP address or hostname of the printer
Port Empty for the default port (80, or 443 with HTTPS)
Use HTTPS Only for printers whose web server answers over HTTPS only

Options#

Option Default Description
Status refresh interval 30 s How often the status is read (10 to 600 s). Counters and ink levels are read every 5 minutes and after each job, whatever this interval
Keep scans not downloaded 30 min A scan file not downloaded is deleted after this time (a downloaded file is deleted at once); 0 keeps them

Entities

Entities

Entities are named after the printer model, for example sensor.hp_officejet_pro_9010_series_black_level. Entity names stay in English in every language, so entity IDs do not depend on the language of Home Assistant.

Entity Notes
sensor.<printer>_status ready, processing, copying, scan_processing, cancel_job, in_power_save, initializing, shutting_down, off, tray_empty, paper_jam, close_door_or_cover, other; attributes raw_status, message, alerts
binary_sensor.<printer>_online Whether the printer answered the last poll
sensor.<printer>_<color>_level black, cyan, magenta, yellow, tri_color, in %; attributes state, installed, cartridge, product_number, low_threshold, type
sensor.<printer>_<color>_pages_remaining When the printer estimates it
sensor.<printer>_<color>_pages_printed Disabled by default
sensor.<printer>_printed_pages, _printed_black_and_white_pages, _printed_color_pages Page counters
sensor.<printer>_scanned_pages, _copied_pages, _faxed_pages When the printer has a scanner, copier or fax
sensor.<printer>_printed_single_sided_sheets, _printed_double_sided_sheets, _scanned_pages_from_document_feeder, _scanned_pages_from_glass, _scanned_double_sided_sheets Disabled by default
sensor.<printer>_paper_jams, _paper_mispicks, _scanner_jams, _scanner_mispicks Diagnostic; mispicks and scanner counters disabled by default
sensor.<printer>_last_seen Diagnostic, disabled by default: when the printer last answered (it changes at every poll, so it is the only entity written every 30 s)
binary_sensor.<printer>_ethernet, _wi_fi, _usb Diagnostic: adapter connected (USB disabled by default)
binary_sensor.<printer>_hp_cloud_registered, _hp_cloud_services Diagnostic

Scanning

Scanning

Printers whose scanner answers eSCL (AirScan, at http://<printer address>/eSCL/ScannerCapabilities) get the scan entities; the choices offered are those the scanner reports.

Entity Notes
button.<printer>_scan Scans with the settings below and saves a new file
button.<printer>_scan_and_add_page Scans one more page and adds it to the last PDF: put the next page on the glass and press it, page after page
select.<printer>_scan_format pdf (one file with every page), jpeg or png (one image per page)
select.<printer>_scan_source flatbed (glass), feeder, feeder_duplex
select.<printer>_scan_resolution The resolutions the scanner offers (300 by default)
select.<printer>_scan_color_mode color, grayscale, black_and_white
select.<printer>_scan_page_size a4 (default), letter, legal, max (largest area of the source)
sensor.<printer>_last_scan Time of the last scan; attributes format, files, media_ids (media source IDs, to show the images in the media browser), download_paths (to download the files, PDF included), pages
image.<printer>_last_scanned_image First page of the last scan (PDF, JPEG or PNG)

Files are saved in the hp folder of the local media (/media/hp on Home Assistant OS), named scan_<date>_<time>.pdf (_1.jpg, _2.jpg… per page in JPEG or PNG); an existing file is never overwritten. They show in Media → Local media → hp. The settings are kept across restarts.

Action hp.scan#

Every field is optional: those not given come from the select entities, and device_id is only needed with several printers.

action: hp.scan
data:
  format: pdf              # pdf, jpeg, png
  source: feeder_duplex    # flatbed, feeder, feeder_duplex
  resolution: 300
  color_mode: grayscale    # color, grayscale, black_and_white
  page_size: a4            # a4, letter, legal, max
  filename: invoice_2026_11
  directory: /media/scans  # must be in allowlist_external_dirs (the media folders are)
  append: false            # true: add the pages to the last PDF instead of a new file
response_variable: scan    # scan.files, scan.media_ids, scan.download_paths, scan.pages

When a scan is saved, the event hp_scan_completed is fired with device_id, format, files, media_ids, download_paths and pages.

The files of each printer's last scan are downloaded from /api/hp/scans/<entry>/<n> (the paths in download_paths), by a signed-in user or a signed link: Home Assistant's media view only serves audio, video and images, not PDFs. A file is deleted once downloaded (once fully sent: an interrupted download keeps it), and leaves the last scan; a file never downloaded is deleted after 30 minutes (option Keep scans not downloaded; 0 keeps them), even across a restart. Only the files the integration wrote are deleted. ha-printer-card scans from the glass or the feeder and offers the download link.

PDF and PNG are made by the integration from the scanner's JPEG pages (embedded as is in the PDF, no new compression), which is what lets pages be added to a PDF. A scanner that only offers PDF gets its own PDF saved, without adding pages.

Errors are shown, translated, on the button or the action: printer off, scanner busy, feeder empty, a setting the scanner does not offer, folder not allowed.

Automation examples#

Ink running low, whether the printer is on or not:

triggers:
  - trigger: numeric_state
    entity_id: sensor.office_printer_black_level
    below: 10
actions:
  - action: notify.mobile_app_phone
    data:
      message: >
        Black cartridge at {{ states('sensor.office_printer_black_level') }} %
        ({{ state_attr('sensor.office_printer_black_level', 'cartridge') }}).

Scan the feeder to PDF and say where it went:

actions:
  - action: hp.scan
    data:
      source: feeder
      format: pdf
    response_variable: scan
  - action: notify.mobile_app_phone
    data:
      message: "Scan saved: {{ scan.files | join(', ') }}"

Out of paper:

triggers:
  - trigger: state
    entity_id: sensor.office_printer_status
    to: tray_empty
actions:
  - action: notify.mobile_app_phone
    data:
      message: The printer is out of paper.

How it works

How it works

  • Scans: eSCL, POST /eSCL/ScanJobs (JPEG pages, made into PDF or PNG here) with the settings, then GET <job>/NextDocument until the printer has no document left; the scanner and feeder states are checked first, a busy answer (503) is asked again, and a job that fails is deleted so the scanner is free. Capabilities are read with the identity, so the scan entities exist even while the printer is off
  • Documents: ProductStatusDyn (status), ConsumableConfigDyn and ProductUsageDyn (cartridges and counters), ProductConfigDyn (identity), /IoMgmt/Adapters and ePrintConfigDyn (network), over HTTP on port 80 (HTTPS optional, self-signed certificates accepted)
  • A poll reads the status; when it does not answer twice in a row, the printer is off: the status turns off, the other values stay, and everything is read again when it answers. While it is off, one attempt per poll
  • Another printer answering at the address (DHCP) is detected by its serial number: this printer counts as off and keeps its values, and the address is checked again every 5 minutes
  • The data is saved in .storage/hp.<entry id> when it changes (and every 10 minutes for the last-seen time while the printer is on), and removed with the printer

Support

Support

If you find this project useful, you can support its development:

Buy Me a Coffee

Changelog

CHANGELOG.md

1.2.1Nov 12, 2026Latest

Fixes

  • While the printer is off or unreachable, the Wi-Fi, Ethernet, USB and HP cloud sensors are off instead of keeping their last value (connected, registered). They show the printer's report again as soon as it answers.

1.2.0Nov 12, 2026

Fixes

  • Downloading a PDF scan gave a 14-byte file (404: Not Found): Home Assistant's media view only serves audio, video and images. The integration now serves the files of each printer's last scan itself, at /api/hp/scans/<entry>/<n>, to a signed-in user or a signed link; their paths are in download_paths (action response, event, Last scan sensor). Each file is deleted once downloaded (after it is fully sent: an interrupted download keeps it) and leaves the last scan; files never downloaded are deleted after 30 minutes (new option Keep scans not downloaded, 0 keeps them), a restart included. ha-printer-card 2.12.1 downloads through these paths.
  • The device_id of hp.scan no longer uses DeviceEntry.config_entries, deprecated since Home Assistant 2026.10.

1.1.1Nov 12, 2026

Maintenance

  • Config flow tests no longer set the printer up: the reconfigure test left the image token timer running and failed on the latest Home Assistant depending on test order. No change to the integration itself.

1.1.0Nov 12, 2026

Improvements

  • Scans in a media folder get their media source ID (media_ids) in the hp.scan response, the hp_scan_completed event and the Last scan sensor, which also gives the number of pages: a dashboard card can show or download the file (ha-printer-card 2.12 does).

Fixes

  • The scan folder is checked outside Home Assistant's event loop (the check reads the disk).

1.0.1Nov 12, 2026

Fixes

  • Status other (unknown state on the card) on printers that list several statuses, an informative one first: an OfficeJet Pro 9010 reports genuineHP ("Cart. HP Instant Ink") before ready. The status shown is now the most important known one (a stop, then work, then rest), with its message; other only when none is known. Alerts are listed once each.
  • Cartridge states keep acronyms whole: new_genuine_hp instead of new_genuine_h_p.

1.0.0Nov 12, 2026

First release: a local integration for HP printers, built to replace the core HP Printer integration where it is fragile.

  • Sensors keep their last values while the printer is off or asleep, and after a restart with the printer off (saved data): no more unavailable or unknown entities; the Status turns off and a new Online sensor turns off
  • Home Assistant starts without waiting for the printer when its data was saved
  • A lost status request is tried again before the printer counts as off
  • Tiered polling: status every 30 s (option), counters and ink levels every 5 minutes and after each job, network every 30 minutes, identity every 6 hours and when the printer comes back
  • ETags: unchanged documents answered with a 304 (never for the status; full read every 30 minutes anyway); documents the printer does not publish asked again every 6 hours only; at most two requests at a time
  • Status other (with the printer's status in an attribute) instead of unknown; paper jams and open doors recognized
  • Cartridge attributes: state, cartridge number, product number, installed, low threshold; a cartridge taken out keeps its last level
  • Zeroconf discovery following address changes, reconfigure flow, detection of another printer at the address, firmware updates on the device page, diagnostics
  • Nothing written when a poll finds nothing new: no entity write and nothing recorded every 30 s; the Last seen sensor, the one value that changes at every poll, is disabled by default
  • Page counters never go down (a lower firmware value is ignored, so long-term statistics see no false reset); counters and ink not read while the printer starts up or shuts down
  • Scanning to PDF, JPEG or PNG through eSCL (AirScan): Scan button with format, source (glass, feeder, double-sided feeder), resolution, color mode and page size selects kept across restarts; hp.scan action with a response (saved files, pages); files in the local media hp folder, never overwritten; Last scan sensor, Last scanned image (first page, PDF included) and hp_scan_completed event
  • Multi-page PDFs from the glass: Scan and add page button and append field add the next page to the last PDF; PDFs are built from the scanner's JPEG pages without recompression, PNG converted with Home Assistant's Pillow
  • No Python dependency