DOCUMENTATION
Printer Fleet Manager for Odoo 19 - on-prem, Docker, and Odoo.sh deployments, license activation, upgrades, and troubleshooting.
Module: printer_fleet_manager
Version: 19.0.7.1.1
Optional add-on: printer_fleet_manager_purchase 19.0.6.4.0
Target platform: Odoo 19.0 (Community or Enterprise)
License: OPL-1 (commercial)
Support: [email protected]
This guide is written for IT administrators deploying Printer Fleet Manager (PFM) on a production Odoo 19 server. It is deliberately detailed and covers on-prem, Docker, and Odoo.sh deployments, license activation (online and air-gapped), first-run configuration, upgrades, uninstall, and troubleshooting. Every command below is written for a typical Odoo 19 install; adjust paths, service names, and the database/user names to match your environment.
Deployment: Odoo.sh or On-Premise. Odoo Online: not supported. Odoo Online does not permit installation of third-party Python modules; this is a limitation of the Odoo Online platform, not of the module.
Printer Fleet Manager is a self-contained, agentless network-printer monitoring solution for Odoo 19. It discovers printers on your network, polls them over SNMP for status/toner/page-count, raises and auto-resolves alerts, tracks service history, and provides dashboards, a read-only wallboard, a mobile technician page reachable from a QR label, and usage reporting.
The download package contains up to two modules:
| Module | Version | Required? | What it does |
|---|---|---|---|
printer_fleet_manager |
19.0.7.1.1 | Yes - the core product | Discovery, SNMP monitoring, alerts, service history, sites, dashboards, wallboard, mobile page, QR labels, reports, licensing |
printer_fleet_manager_purchase |
19.0.6.4.0 | Optional | Bridge to Odoo Purchase: auto-creates draft reorder RFQs when a consumable crosses its reorder threshold |
Note on SNMP: PFM includes a lightweight, built-in SNMPv1/v2c client implemented over raw UDP sockets. There is no
pysnmp,net-snmp, or any other SNMP library to install. This is the single most common misconception about the module - see §2 and the Troubleshooting section.
base and mail, both
of which are in Community. It has been install-verified on a Community-only
addons path with no Enterprise directory present./opt/odoo; translate paths for your distro.PFM declares exactly one external Python dependency in its manifest:
| Library | Required by | Needed for | If missing |
|---|---|---|---|
qrcode (with a PIL/Pillow backend) |
manifest external_dependencies |
Generating printer QR labels (PDF/HTML) | Module installs and runs normally; only QR-label image generation degrades (label renders without the QR image, a warning is logged). It will not crash install or the registry. |
Install it into the same Python environment Odoo runs in:
# On-prem, virtualenv example:
sudo -u odoo /opt/odoo/venv/bin/pip install "qrcode[pil]"
qrcode[pil] pulls in Pillow, the imaging backend qrcode needs to render
PNGs. If Pillow is already present (it usually is on a full Odoo install you
can just pip install qrcode), the [pil] extra is harmless.
No version pin is required. The manifest declares
qrcodewithout a version constraint; any current release works.
Libraries you do NOT need to install (documented here to prevent wasted effort):
pysnmp - NOT required. SNMP is done over raw sockets in pure Python.cryptography - already present. Ships with Odoo; used by the licensing
client. Do not install it separately unless your Odoo runtime is somehow
missing it.dateutil, psycopg2, markupsafe - these are Odoo core requirements,
already satisfied by any working Odoo install.urllib) to call the Twilio REST API; there is no
twilio pip package to install.PFM ships two QWeb-PDF reports - the Printer QR Label and the
Site Monthly report. Rendering these to PDF requires Odoo's standard
wkhtmltopdf (0.12.6 with the Qt patch, the version Odoo recommends). This is
the same PDF stack every Odoo install uses; if your server already prints any
PDF (invoices, etc.) you are done. If not:
# Debian/Ubuntu - install the Odoo-recommended patched build from the
# wkhtmltopdf releases page for your distro, e.g.:
sudo apt-get install -y ./wkhtmltox_0.12.6.1-3.jammy_amd64.deb
Without
wkhtmltopdf, PFM still installs and runs; only PDF export of those two reports is unavailable. The on-screen dashboards, wallboard, and mobile page do not use it.
Before touching a production server, confirm all of the following:
bash
pg_dump -Fc -h localhost -U odoo -d YOUR_DB -f /var/backups/YOUR_DB-$(date +%m-%d-%Y).dump
Also back up the Odoo filestore (~/.local/share/Odoo/filestore/YOUR_DB
or your configured data_dir).addons_path. Find it in your Odoo config:
bash
grep -E "addons_path" /etc/odoo/odoo.confodoo).Pick the section matching your deployment: 4.1 on-prem, 4.2 Docker, or 4.3 Odoo.sh.
/opt/odoo)Assume: Odoo config /etc/odoo/odoo.conf, systemd unit odoo, OS user
odoo, virtualenv /opt/odoo/venv, and a custom-addons directory already on
addons_path, e.g. /opt/odoo/custom-addons.
Step 1 - install the Python dependency (see §2.4):
sudo -u odoo /opt/odoo/venv/bin/pip install "qrcode[pil]"
Step 2 - unzip the module(s) into a directory on addons_path:
cd /opt/odoo/custom-addons
sudo -u odoo unzip /path/to/printer_fleet_manager-19.0.7.1.1.zip
# Optional Purchase bridge:
sudo -u odoo unzip /path/to/printer_fleet_manager_purchase-19.0.6.4.0.zip
After unzipping you should have /opt/odoo/custom-addons/printer_fleet_manager/
(containing __manifest__.py). Confirm ownership/readability:
sudo chown -R odoo:odoo /opt/odoo/custom-addons/printer_fleet_manager
ls -l /opt/odoo/custom-addons/printer_fleet_manager/__manifest__.py
If your zip extracts to a versioned folder name (e.g.
printer_fleet_manager-19.0.7.1.1/), rename the inner folder to exactlyprinter_fleet_manager- Odoo matches modules by directory name. The directory that contains__manifest__.pymust be namedprinter_fleet_manager.
Step 3 - confirm the directory is on addons_path. If you dropped it in a
directory not already listed, add it and restart:
grep addons_path /etc/odoo/odoo.conf
# addons_path = /opt/odoo/odoo/addons,/opt/odoo/custom-addons
sudo systemctl restart odoo
Step 4 - update the Apps list and install. Two options:
UI: Log in as an administrator → enable Developer Mode (Settings → Developer Tools → Activate the developer mode) → Apps → Update Apps List → search Printer Fleet Manager → Activate/Install.
CLI (recommended for scripted deploys) - installs and exits:
bash
sudo systemctl stop odoo
sudo -u odoo /opt/odoo/venv/bin/python /opt/odoo/odoo/odoo-bin \
-c /etc/odoo/odoo.conf \
-d YOUR_DB \
-i printer_fleet_manager \
--stop-after-init
sudo systemctl start odoo
To also install the optional Purchase bridge in the same run, use
-i printer_fleet_manager,printer_fleet_manager_purchase (note: the bridge
also auto_installs by itself if purchase is already installed - see §7).
Typical single-module install completes in well under a minute on a dedicated host. Verify success:
Modules loaded.in the log and the module shows Installed under Apps.
Using the official odoo:19 image (or your own image built from it):
printer_fleet_manager/ (and optionally
printer_fleet_manager_purchase/) into a host directory you mount at
/mnt/extra-addons, and make sure that path is on addons_path
(the official image already includes /mnt/extra-addons).bash
unzip printer_fleet_manager-19.0.7.1.1.zip -d ./extra-addons
Dockerfile:dockerfile
FROM odoo:19
USER root
RUN pip3 install "qrcode[pil]"
USER odoo
Build and use that image. (Installing with docker exec … pip install
into a running container works but is lost on container recreation - bake
it into the image.)
bash
docker compose run --rm odoo \
odoo -d YOUR_DB -i printer_fleet_manager --stop-after-init
docker compose up -d
SNMP + Docker networking: the container must be able to send UDP/161 to your printers and receive replies. Bridge NAT usually handles outbound UDP fine, but if printers live on other VLANs, ensure the Docker host's routing/firewall permits it (see §6.1).
--network hostis one simple way to give the container the host's L3 reachability if bridge routing is a problem.
Odoo.sh installs modules from your project's Git repository.
Add the module to your repo on the branch you deploy (production /
staging / development). Either commit the printer_fleet_manager folder
directly, or add it as a git submodule if you keep third-party modules
separate. Commit printer_fleet_manager/ (and optionally
printer_fleet_manager_purchase/) at the repo root or under a directory
Odoo.sh includes in the addons path.
Declare the Python dependency. Add a requirements.txt at the root
of your repository (Odoo.sh installs it automatically on build):
text
qrcode[pil]
Odoo.sh already provides
wkhtmltopdfandcryptography, so PDF reports and license verification work out of the box.
PFM is a commercial (OPL-1) module. Licensing is designed to be production-friendly: a licensing communication problem never interrupts printer management. Activate your license so your installation shows as licensed and you receive your Maintenance & Support entitlements.
You must be a Printer Manager (group
printer_fleet_manager.group_printing_manager) to activate - this is enforced
in the server code, not just the menu, so it can't be bypassed over RPC.
The only external host PFM ever contacts is the license server
(license.modulesmith.com, over HTTPS). Each licensing request contains
exactly these fields:
| Field | Value |
|---|---|
key |
Your license key |
db_uuid |
Your Odoo database UUID (database.uuid) |
module_version |
The installed module version (e.g. 19.0.7.1.1) |
nonce |
A random per-request replay guard |
No printer data, no network inventory, no customer records - nothing else leaves your server. All licensing responses are cryptographically verified by the module.
Allow only this single outbound destination for licensing:
Destination host: license.modulesmith.com
Protocol/port: TCP 443 (HTTPS), OUTBOUND only
No inbound rule is needed. If licensing must traverse a corporate proxy, you can override the base URL in Settings → Printer Fleet Manager → License Server URL.
For servers with no outbound internet, use the offline flow. It exchanges a small signed JSON blob by email - no direct connection is ever needed.
pfm-offline-request.json). It contains your key, db_uuid,
module_version, and a timestamp.[email protected]. Support returns a signed
offline-activation response (a small JSON document).While an offline activation is active, no licensing network communication occurs. Request a fresh offline grant before the printed expiry to stay activated.
If your server temporarily cannot reach the license server, the module continues to operate normally; you may see an informational banner until connectivity is restored. If a banner persists, see the troubleshooting section or contact [email protected].
PFM talks to printers from the Odoo host (or Docker container). Your network must permit:
| Direction | Protocol / Port | Purpose |
|---|---|---|
| Odoo host → printers | UDP 161 (SNMP) | Toner levels, status, serial, page counts |
| Odoo host → printers | TCP 9100 (default; also 631 for IPP) | Reachability check / discovery port probe |
| Odoo host → printers | ICMP (optional) | Not required by PFM, but useful for your own connectivity testing |
public). PFM supports SNMPv1 and SNMPv2c (no SNMPv3).Go to Settings → Printer Fleet Manager and review:
public), and leave Query SNMP on to pull model /
serial / toner during discovery.Only Printer Managers may run scans (enforced server-side): scanning port-probes whole ranges and creates records.
All operational crons ship DISABLED by default so the module is inert until you configure printers. Enable the ones you want under Settings → Technical → Automation → Scheduled Actions (Developer Mode). The full list:
| Cron name | Default interval | Ships active? | What it does |
|---|---|---|---|
| Printer SNMP Monitoring | 5 minutes | No | Polls all SNMP-enabled printers (status, toner, page count, alerts). Enable this first. |
| Printer Consumable Refresh | 1 day | No | Syncs toner consumables, snapshots levels for burn-rate, runs reorder checks. |
| Printer Page-Count Snapshot | 1 day | No | Records daily page-count deltas for volume trends/monthly reports. |
| Printer Alert Escalation | 15 minutes | No | Re-notifies + emails the escalation contact for unacknowledged criticals. |
| Printer Warranty Check | 1 day | No | Raises warranty alerts for printers expiring within the warning window. |
| Printer Alert Daily Digest | 1 day | No | One summary email per digest-mode subscriber. |
| Printer Job History Cleanup | 1 day | No | Deletes print-job history older than the retention setting. |
| Printer Discovery: Background Scan Runner | 1 day | Yes | No-op unless a background scan is queued; fires on demand. Leave enabled. |
| Printer Fleet Manager License Check-in | 7 days | Yes | Periodic license check-in. Leave enabled. |
Tuning tips:
http:// or https://.The wallboard is a full-screen, read-only, auto-refreshing fleet status page that a hallway TV/kiosk can display without logging in, guarded by a token.
https://YOUR_ODOO_HOST/printer_fleet/wallboard?token=YOUR_TOKEN
The token is validated, then moved into a secure cookie and stripped from
the URL. The cookie lifetime is the Kiosk Cookie Lifetime setting
(default 30 days; clamped 1-365). Rotating the token instantly revokes old
devices on their next load.Serve the wallboard over HTTPS so the kiosk cookie is set with the
secureflag.
/printer_fleet/mobile/<id>).auth='user') can acknowledge alerts and log service (toner/drum/
fuser/maintenance/jam/repair) right from their phone.qrcode library (§2.4). Label PDF export
requires wkhtmltopdf (§2.5).printer_fleet_manager_purchase)What it does: when both printer_fleet_manager and Odoo Purchase are
installed, this bridge turns consumable reorder thresholds into draft
purchase RFQs.
purchase.order when a consumable crosses its reorder threshold - opt-in
per consumable (auto_po_enabled defaults off).Install: the bridge is auto_install = True, so if both
printer_fleet_manager and purchase are already installed, Odoo installs it
automatically on the next Update Apps List. Otherwise install it explicitly
(-i printer_fleet_manager_purchase, which pulls in purchase).
Its cron ships DISABLED. After you've mapped consumables to products/ vendors and enabled
auto_po_enabledon the ones you want, enable the "Printer Fleet: Auto-Create Reorder RFQs" scheduled action.
unzip/rename-to-printer_fleet_manager steps as install), or pull the new
commit on Odoo.sh / rebuild your Docker image.bash
sudo systemctl stop odoo
sudo -u odoo /opt/odoo/venv/bin/python /opt/odoo/odoo/odoo-bin \
-c /etc/odoo/odoo.conf -d YOUR_DB \
-u printer_fleet_manager --stop-after-init
sudo systemctl start odooUpgrade notes:
noupdate, so an upgrade won't reset the intervals or
enabled/disabled states you chose. (The discovery background-scan runner
cron is intentionally re-synced on upgrade so its internal routing self-healsUninstall from Apps → Printer Fleet Manager → Uninstall (Developer Mode),
or via odoo-bin shell. Uninstall has been verified clean.
What is removed:
What persists:
purchase itself.Order: uninstall
printer_fleet_manager_purchasebefore (or together with)printer_fleet_manager.
Each item is symptom → cause → fix.
1. Install fails / QR labels blank, log shows No module named 'qrcode'
- Cause: the qrcode library isn't installed in Odoo's Python
environment. (The module still installs - QR generation is wrapped in a
guard - but the label QR image will be empty and a warning is logged.)
- Fix: sudo -u odoo /opt/odoo/venv/bin/pip install "qrcode[pil]" into the
same environment Odoo runs from, then restart Odoo. In Docker, bake it
into the image; on Odoo.sh, add qrcode[pil] to root requirements.txt.
2. "The module wants pysnmp / net-snmp" - Cause: a misconception. PFM uses a built-in raw-socket SNMP client. - Fix: do not install any SNMP library - there is no such dependency. If a tool reports one, it's looking at the wrong module.
3. Discovery scan finds nothing (or far fewer printers than expected)
- Cause: the Odoo host has no route to the printer subnet/VLAN, or a
firewall/ACL blocks the TCP probe port (9100) and/or UDP 161; or the
scan range/port is wrong; or the per-IP timeout is too low for slow devices.
- Fix: verify L3 reachability from the Odoo host
(nc -vz PRINTER_IP 9100, ping PRINTER_IP); confirm firewall/ACL permits
UDP/161 + TCP/9100 from the Odoo host to the printer VLANs; narrow the range
(max 1024 IPs); raise the scanner timeout; confirm the correct scan port.
4. Printers discovered by port but no model/serial/toner filled in
- Cause: SNMP is disabled on the printer, the community string is
wrong (default is public), or the device only speaks SNMPv3 (unsupported).
- Fix: enable SNMP read (v1/v2c) on the printer, set the correct community
string in the scan (and later on the printer record), and re-scan. PFM does
not support SNMPv3.
5. Printer shows "Offline - Port not responding" but it's actually up - Cause: the reachability check connects to the printer's configured TCP port (default 9100). If the device serves on a different port (e.g. IPP 631) or that port is firewalled, the check fails even though SNMP works. - Fix: set the correct Port on the printer record and ensure it's reachable from the Odoo host.
6. No SNMP updates happening at all (toner/status never changes) - Cause: the "Printer SNMP Monitoring" cron is disabled (it ships off by default), or the printer's SNMP Enabled flag is off. - Fix: enable the cron (Settings → Technical → Scheduled Actions) or set the poll interval in Settings; enable SNMP on the printer record. Confirm Odoo has at least one worker/cron thread running.
7. SNMP polls time out for some printers - Cause: slow devices, congested/high-latency VLANs, or a too-short SNMP timeout. - Fix: increase SNMP Timeout (ms) in Settings (default 3000). Confirm UDP/161 isn't rate-limited by an intermediate firewall.
8. No alert emails / no digest emails - Cause: no working Outgoing Mail Server configured in Odoo, or the relevant crons (Escalation / Daily Digest) are disabled, or users have no notification subscriptions with the Email channel. - Fix: configure Settings → Technical → Email → Outgoing Mail Servers and send a test; enable the Escalation and/or Daily Digest crons; have users create subscriptions with Email enabled.
9. PDF export of QR labels / monthly report fails or is missing
- Cause: wkhtmltopdf is not installed (or not the Odoo-recommended
patched build).
- Fix: install the patched wkhtmltopdf 0.12.6 (§2.5) and restart Odoo.
On-screen dashboards/wallboard don't need it - only the two QWeb-PDF reports.
10. Wallboard shows "Forbidden / invalid or missing kiosk token"
- Cause: the kiosk token is blank (public access disabled), or the URL
token doesn't match, or the kiosk cookie expired.
- Fix: set/generate a token in Settings; browse to
…/printer_fleet/wallboard?token=YOUR_TOKEN once to seed the cookie; serve
over HTTPS. Rotating the token intentionally logs out all kiosks.
11. License banner won't go away / "Could not reach the license server"
- Cause: the server can't reach license.modulesmith.com:443 outbound
(firewall/proxy), or a proxy is mangling the response so signature
verification fails.
- Fix: allow TCP 443 outbound to license.modulesmith.com (§5.3), or
set a proxy-friendly License Server URL in Settings, or use Offline
Activation (§5.4). The banner is informational - printer management is
not interrupted.
12. Background discovery scan stuck in "Queued/Scanning" - Cause: the "Printer Discovery: Background Scan Runner" cron is disabled, or a worker died mid-scan. - Fix: ensure that cron is active (it ships enabled). Scans stuck longer than 30 minutes, or that fail 3 background attempts, are automatically failed with a message; use Reset on the scan to try again.
13. Auto-RFQ (Purchase bridge) never creates RFQs
- Cause: the "Printer Fleet: Auto-Create Reorder RFQs" cron is disabled
(ships off), consumables aren't mapped to a product/vendor, or
auto_po_enabled isn't set on those consumables, or an open RFQ/PO already
covers them (dedup).
- Fix: map each consumable to a purchasable product + vendor, enable
auto_po_enabled per consumable, then enable the cron.
Email [email protected]. To get a fast, accurate answer, include:
journalctl -u odoo). Redact secrets - the module never logs your
license key.Printer Fleet Manager 19.0.7.1.1 - © ModuleSmith. Licensed under OPL-1.
Premium Odoo modules, forged with care.
Terms of Use · Privacy Policy · Terms of Sale · Refund Policy · Maintenance & Support
© 2026 ModuleSmith · All rights reserved · Odoo is a trademark of Odoo S.A. ModuleSmith is an independent vendor.