Werklio
☰

Integrationen

Shelly direkt einrichten

Ein natives Shelly-Skript sendet Heartbeat, Firmware, Uptime und vorhandene DevicePower-Batteriewerte direkt per HTTPS an Werklio.

Voraussetzungen

  • Ein Shelly Gen2+ mit Skriptunterstützung, zum Beispiel Plus, Pro, Gen3 oder Gen4
  • Aktuelle stabile Shelly-Firmware und Internetzugang
  • Eine eigene Werklio-Shelly-Integration mit aktivem API-Key pro Gerät

Schritt für Schritt

  1. Lege für das Shelly-Gerät in Werklio eine Shelly-Integration an. Der danach angezeigte Einrichtungscode enthält den integrationsbezogenen API-Key bereits.
  2. Öffne die lokale Weboberfläche des Shelly und wähle Scripts → Create script.
  3. Vergib als Script name zum Beispiel Werklio, füge den vollständigen Code unverändert in den Editor ein und speichere ihn.
  4. Starte das Skript. In der Konsole erscheint nach etwa fünf Sekunden Werklio: Healthcheck angenommen (HTTP 202).
  5. Aktiviere in der Skriptübersicht Run on startup, damit die Überwachung nach jedem Geräteneustart automatisch weiterläuft.
  6. Das Skript übernimmt einen vorhandenen devicepower-Batteriestand automatisch. Tiefschlafende Batteriegeräte ohne dauerhaft laufendes Skript bindest du über Home Assistant oder ioBroker an.
  7. Öffne in Werklio den Standort. Firmware, Uptime, Gerätezustand, Netzwerkverbindung und gegebenenfalls Batterie erscheinen spätestens nach einer Minute.
  8. Verwende denselben Key nicht auf mehreren Geräten: Nur mit einer Integration pro Shelly kann Werklio einen einzelnen Ausfall zuverlässig erkennen.

Beispielkonfiguration

// Werklio Healthcheck für Shelly Gen2+ (Plus, Pro, Gen3 und Gen4)
// Das Skript sendet ausschließlich technische Zustände, keine Schalt- oder Verbrauchswerte.
let WERKLIO = {
  url: "https://app.werkl.io/api/v1/ingest/shelly/direct",
  apiKey: "wk_live_DEIN_EINMALIGER_KEY",
  intervalMs: 60000,
  retryMs: 15000
};

let requestRunning = false;
let retryTimer = null;

function scheduleRetry() {
  if (retryTimer !== null) return;
  retryTimer = Timer.set(WERKLIO.retryMs, false, function () {
    retryTimer = null;
    sendHealthcheck();
  });
}

function collectErrors(status) {
  let errors = [];
  if (!status) return errors;
  let keys = Object.keys(status);
  for (let i = 0; i < keys.length && errors.length < 20; i++) {
    let key = keys[i];
    let component = status[key];
    if (!component || !component.errors || !component.errors.length) continue;
    for (let j = 0; j < component.errors.length && errors.length < 20; j++) {
      errors.push(key + ":" + component.errors[j]);
    }
  }
  return errors;
}

function collectBatteryPercent(status) {
  if (!status) return null;
  let keys = Object.keys(status);
  for (let i = 0; i < keys.length; i++) {
    if (keys[i].indexOf("devicepower:") !== 0) continue;
    let component = status[keys[i]];
    let percent = component && component.battery ? component.battery.percent : null;
    if (typeof percent === "number" && percent >= 0 && percent <= 100) return Math.round(percent);
  }
  return null;
}

function handleResponse(result, errorCode, errorMessage) {
  requestRunning = false;
  if (errorCode !== 0) {
    console.log("Werklio: Übertragung fehlgeschlagen (RPC " + errorCode + "): " + errorMessage);
    scheduleRetry();
    return;
  }

  let httpCode = result && result.code ? result.code : 0;
  if (httpCode >= 200 && httpCode < 300) {
    console.log("Werklio: Healthcheck angenommen (HTTP " + httpCode + ")");
    return;
  }

  console.log("Werklio: Serverantwort HTTP " + httpCode);
  if (httpCode === 0 || httpCode === 408 || httpCode === 429 || httpCode >= 500) scheduleRetry();
}

function postStatus(status) {
  let info = Shelly.getDeviceInfo();
  let sys = status && status.sys ? status.sys : Shelly.getComponentStatus("sys");
  let wifi = status && status.wifi ? status.wifi : Shelly.getComponentStatus("wifi");
  let sysConfig = Shelly.getComponentConfig("sys");
  let updateVersion = null;
  let deviceName = null;

  if (sys && sys.available_updates && sys.available_updates.stable) {
    updateVersion = sys.available_updates.stable.version || null;
  }
  if (sysConfig && sysConfig.device && sysConfig.device.name) {
    deviceName = sysConfig.device.name;
  }

  let payload = {
    deviceName: deviceName,
    model: info.model || info.app || "Shelly",
    generation: info.gen || 2,
    version: info.ver || info.fw_id || null,
    uptimeSeconds: sys && typeof sys.uptime === "number" ? Math.floor(sys.uptime) : Math.floor(Shelly.getUptimeMs() / 1000),
    wifiRssi: wifi && wifi.status === "got ip" && typeof wifi.rssi === "number" ? Math.round(wifi.rssi) : null,
    batteryPercent: collectBatteryPercent(status),
    restartRequired: sys && sys.restart_required === true,
    updateVersion: updateVersion,
    errors: collectErrors(status)
  };

  Shelly.call("HTTP.Request", {
    method: "POST",
    url: WERKLIO.url,
    headers: {
      "Content-Type": "application/json",
      "X-Werklio-Key": WERKLIO.apiKey
    },
    body: JSON.stringify(payload),
    timeout: 15
  }, handleResponse);
}

function sendHealthcheck() {
  if (requestRunning) return;
  requestRunning = true;
  Shelly.call("Shelly.GetStatus", {}, function (status, errorCode, errorMessage) {
    if (errorCode !== 0) {
      requestRunning = false;
      console.log("Werklio: Gerätestatus nicht lesbar (RPC " + errorCode + "): " + errorMessage);
      scheduleRetry();
      return;
    }
    postStatus(status);
  });
}

console.log("Werklio: Skript gestartet; erster Healthcheck in 5 Sekunden");
Timer.set(5000, false, sendHealthcheck);
Timer.set(WERKLIO.intervalMs, true, sendHealthcheck);

Testschritt

Skript speichern und starten. In der Shelly-Konsole auf HTTP 202 achten und anschließend unter Werklio → Standort → Integrationen die Verbindung testen.

Erwartetes Ergebnis

Werklio zeigt einen aktuellen Shelly-Heartbeat. Unter Geräte & Entitäten erscheinen Gerät, Netzwerk und Firmware; ein vorhandener DevicePower-Wert erscheint zusätzlich im Batterie-Tab.

Übertragene Gesundheitsdaten

Shelly-SignalWerklio
Firmware-Version und verfügbare stabile VersionHeartbeat und Firmwarezustand
Sekunden seit BootHeartbeat · Uptime
Komponentenfehler und NeustartbedarfGerät · online/warning
WLAN-Signalstärke, ohne SSID oder IPNetzwerk · online/warning ab −80 dBm
DevicePower-Batteriestand, falls vorhandenBatterie · automatische Prozentüberwachung

Fehlerbehebung

  • HTTP 401: Der Skript-Key gehört nicht zu dieser Shelly-Integration oder wurde widerrufen. In Werklio einen Ersatz-Key erzeugen und das gesamte neu generierte Skript einsetzen.
  • HTTP 400: Das Skript wurde verändert oder ist unvollständig. Den aktuellen Einrichtungscode erneut vollständig kopieren.
  • RPC- oder Netzwerkfehler: DNS, Gateway, Internetzugang und Systemzeit des Shelly prüfen. Die Zertifikatsprüfung nicht deaktivieren.
  • Kein automatischer Start: In der Skriptübersicht Run on startup aktivieren.
  • Keine Firmwarewarnung trotz verfügbarer Version: Die Shelly-Firmwareprüfung einmal in der Geräteoberfläche öffnen; verfügbare Updates werden vom Systemstatus bereitgestellt.
  • Gen1-Gerät ohne Scripts-Menü: Das native Skript kann auf diesem Gerät nicht ausgeführt werden; ein Gen2+-Gerät oder eine bestehende Home-Assistant-/ioBroker-Anbindung ist erforderlich.

Sicherheitshinweise

  • Der Werklio-Key liegt im Shelly-Skript. Bei Export, Weitergabe oder Screenshot der Gerätekonfiguration den Key in Werklio rotieren.
  • Das Skript sendet weder MAC-/IP-Adresse und WLAN-Name noch Schaltzustände, Eingänge, Leistung oder Energieverbrauch.
  • HTTPS-Zertifikatsprüfung bleibt aktiv; keine ssl_ca-Ausnahme und keine Portfreigabe zum Shelly einrichten.
  • Ein technisch neutraler Gerätename verhindert, dass Raum- oder Personennamen als Healthcheck-Anzeige übertragen werden.