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.zeptrion

v0.8.3

Published

ioBroker Adapter für Feller zeptrion / zApp WLAN-Aktoren (WLAN-Nebenstelle 4K, WLAN-Zwischenmodul 2K) über die zrap Webservice API - inkl. Sammelbefehlen für Hagelalarm und mDNS-Discovery

Readme

ioBroker.zeptrion

Logo

NPM version Downloads Tests License

Adapter für Feller zeptrion / zApp WLAN-Aktoren (WLAN-Nebenstelle 4K = zApp-Gateway, WLAN-Zwischenmodul 2K = zApp-Booster) für Licht- und Storensteuerung, basierend auf der zrap Webservice API (Feller-Dokument 10.ZEPAPI-E.1612 / Version 1.0, Firmware ab 01.08.18).

Funktionsumfang

  • Kanalsteuerung (zrap/chctrl): on/off/stop/toggle, open/close, move_open/move_close, dim_up/dim_down inkl. zeitgesteuerter Varianten (_t in ms), sowie Szenen recall_s1-4 / store_s1-4 / delete_s1-4 - als einzelne Buttons UND als freies command-Textfeld.
  • Kanalzustand (zrap/chscan als periodischer Resync + zrap/chnotify als Long-Poll-Push für nahezu Echtzeit-Updates) und Kanalbeschreibung (zrap/chdes, read/write: Name, Gruppe, Icon, Typ, Kategorie).
  • Geräteinformationen (zrap/id): Hardware-/Software-/Bootloader-Version, Seriennummer, Systemname, Gerätetyp.
  • Signalstärke (zrap/rssi, gepollt).
  • Netzwerkstatus (zrap/net, read-only): SSID, IP, MAC, Modus, Verschlüsselung, Maske, Gateway.
  • Systembefehle (zrap/sys): Neustart, Werksreset, Zurücksetzen in Access-Point-Modus.
  • Standort (zrap/loc), NTP-Konfiguration (zrap/ntp) und Datum/Zeit (zrap/date) inkl. Ein-Klick-Synchronisation der Geräte-Uhrzeit mit dem ioBroker-Host.
  • mDNS-Discovery (Kapitel 4 der API-Doku): durchsucht das lokale Netz nach zeptrion-Geräten und übernimmt Funde deaktiviert in die Konfigurationstabelle (Discovery kombiniert mit manueller Kontrolle/Aktivierung).
  • Sammelbefehle für Hagelalarm: control.closeAllShutters / openAllShutters / stopAllShutters steuern alle konfigurierten Kanäle über alle aktiven Geräte gleichzeitig
    • dank Multicast-Bündelung (siehe unten) als je EIN Request pro Gerät, nicht pro Kanal.
  • Multicast-Befehlsbündelung: Kanalbefehle desselben Geräts, die innerhalb von 50ms eintreffen, werden automatisch zu einem einzigen zrap/chctrl-Multicast-POST gebündelt (Kapitel 3.6.5 der API-Doku) statt mehrerer sequentieller Einzelrequests.
  • Storen-Positionsschätzung (optional, posEstimate): da die Hardware laut Doku für Storenkanäle praktisch immer -1 (unbekannt) liefert, kann pro Gerät eine Motor-Laufzeit hinterlegt werden; der Adapter schätzt daraus die Position anhand Bewegungsrichtung und verstrichener Zeit (Best Effort, kein Hardware-Feedback, manuell kalibrierbar).
  • Smartfront-Unterstützung (optional, zapi/smartfront/*): Temperatur/Helligkeit/ Luftfeuchtigkeit auslesen, LED-Hintergrundfarbe setzen (nur für Geräte mit angeschlossenem Feller-Smartfront-Taster, Checkbox in der Konfiguration).
  • Robustes Error-Handling: unterscheidet ECONNREFUSED/Timeout/DNS-Fehler, Backoff bei wiederholten Fehlern, pro Gerät und global sichtbarer Verbindungsstatus. mDNS-Discovery ist zusätzlich gegen Exceptions durch fremde/kaputte Netzwerkpakete abgesichert.

Nicht implementiert (siehe "Bekannte Einschränkungen"): Schreibzugriff auf zrap/net (WLAN-Zugangsdaten ändern), zrap/scheduler, Smartbutton-Webhook-Programmierung (zapi/smartbt/*).

Installation

a) Lokal/manuell (vor Store-Veröffentlichung)

cd /opt/iobroker/node_modules
mkdir iobroker.zeptrion
# Dateien dieses Pakets hierhin kopieren
cd iobroker.zeptrion
npm install --production

cd /opt/iobroker
iobroker upload zeptrion
iobroker add zeptrion

b) Über den ioBroker Adapter-Store (nach erfolgter Veröffentlichung)

Admin-Oberfläche -> Adapter -> "zeptrion" suchen -> Installieren.

Konfiguration

  • HTTP Timeout: Timeout pro Request an ein Gerät (Default 4000 ms).
  • Discovery-Button: durchsucht das lokale Netz per mDNS (Service-Type _zapp._tcp, Fallback _http._tcp für Firmware < 01.08.xx anhand des Hostname-Musters zapp-YYWWNNNN). Neu gefundene Geräte werden deaktiviert in die Tabelle übernommen - Zeile danach prüfen, ID/Name vergeben, Kanalzahl kontrollieren (3340-4-x = 4 Kanäle, 3340-2-x = 2 Kanäle) und aktivieren. mDNS funktioniert nur innerhalb des gleichen Netzsegments/VLANs.
  • Geräte-Tabelle (auch komplett manuell befüllbar, ohne Discovery):
    • Aktiv, ID (a-z 0-9 _ -), Bezeichnung, IP-Adresse/Hostname, Kanäle (1-4), Art (Storen/Licht/unbekannt - steuert die ioBroker-Objektrollen, siehe unten), Laufzeit Storenmotor (Sekunden, 0=deaktiviert - schaltet posEstimate frei, siehe unten, gilt als Standard für alle Kanäle), Laufzeit/Kanal (optional, kommagetrennt, z.B. 22,28 - überschreibt die Standard-Laufzeit einzeln je Kanal; nützlich bei 2K-Geräten, deren beide Kanäle unterschiedliche Motor-Laufzeiten haben; leere Einträge fallen auf die Standard-Laufzeit zurück), Smartfront (Checkbox, nur bei angeschlossenem Feller-Smartfront-Taster aktivieren), Poll (s) (Default 30, für RSSI + periodischen chscan-Resync; die eigentlichen Kanalupdates laufen über den chnotify-Long-Poll unabhängig davon).

Objektbaum pro Gerät (zeptrion.0.<id>)

<id>.info.connection / lastError / hw / sw / boot / sn / sys / type / oen / rssi / refresh
<id>.network.ssid / ip / mac / mode / enc / mask / gw / bssid        (read-only)
<id>.system.reboot / unlock / factoryDefault / networkDefault      (Buttons; factoryDefault erfordert unlock binnen 30s)
<id>.location.name                                                  (read/write)
<id>.ntp.url / per                                                   (read/write)
<id>.date.rfc1123 / tz / dst / syncNow                               (read/write + Button)

<id>.channels.chN.val                                    Kanalzustand 0-100 / -1 (roher Hardwarewert)
<id>.channels.chN.posEstimate                             nur bei Art=Storen: Software-Positionsschätzung
                                                           0=zu/100=offen, auch manuell schreibbar (Kalibrierung)
<id>.channels.chN.name / group / icon / type / cat        Kanalbeschreibung (read/write)
<id>.channels.chN.command                                 freies Kommando (String)
<id>.channels.chN.stop / on / off / toggle / open / close /
                  move_open / move_close / dim_up / dim_down        (Buttons)
<id>.channels.chN.recall_s1..4 / store_s1..4 / delete_s1..4          (Buttons)

<id>.smartfront.temp / lux / hum       nur wenn "Smartfront" aktiviert (read)
<id>.smartfront.ledState               aktueller LED-Status als JSON (read)
<id>.smartfront.ledSet                 LED(s) setzen, JSON-Array (write)

Global:

info.connection                mind. ein Gerät erreichbar
control.closeAllShutters       Button: ALLE konfigurierten Kanäle -> "close"
control.openAllShutters        Button: ALLE konfigurierten Kanäle -> "open"
control.stopAllShutters        Button: ALLE konfigurierten Kanäle -> "stop"

Objekt-Rollen und "Art" (kind)

Die zrap-API selbst unterscheidet nicht zwischen Licht- und Storenkanal - das steckt allein in der Verkabelung/im Aktor. Damit Visualisierungen (VIS, evtl. spätere ioBroker.iot/Alexa-Anbindung) Kanäle trotzdem sinnvoll klassifizieren können, kann pro Gerät die "Art" gesetzt werden:

| Art | <ch>.val Rolle | stop/open/close Rolle | |---|---|---| | Storen/Rolladen | level.blind | button.stop / button.open.blind / button.close.blind | | Licht | level.dimmer | generisch button | | unbekannt (Default) | value | generisch button |

Wichtig: level.blind täuscht keine echte Positionsrückmeldung vor - laut Feller-Doku liefert chscan/chnotify für einen Storenkanal so gut wie immer -1 (unbekannt), da die Hardware selbst keine Lamellenposition zurückmeldet. Die Rolle verbessert nur die Erkennung durch VIS-Widgets, der Zahlenwert bleibt i.d.R. uninformativ.

Hagelalarm-Nutzung

// JavaScript-Adapter Beispiel
on({id: 'wetter.0.warnungen.hagel', val: true}, function () {
    setState('zeptrion.0.control.closeAllShutters', true);
});

Fehler bei einzelnen Geräten (offline etc.) unterbrechen die übrigen Kanäle nicht - jeder fehlgeschlagene Kanal wird einzeln geloggt und in <id>.info.lastError vermerkt.

Bekannte Einschränkungen / bewusste Entscheidungen

  • Smartbutton-Webhook-Programmierung (zapi/smartbt/prgm/prgn/prgs) ist nicht implementiert: dabei ruft der Taster bei Tastendruck direkt eine URL auf ioBroker auf (echtes Push, ganz ohne Polling). Das würde einen eingehenden HTTP-Server im Adapter voraussetzen, den es aktuell nicht gibt - eine grössere Architekturerweiterung, kein kleiner Zusatz. Bleibt als möglicher zukünftiger Ausbauschritt dokumentiert.
  • Schreibzugriff auf zrap/net ist nicht implementiert - WLAN-Zugangsdaten eines Aktors per Skript zu ändern ist riskant (Verbindungsverlust, Reboot nötig). Kann bei Bedarf ergänzt werden.
  • Scheduler (zrap/scheduler) und die zeptrionAir-Smartfront-Services (zapi/smartfront/*, zapi/smartbt/*) sind nicht implementiert, da für den Storen-/Hagel-Use-Case nicht relevant. Die vorhandene zrapGet/zrapPost-Struktur in main.js lässt sich leicht erweitern.
  • chctrl liefert laut Doku HTTP 302 ohne Body - Redirects werden bewusst nicht verfolgt (maxRedirects: 0), um unnötige Zusatzrequests zu vermeiden.
  • Bei wiederholten Fehlern eines Geräts wird das Poll-Intervall bis maximal das 5-fache verlängert (einfacher Backoff).

Entwicklung / Tests

npm install
npm run lint
npm test              # Package-Konsistenz + Unit-Tests
npm run test:integration   # startet echten js-controller (dauert länger)

Changelog

0.7.0 (2026-07-10)

  • Skalierung für 20+ Geräte: paralleles Setup, Poll-Jitter, Duplikat-Erkennung
  • Strikte Startup-Validierung jeder konfigurierten Geräte-Zeile
  • CSV-Massenimport (eigener Konfig-Tab) mit Zeilen-Validierung und Auto-ID
  • FIX: Positionsschätzung nach Stopp während Endlagenfahrt korrekt
  • FIX: Adapter-Timer-Cleanup (this.clearTimeout), führende Nullen in chdes-Codes bleiben erhalten

0.6.0 (2026-07-10)

  • Auto-ID aus Host, Geräte-Test-Button (Erreichbarkeit + zeptrion-Verifikation + Kanalzahl-Prüfung)
  • Kanal-Objektnamen aus dem Gerät (chdes), neues Icon, Geräte-Icons

0.5.1 (2026-07-10)

  • KRITISCHER FIX: XML-Parser übersprang die Nutzdaten wegen des XML-Deklarations-Keys - alle GET-Werte blieben in 0.5.0 null

0.5.0 (2026-07-07)

  • setPosition: zeitbasierte %-Anfahrt für Storen (Chunking wegen 32s-API-Limit, Referenzfahrt bei unbekannter Position)
  • tiltOpen/tiltClose: Lamellen-Kipp-Impulse (konfigurierbare Impulsdauer)
  • calibrate: Positionsschätzung ohne Fahrt setzen

0.4.0 (2026-07-07) - Security- & Qualitäts-Härtung

  • Verriegelter Werksreset: system.factoryDefault funktioniert nur noch innerhalb von 30s nach Setzen von system.unlock - ein einzelner versehentlicher setState aus Script/VIS kann das Gerät nicht mehr plätten.
  • Crashsicheres onStateChange: der komplette Handler (inkl. der Sammelbefehle) läuft jetzt in einer zentralen Fehlerbehandlung - keine Unhandled Promise Rejections mehr möglich.
  • Eingabevalidierung: Kanalbeschreibung (32/32/24/4/4 Bytes UTF-8), Standort (32), NTP-URL (32) und NTP-Intervall (0-255) werden vor dem Senden geprüft; klare Fehlermeldung statt HTTP-400 vom Gerät. Umlaute zählen korrekt als 2 Bytes.
  • Adapter-verwaltete Timer (this.setTimeout) überall - automatische Aufräumung beim Unload gemäss ioBroker-Guidelines.
  • Verbindungs-Ökonomie: solange der chnotify-Long-Poll gesund läuft, wird der redundante chscan-Resync nur noch bei jedem 5. Poll ausgeführt (schont die schwachen Embedded-Webserver der Unterputzaktoren).
  • chnotify abschaltbar (Experten-Tab) für Umgebungen mit Verbindungsproblemen.
  • Admin-UI neu: Tabs (Geräte/Experten), durchgängig EN+DE, Eingabe-Validatoren (ID-Muster, Host-Muster), Tooltips an jeder Spalte, Sicherheitshinweis.
  • ESLint auf Flat Config (v9) migriert, Lint läuft sauber durch; Smoke-Tests für Kommando-Validierung, Byte-Limits, Positionsmathematik und Multicast-Body.

0.3.0 (2026-07-07)

  • Kanalbefehle desselben Geräts werden innerhalb eines 50ms-Fensters automatisch zu einem einzigen Multicast-POST an /zrap/chctrl gebündelt statt sequentiell einzeln gesendet - insbesondere control.closeAllShutters (Hagelalarm) profitiert davon massiv (ein Request pro Gerät statt einer pro Kanal).
  • Optionale zeitbasierte Storen-Positionsschätzung (posEstimate) anhand konfigurierbarer Motor-Laufzeit, da die Hardware selbst keine Position zurückmeldet.
  • Optionale Smartfront-Unterstützung (zapi/smartfront/*): Temperatur/Helligkeit/ Feuchtigkeit auslesen, LED-Hintergrundfarbe setzen.
  • Rollen-Korrektur: level.blind sitzt jetzt auf der Positionsschätzung statt auf dem rohen (meist -1) Hardwarewert.

0.2.0 (2026-07-07)

  • Kanalzustände werden jetzt primär über zrap/chnotify (Long-Poll) nahezu in Echtzeit aktualisiert statt nur per Intervall-Polling; chscan-Poll bleibt als periodischer Resync/Fallback erhalten.
  • Zusätzliches Sicherheitsnetz (Busy-Window, 5s) verhindert, dass ein zeitgleicher chscan-Resync einen gerade gesendeten Bewegungsbefehl mit einem veralteten Wert überschreibt.
  • mDNS-Discovery-Handler gegen Exceptions durch fremde/kaputte Netzwerkpakete abgesichert (try/catch je Service-Event statt nur um die Subscription herum).
  • Neues Geräte-Feld "Art" (Storen/Licht/unbekannt) steuert Standard-Objektrollen (level.blind, button.stop, button.open.blind, button.close.blind bzw. level.dimmer) für bessere VIS-/Smart-Home-Integration.
  • Strukturierte native-Metadaten (Host, Kanalnummer, Art) an Geräte-/Kanal-Objekten.

0.1.0 (2026-07-07)

  • Erste Version: Kanalsteuerung, Kanalzustand/-beschreibung, Geräte-/Netzwerkinfo, Systembefehle, Standort/NTP/Datum, Sammelbefehle für Hagelalarm, mDNS-Discovery.

License

MIT License

Copyright (c) 2026 Stefan Bühler

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.