npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

iobroker.hassemu

v1.38.0

Published

Emulates a minimal Home Assistant server so devices expecting a Home Assistant dashboard can display any custom web URL.

Readme

ioBroker.hassemu

Release: npm version stable Installations npm downloads

Build: Test and Release Node TypeScript License Sentry

Support: Ko-fi PayPal

Emulates a Home Assistant server so displays that only accept an HA dashboard show any web URL instead.


What it's for

The display completes the HA onboarding, then shows whatever web URL you point it at — VIS, VIS-2, Aura, Grafana, Node-RED, anything HTTP.

Typical clients: Shelly Wall Display family (built-in HA page; on-device HA app on firmware 2.6.0+), Home Assistant Companion App (Android wall panels, sideloaded apps). Anything that uses the same HA onboarding flow should work — if yours doesn't, open an issue with the failing endpoint trace.


Features

  • One URL per display, or one global URL for all
  • Auto-discovery via mDNS, plus auto-detect of every VIS / VIS-2 / Aura instance installed on the host (see Supported dashboards below)
  • Two HA login flows in parallel — the classic JSON login_flow for older clients, plus the browser-OAuth2 flow used by the on-device HA app on Shelly Wall Display 2.6.0+
  • Mobile-App registration emulation so the HA Companion App finishes onboarding
  • Cookie-based: displays keep their URL across reboots, IP changes, renames

Sentry / Error reporting

This adapter uses Sentry libraries to automatically report exceptions and code errors to the developers. Reporting only happens if you have enabled error reporting in the ioBroker diagnostics (System settings → Diagnostics and error reporting). Only an anonymous installation ID is transmitted — no name, e-mail address or IP address.

For details and how to disable it, see the Sentry plugin documentation. Error reporting requires js-controller 3.0 or newer.


Supported dashboards

The mode dropdown auto-discovers what's installed on your ioBroker host. You always have the option to paste any other HTTP URL as manual.

| Source | What gets discovered | Notes | | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ioBroker VIS (vis.0+) | One entry per project, plus one entry per view inside each project | Works with every web.* instance — multiple web instances get a (web.X) suffix on the label | | ioBroker VIS-2 (vis-2.0+) | Same — one entry per project, one per view | Project + view encoded into the URL (?<project>#<view>); deep links work | | ioBroker Aura (aura.0+) | One entry per running aura instance, pointing at its frontend | Reads the actual native.port configured in aura (default 8095, ignores the hardcoded value in aura's localLinks template) — works with https and customUrl overrides | | Admin tiles | Anything an adapter advertises via common.localLinks / common.welcomeScreen (jarvis, material, grafana, custom UI…) | Resolves %ip%, %port%, %protocol%, %bind%, and cross-instance refs like %web.0_port% | | Manual URL | A free-text URL of your choice — Grafana, Node-RED, custom HTML, anything HTTP/HTTPS | Set the display's mode to manual and the URL in manualUrl. javascript:, data:, file: are rejected for safety |

Want to add a URL the adapter doesn't auto-detect? Set manual and paste it.


Requirements

  • Node.js ≥ 22
  • ioBroker js-controller ≥ 7.2.2
  • ioBroker Admin ≥ 7.8.23

Ports

| Port | Use | | ---------- | ----------------------------------- | | 8123 / TCP | HA emulation (fixed, HA standard) | | 5353 / UDP | mDNS broadcast (only if mDNS is on) |

One instance per host. Port 8123 is HA-fixed. With multiple ioBroker hosts on the same LAN, only one of them runs hassemu.

All traffic is plain HTTP — HA clients do not support HTTPS on this flow. Treat port 8123 as LAN-only and never forward it to the internet. With authentication on, the username, password and tokens travel unencrypted over your LAN, so Auth guards the HA API against other LAN devices — it is not internet-exposure protection.


First steps

  1. Start the hassemu instance in ioBroker.
  2. On the display, add a Home Assistant server. With mDNS on it appears automatically; otherwise enter http://<ioBroker-IP>:8123 by hand.
  3. Complete the HA onboarding on the display. With Auth off you can click through the login; with Auth on, enter the username and password from the instance settings.
  4. The display now shows the landing page with its own device ID — that means it is connected and waiting for a URL.
  5. In ioBroker, open the Object Browser and set hassemu.0.clients.<id>.mode for that device: pick a discovered URL from the dropdown, or choose manual and put any URL in clients.<id>.manualUrl.
  6. The display reloads within ~30 seconds and shows your URL.

Want the same URL on every display? Set global.mode (plus global.manualUrl for a free URL) and turn on the global.enabled master switch instead of configuring each client.


Configuration

| Option | What | Default | | ------------------- | --------------------------------------------------------------------------------- | --------- | | Bind | Network interface | 0.0.0.0 | | Service Name | Name the display sees | ioBroker | | mDNS | LAN auto-discovery. Off → set http://<ioBroker-IP>:8123 on the display by hand. | on | | Auth | Login required (guards the HA API on the LAN; credentials travel in plain HTTP) | off | | Username / Password | When Auth is on | admin / — | | Trust Proxy | Only behind a trusted reverse proxy that terminates TLS and strips X-Forwarded-* | off |


State tree

hassemu.0.
├── info.
│   ├── connection      — server is running
│   ├── serverUuid      — server identity (read-only)
│   └── refreshUrls     — re-scan URL list (button, set to true)
├── global.
│   ├── enabled         — master switch
│   ├── mode            — URL choice used by every client whose mode is `global`
│   └── manualUrl       — free-text URL, used when global.mode = `manual`
└── clients.
    └── <id>            — one channel per display (channel name = hostname or IP)
        ├── mode        — per-client URL choice
        ├── manualUrl   — free-text URL, used when mode = `manual`
        ├── ip          — last seen client IP
        └── remove      — forget this client (button, set to true)

Which URL does the display get?

| mode | URL | | ------------- | ----------------- | | global | use global.mode | | manual | use manualUrl | | a URL | that URL | | empty (---) | landing page |

Master switch:

  • on — all displays follow global.mode
  • off — all displays go back to ---
  • new displays always start at ---

Refresh

The display reloads itself within ~30 seconds after a URL change.

After adding or renaming a VIS-2 project or view, set info.refreshUrls to true so it shows up in the dropdown.

If hassemu goes offline while a display is running, the display switches to a clear offline page with a reload button after ~1.5 minutes and returns to your dashboard automatically once hassemu is back. Limitation: a display that cold-boots while hassemu is down can't load that page and shows a connection error until the adapter is running again.


Troubleshooting

Set the instance log level to debug first — since v1.31.1 the adapter traces every decision point (identify, OAuth2, URL discovery, resolver chain, mobile-app webhooks, master switch). Most symptoms are triage-able from that log alone.

Display can't find the server — with mDNS on, the log should show mDNS: Broadcasting. If that line is missing, mDNS failed to bind (port 5353/UDP). Workaround: turn mDNS off in the instance config and point the display at http://<ioBroker-IP>:8123 by hand.

Display shows the wrong URL or the landing page — open Object Browser, check clients.<id>.mode (and manualUrl if mode is manual). At mode='global', also check global.mode / global.manualUrl. The device id is shown on the landing page and stored at clients.<id>.ip. The debug log shows the full resolver chain (chain=global→manual→…) per request.

Display lost its identity (new id on every visit) — the display is not persisting the cookie. Common causes: aggressive privacy mode, factory reset, browser cache flush. The old clients.<id>-channels can be removed via their remove button, but the root cause is on the display side, not in hassemu.

HA Companion App says "Server is not Home Assistant" — point the app at http://<ioBroker-IP>:8123, not at the ioBroker Admin port. If a reverse proxy is in front of hassemu, make sure /manifest.json is passed through unmodified — the App parses name === "Home Assistant" to verify the server.

Aura entry in the dropdown points at the wrong portnative.port of the Aura instance must match its actually-listening port. Trigger info.refreshUrls = true to re-run discovery after fixing the Aura config.


Upgrade

Migration runs automatically when the adapter starts.

Got scripts that still write to visUrl? Update them — write to manualUrl instead and set mode to manual.

Coming from a Shelly Wall Display on firmware 2.6.0 or newer? Make sure you're on hassemu ≥ 1.29.2. The on-device HA app introduced in firmware 2.6.0 needs a server-identity probe, a mobile-app registration step and a WebView "connected" signal — all three came in with v1.29.0–v1.29.2. After upgrading, run the display through the on-device HA onboarding once more.


Changelog

1.38.0 (2026-07-12)

  • Known displays were re-created as new clients after every adapter restart — losing their saved redirect and login, and leaving duplicates. The display list is now restored correctly.
  • The setup screen on the display now explains how to pick a dashboard from the dropdown, or choose Manual URL and enter your own address next to it.
  • The global and per-display redirect datapoints now have descriptions explaining each option, and everything you see consistently says display.
  • The sign-in and error pages shown while a display is onboarding now appear in your ioBroker language instead of English only.

1.37.1 (2026-07-11)

  • Internal cleanup. No user-facing changes.

1.37.0 (2026-07-09)

  • A custom name you give a display now survives even when its network hostname resolves later — the name you set sticks.
  • A display that keeps losing its identity no longer fills ioBroker with unused entries over time.
  • A display connection that simply goes away (a panel powered off) is now cleaned up instead of lingering until the adapter restarts.
  • The manual URL-refresh datapoint is now info.refreshUrls (was info.refresh_urls); the old one is removed automatically on upgrade — update any script that wrote to the old name.
  • Corrected the configuration help texts and the README to match the current setup, documented the offline behaviour, and added a first-steps guide.

1.36.0 (2026-06-22) — stable

  • Fixed a rare adapter crash and restart loop that a malformed connection message could trigger — it briefly took all connected displays offline until the adapter recovered.
  • A custom name you give a display (its channel name) is no longer overwritten with the device's IP address when that IP changes.
  • With authentication enabled, a display again reloads automatically after you change its target URL.
  • With authentication enabled, a password is now required — the settings can no longer be saved with an empty password.

1.35.3 (2026-06-15)

  • Fixed Home Assistant discovery pointing the display at the wrong address on multi-interface hosts; it now uses the address the adapter actually listens on.

Older changelogs can be found there

Support Development

This adapter is free and open source. If you find it useful, consider buying me a coffee:

Ko-fi PayPal


License

MIT License

Copyright (c) 2026 krobi [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Developed with assistance from Claude.ai