Niimbot Label Printer Custom Integration

Hm I am also having issues with the speed here… I noticed it works a lot better though when I disable the Bermuda BLE and Passive BLE Tracker integrations (that I was not using for the most part anyway…) I also disabled active scanning there…

Still need to to more testing…

B21 Pro has been added very recently, although to be fair it’s not 100% reliable (sometimes it prints an empty label, guh). It’s probably my fault.

There is also a crash concerning labels with large amounts of vertical empty space, that will be fixed after another (currently open) PR is merged.

Finally, a new element type of new_multiline may be added soon, which will auto-fit the width of multiline text to a bounding box you can define.

1 Like

The latest features:

  • performance settings to tweak how HA talks to the printer and make it go faster
  • a “last label made” image entity that you can place on your dashboard
  • preview-only mode for when you want to design a label using the niimbot.print service call but you don’t want to waste paper; complements last label made image very well
  • multiline labels with auto-fit line width

It’s looking good! Thanks to eigger for prompt PR reviews.

This should be fixable with the new config settings (you can test them via the service call, but to make them permanent you have to delete and readd the config entry).

Hey everyone,
Is anyone else getting this error message in Home Assistant when their Niimbot is offline?

The automation “Etikette - Essen” (automation.etikette_essen) has an unknown action: niimbot.print.

This error prevents the automation from running correctly. This action may no longer be available or it may have been caused by a typo.

To fix this error, edit the automation and remove this action.

Click OK below to confirm that you have corrected this automation.

It seems to happen whenever the printer isn’t running. Any ideas?

I have never gotten that notification. If my printer is offline, instead of getting a notification like that, I get an error in the trace of the automation or script that ran the service call.

By the way, the combination of Grocy (the Inventory for Personal Homes app), its support for label making via JSON and HTTP REST endpoint, and Home Assistant with the Niimbot is PHENOMENAL.

SUP FOLKS MEGA HEADS UP FOR ALL NIIMBOT PRINTER USERS:

If you are using Bluetooth proxies to print labels with this integration (almost certain many of you are), update your Bluetooth proxies to ESPHome 2025.11.2 right now.

Prints that would take 20-30 seconds before now come out in a flash. It’s almost instantaneous.

Reliability of prints is also enormously improved. I used to see refusal to print (until the integration was reloaded) every 3 out of 10 labels. Now it works errytiem always.

Seriously, leap into the latest ESPHome ASAP.

The main technical reason for this improvement is that, whereas before, every line sent to the printer would wait for an acknowledgement up to 16 milliseconds in the event loop of the Bluetooth proxy device, now these GATT acknowledgments are received instantaneously and processed using a loopback process inside of the ESP device. In previous iterations of the integration, I added a feature that would allow BT proxies to relay a configurable number of print lines without waiting for acknowledgments, but relying on that usually came at the cost of reliability. Now that acknowledgments are lightning fast, this does not need to be enabled, although you still might see some tiny improvement in print speed compared to the baseline configuration. It should also be possible to configure a lower time to wait between print lines being sent, and gain performance this way.

OP you may want to update the README to mention this development.

1 Like

Thanks a lot for the heads-up!
Really appreciate the info — I’ll make sure to add this to the README.

1 Like

I’ve been trying to get this to work with my D11, but I can’t keep the bluetooth connected and no entity for the device itself is created. I can confirm it does however work without issue on https://niim.mmote.ru, any thoughts?

Could you check whether there are any error messages in the logs and upload them?

Log details (ERROR)
Logger: homeassistant.helpers.script.websocket_api_script
Source: helpers/script.py:2070
First occurred: February 5, 2026 at 10:16:41 PM (4 occurrences)
Last logged: February 5, 2026 at 10:19:00 PM

websocket_api script: Error executing script. Error for call_service at pos 1: Failed to print: printer model None is not known to the niimprint library

Log details (ERROR)

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/connection.py:315
integration: Home Assistant WebSocket API ([documentation](https://www.home-assistant.io/integrations/websocket_api), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+websocket_api%22))
First occurred: February 5, 2026 at 10:16:41 PM (4 occurrences)
Last logged: February 5, 2026 at 10:19:00 PM

[126808329449568] Error handling message: Failed to print: printer model None is not known to the niimprint library (home_assistant_error) Shane Ronan from 192.168.5.36 (Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36)

Log details (WARNING)

This error originated from a custom integration.

Logger: custom_components.niimbot
Source: custom_components/niimbot/__init__.py:106
integration: Niimbot ([documentation](https://www.github.com/eigger/hass-niimbot), [issues](https://www.github.com/eigger/hass-niimbot/issues))
First occurred: February 5, 2026 at 10:08:06 PM (19 occurrences)
Last logged: February 5, 2026 at 10:31:01 PM

* Unable to fetch data from 01:16:DC:7D:BC:2F: 'ascii' codec can't decode byte 0xdc in position 0: ordinal not in range(128)
* Unable to fetch data from 01:16:DC:7D:BC:2F:
* Unable to fetch data from 01:16:DC:7D:BC:2F: 01:16:DC:7D:BC:2F - 01:16:DC:7D:BC:2F: Failed to connect after 4 attempt(s): Timeout waiting for connect response while connecting to 01:16:DC:7D:BC:2F after 20.0s, disconnect timed out: False, after 20.0s
* Unable to fetch data from 01:16:DC:7D:BC:2F: 01:16:DC:7D:BC:2F - 01:16:DC:7D:BC:2F: Failed to connect after 11 attempt(s): No backend with an available connection slot that can reach address 01:16:DC:7D:BC:2F was found: The proxy/adapter is out of connection slots or the device is no longer reachable; Add additional proxies (https://esphome.github.io/bluetooth-proxies/) near this device
* Unable to fetch data from 01:16:DC:7D:BC:2F: 01:16:DC:7D:BC:2F - 01:16:DC:7D:BC:2F: Failed to connect after 9 attempt(s): No backend with an available connection slot that can reach address 01:16:DC:7D:BC:2F was found: The proxy/adapter is out of connection slots or the device is no longer reachable; Add additional proxies (https://esphome.github.io/bluetooth-proxies/) near this device

Please update to version 1.3.4 and try again.
If you continue to experience any errors, unexpected behavior, or issues with the entity configuration not loading, please provide the relevant debug logs from that time.

2026-02-06 10:07:34.489 WARNING (MainThread) [custom_components.niimbot] Unable to fetch data from 01:16:DC:7D:BC:2F:
2026-02-06 10:08:11.495 WARNING (MainThread) [custom_components.niimbot] Unable to fetch data from 01:16:DC:7D:BC:2F:

Printer initially connects to HA, but after about 5 seconds disconnects. If I reload the integration, it connects again for five seconds and disconnects. I was able to get it to print using the action, it connects and immediately disconnects after the print is complete.

Here is the data from NiimBlue, where it stays connected without issue.

Printer info:

  • connectResult: 2

  • protocolVersion: 1

  • modelId: 512

  • serial: DC160127

  • mac: 01:16:dc:7d:bc:2f

  • charge: 4

  • autoShutdownTime: 1

  • labelType: 1

  • hardwareVersion: 0x07d1 (9.09 or 20.01)

  • softwareVersion: 0x07e0 (9.24 or 20.16)

  • model: D11

  • id: 512

  • dpi: 203

  • printDirection: left

  • printheadPixels: 96

  • paperTypes: 1,5

  • densityMin: 1

  • densityMax: 3

  • densityDefault: 2

The disconnection is intentional by design.
The component periodically reconnects to retrieve the necessary information and then disconnects.
Printing also follows the same approach: it connects only when a print request is made, completes the print job, and then disconnects.

1 Like

Attention: the B21 Pro printer seems to have a firmware fault whereby if you leave it charging “forever”, at some point it will discharge to zero and will refuse to charge unless disconnected, power cycled and reconnected. You may have prints fail with “low battery” error messages when the printer is at zero battery (but still enough juice to stay alive).

It seems like the printer simply isn’t built to stay connected all the time.

The fix I found was to plug it to a remotely controlled Sinilink USB plug, which in turn is automated to keep the printer between 75% and 25% battery, thus avoiding the B21 Pro getting to 100% battery and then no longer charging.

Sample automation follows:

alias: Keep label printer at half-charge
description: ""
triggers:
  - alias: On with high battery
    trigger: template
    value_template: |-
      {{ (
           has_value("sensor.kitchen_label_printer_battery")
           and
           states("sensor.kitchen_label_printer_battery") | int > 74
         )
         and is_state("switch.kitchen_label_printer_charger", "on") }}
    for:
      hours: 0
      minutes: 1
      seconds: 0
    id: above
  - alias: Off with printer AWOL or low battery
    trigger: template
    value_template: |-
      {{ (
            not has_value("sensor.kitchen_label_printer_battery")
            or
            states("sensor.kitchen_label_printer_battery") | int < 26
         )
         and is_state("switch.kitchen_label_printer_charger", "off") }}
    id: below
    for:
      hours: 0
      minutes: 1
      seconds: 0
  - trigger: homeassistant
    event: start
conditions: []
actions:
  - choose:
      - conditions:
          - alias: On with high battery
            condition: template
            value_template: |-
              {{ (
                   has_value("sensor.kitchen_label_printer_battery")
                   and
                   states("sensor.kitchen_label_printer_battery") | int > 74
                 )
                 and is_state("switch.kitchen_label_printer_charger", "on") }}
        sequence:
          - action: switch.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: switch.kitchen_label_printer_charger
      - conditions:
          - condition: template
            value_template: |-
              {{ (
                    not has_value("sensor.kitchen_label_printer_battery")
                    or
                    states("sensor.kitchen_label_printer_battery") | int < 26
                 )
                 and is_state("switch.kitchen_label_printer_charger", "off") }}
            alias: Off with low battery
        sequence:
          - action: switch.turn_on
            metadata: {}
            data: {}
            target:
              entity_id: switch.kitchen_label_printer_charger
mode: single

I have a post in this forum explaining how to flash the Sinilink USB switch with ESPHome.

1 Like

Something got really bad with ESPHome 2026.1.3, now it’s slow enough to be totally unresponsive even to scanning the printer characteristics.

Not sure what happened in between.

If I force the device to use my other proxy with 2025.11.3, it works fine.

EDIT:

Hooray!

Today I put up my B21 Pro for sale!

What did I replace it with? A different set of problems, but this one is all solvable problems:

To continue making my labels automations work, I created two new integrations:

GitHub - Rudd-O/hass-simple-image-raster: Generate pictures on the fly to print or update ePaper displays. Simple image rasterizer based on PIL / Pillow (derived from Niimbot Label Printer Home Assistant Integration). · GitHub draws labels (thanks @eigger for the code).

GitHub - Rudd-O/homeassistant-ipp-printing: Service to add printing capabilities to Home Assistant · GitHub for actually printing the rasterized labels.

And I rewired my scripts to use them instead of niimbot.print. Render then print. Frankly I think that is more elegant than having everything in a single service.

Is it more expensive? Yeah, more than twice as much. Nothing says “I am made of money” more than when you verbally order the home to print you a label on a DYMO label maker. OK maybe it would be more dramatic if it was a ZEBRA printer.

Is it more reliable? Yes, it is; it works every time, doesn’t power off, doesn’t give me GATT attribute bullshit or battery issues. Literally Ethernet and 12 volts. Ah, and the labels print in under 2 seconds.

Frankly the NIIMBOT printer seemed like a good idea and cheap too, but such printers are simply not intended for anything beyond drawing a cute label every once in a blue moon using an app. Anything more pro is out of the question. I’m tapping out.

OLD CONTENT FOLLOWS


Script -based procedure to fix printer when it stops working. Change used entities and devices to match yours. Note the Bluetooth proxy that the script restarts here is the closest to the printer. This script is simplified — my own version disconnects power to the printer, but you’ll have to do that by hand.

Before launching the script, read the description and follow the instructions!

sequence:
  - parallel:
      - sequence:
          - action: button.press
            metadata: {}
            target:
              entity_id: button.bluetooth_proxy_restart
            data: {}
          - delay:
              hours: 0
              minutes: 0
              seconds: 5
              milliseconds: 0
          - wait_template: "{{ has_value(\"sensor.bluetooth_proxy_uptime\") }}"
            continue_on_timeout: true
          - delay:
              hours: 0
              minutes: 0
              seconds: 5
              milliseconds: 0
  - action: homeassistant.reload_config_entry
    metadata: {}
    data:
      entry_id: 01K4XM3C2ZFTHSTQSFZ4Q8J0XS
    continue_on_error: true
  - action: niimbot.print
    metadata: {}
    target:
      device_id: b6e592d56d694847d02172dad9991622
    data:
      payload:
        - type: text
          value: ""
          x: 5
          "y": 5
          size: 40
      width: 400
      height: 240
      density: 5
    continue_on_error: true
alias: Try to fix the Niimbot printer
description: >-
  Disconnect the printer charger, wait ten seconds, reconnect the printer.  Turn the printer off, wait three seconds, then turn the printer on. Only then
  run this script.


  If this works, then the printer will print an empty label.  You can open the
  printer and rewind the roll to reuse it.
1 Like

I just set this up and it seems pretty great. Is it possible for it to print sensor values? I didn’t see that in any of the examples, but it seems like it should be possible…

Yes, of course it’s possible. You can use a Jinja2 template: {{ states('sensor.temperature') }}