{"id":341,"date":"2026-03-31T21:48:09","date_gmt":"2026-03-31T19:48:09","guid":{"rendered":"https:\/\/www.md-technologie.de\/baublog\/?p=341"},"modified":"2026-03-31T21:52:03","modified_gmt":"2026-03-31T19:52:03","slug":"shelly-em-mini-gen4-stromverbrauch-ermitteln-mit-iobroker","status":"publish","type":"post","link":"https:\/\/www.md-technologie.de\/baublog\/shelly-em-mini-gen4-stromverbrauch-ermitteln-mit-iobroker\/","title":{"rendered":"Shelly EM Mini Gen4 Stromverbrauch ermitteln mit ioBroker"},"content":{"rendered":"\n<p>Wie schon in meinem Artikel <a href=\"https:\/\/www.md-technologie.de\/baublog\/shelly-plug-s-stromverbrauch-ermittlen-mit-iobroker\/\">https:\/\/www.md-technologie.de\/baublog\/shelly-plug-s-stromverbrauch-ermittlen-mit-iobroker\/<\/a> beschrieben kann man via Skript den Verbrauch berechnen lassen. Allerdings ist dieses Skript bereits etwas \u00e4lter und kann nicht die Werte des aktuellen Shelly EM Mini Gen4 auslesen, da die Energiewerte dort auf einer anderen Objektpunkt liegen. <\/p>\n\n\n\n<p>In den \u00e4lteren Shelly Generationen lie\u00dft man den aktuellen Verbrauch \u00fcber den Punkt shelly.0.SHSW-25#1111111111#1.Relay1.Energy aus.<\/p>\n\n\n\n<p>Die neuen Shellys k\u00f6nnen aber nicht nur den Strom messen sondern zeigen auch an ob es sich um Verbrauch oder Einspeisung z.B. von einer Balkon PV wie bei mir handelt. Dazu nutzen die Shellys die Werte <br>shelly.0.shellyemminig4#1111111111#1.EM1Data0.TotalActiveEnergy<br>und<br>shelly.0.shellyemminig4#1111111111#1.EM1Data0.TotalActiveReturnEnergy<\/p>\n\n\n\n<p>Um das Skript fit f\u00fcr die neue Generation zu machen habe ich die KI mit ChatGPT und Claude Opus dar\u00fcber gr\u00fcbeln lassen und das Skript von Stephan Keyenborg \u00fcberarbeitet (<a href=\"https:\/\/www.kreyenborg.koeln\/shelly-verbrauchs-historie-fuer-tag-woche-monat-jahr\/\">https:\/\/www.kreyenborg.koeln\/shelly-verbrauchs-historie-fuer-tag-woche-monat-jahr\/<\/a>). Den neuen Code habe ich grob validiert und erfolgreich getestet:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-black-color has-text-color has-link-color wp-elements-2304f0c0a763afdc22c55a056ae5d65a\">\/*<br> * @copyright 2021 Stephan Kreyenborg &lt;stephan@kreyenborg.koeln&gt;<br> *<br> * @author 2021 Stephan Kreyenborg &lt;stephan@kreyenborg.koeln&gt;<br> *<br> * Dieses Skript dient zur freien Verwendung in ioBroker zur Verbrauchserfassung der Shelly Ger\u00e4te.<br> * Jegliche Verantwortung liegt beim Benutzer. Das Skript wurde unter Ber\u00fccksichtigung der bestm\u00f6glichen Nutzung<br> * und Performance entwickelt.<br> * Der Entwickler versichert, das keine b\u00f6swilligen Systemeingriffe im originalen Skript vorhanden sind.<br> *<br> * Sollte das Skript wider Erwarten nicht korrekt funktionieren, so hast Du jederzeit die M\u00f6glichkeit, Dich auf<br> * https:\/\/www.kreyenborg.koeln<br> * f\u00fcr Unterst\u00fctzung zu melden. Jedes Skript besitzt seine eigene Kommentarseite, auf der,<br> * nach zeitlicher M\u00f6glichkeit des Autors, Hilfe angeboten wird. Ein Anrecht hierauf besteht nicht!<br> * <br> * Anspr\u00fcche gegen\u00fcber Dritten bestehen nicht. <br> * <br> * Skript Name:        Shelly-Verbrauch<br> * Skript Version:    1.60<br> * Erstell-Datum:    08. Oktober 2021 | Update: 21. April 2022<br> *<br> * \u00dcberarbeitet von Michael Schumann (https:\/\/www.md-technologie.de\/baublog\/)<br> * Skript Version:    1.70<br> * Letzte \u00c4nderung:   31. M\u00e4rz 2026<br> *<br> * Shelly Verbrauch - robust f\u00fcr Gen2 \/ Gen3 \/ Gen4<br> * verarbeitet auflaufende Energiezaehler in Wh<br> *\/<br><br>\/\/ Datenpunkte neu erstellen<br>var ueberschreiben = false;<br><br>var DEBUG = false; \/\/ auf false setzen wenn alles l\u00e4uft<br><br>\/\/ Hauptdatenpunkt unterhalb javascript<br>var datenpunkt = \"ShellyVerbrauch.\";<br>var javascript_instanz = \"javascript.0.\";<br><br>\/\/ Shelly-Adapter Basis<br>var shelly_dp = \"shelly.0\";<br><br>\/\/ Verbrauchs-Objekte mit Beschreibung<br>var felder = [<br>    { key: \"gesamt\",         desc: \"Gesamter Verbrauch des Shelly\", init: false },<br>    { key: \"dieses_jahr\",    desc: \"Verbrauch aktuelles Jahr\",      init: false },<br>    { key: \"letztes_jahr\",   desc: \"Verbrauch letztes Jahr\",        init: false },<br>    { key: \"letzter_monat\",  desc: \"Verbrauch letzten Monat\",       init: false },<br>    { key: \"dieser_monat\",   desc: \"Verbrauch aktueller Monat\",     init: false },<br>    { key: \"letzte_woche\",   desc: \"Verbrauch letzte Woche\",        init: false },<br>    { key: \"diese_woche\",    desc: \"Verbrauch diese Woche\",         init: false },<br>    { key: \"gestern\",        desc: \"Verbrauch gestern\",             init: false },<br>    { key: \"heute\",          desc: \"Verbrauch heute\",               init: false },<br>    { key: \"alter_wert\",     desc: \"Messwert alt\",                  init: true  },<br>    { key: \"aktueller_wert\", desc: \"Messwert neu\",                  init: true  }<br>];<br><br>\/\/ Shelly-Namen<br>var shellyDpsName = $('state[id=' + shelly_dp + '.*.name]');<br><br>\/\/ Relevante Energie-State-Endungen<br>var energySuffixes = [<br>    { suffix: \".Energy\", extended: false, label: \"Energy\" },<br>    { suffix: \".Total\", extended: false, label: \"Total\" },<br>    { suffix: \".Total_Returned\", extended: true, label: \"Total_Returned\" },<br>    { suffix: \".TotalActiveEnergy\", extended: false, label: \"TotalActiveEnergy\" },<br>    { suffix: \".TotalActiveReturnEnergy\", extended: true, label: \"TotalActiveReturnEnergy\" }<br>];<br><br>\/\/ --------------------------------------------------<br>\/\/ Hilfsfunktionen<br>\/\/ --------------------------------------------------<br><br>function endsWithExact(str, suffix) {<br>    return str.slice(-suffix.length) === suffix;<br>}<br><br>function getAllEnergyStates() {<br>    var result = [];<br><br>    \/\/ gezielte Abfrage pro Suffix statt alle States durchlaufen<br>    for (var x = 0; x &lt; energySuffixes.length; x++) {<br>        var entry = energySuffixes[x];<br>        $('state[id=' + shelly_dp + '.*' + entry.suffix + ']').each(function (id) {<br>            if (endsWithExact(id, entry.suffix)) {<br>                result.push({<br>                    id: id,<br>                    extended: entry.extended,<br>                    label: entry.label<br>                });<br>            }<br>        });<br>    }<br><br>    return result;<br>}<br><br>function safeNumber(val, fallback) {<br>    var n = parseFloat(val);<br>    return isNaN(n) ? fallback : n;<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Zeitbasierte Verschiebungen<br>\/\/ --------------------------------------------------<br><br>function shelly_verbrauch_tag() {<br>    shelly_verbrauch_update();<br><br>    var heute = new Date();<br><br>    verschiebe_verbrauch_objekt(\"heute\", \"gestern\");<br>    log(\"Shelly Verbrauch: Werte fuer gestern und heute aktualisiert!\");<br><br>    if (heute.getDay() === 1) {<br>        verschiebe_verbrauch_objekt(\"diese_woche\", \"letzte_woche\");<br>        log(\"Shelly Verbrauch: Werte fuer diese und letzte Woche aktualisiert!\");<br>    }<br><br>    if (heute.getDate() === 1) {<br>        verschiebe_verbrauch_objekt(\"dieser_monat\", \"letzter_monat\");<br>        log(\"Shelly Verbrauch: Werte fuer diesen und letzten Monat aktualisiert!\");<br>    }<br><br>    if (heute.getDate() === 1 &amp;&amp; heute.getMonth() === 0) {<br>        verschiebe_verbrauch_objekt(\"dieses_jahr\", \"letztes_jahr\");<br>        log(\"Shelly Verbrauch: Werte fuer dieses und letztes Jahr aktualisiert!\");<br>    }<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Hauptupdate<br>\/\/ --------------------------------------------------<br><br>function shelly_verbrauch_update() {<br>    var anzahl_updates = 0;<br>    var anzahl_reboots = 0;<br>    var anzahl_gleich = 0;<br>    var anzahl_verarbeitet = 0;<br>    var anzahl_gefunden = 0;<br>    var anzahl_ohne_objekt = 0;<br><br>    var states = getAllEnergyStates();<br>    anzahl_gefunden = states.length;<br><br>    states.forEach(function (entry) {<br>        var id = entry.id;<br>        var shelly_verbrauch = getState(id).val;<br><br>        if (DEBUG) {<br>            log(\"DEBUG: Shellys gefundener State -&gt; \" + id + \" | Wert: \" + shelly_verbrauch);<br>        }        <br><br>        if (shelly_verbrauch === null || shelly_verbrauch === undefined) return;<br><br>        shelly_verbrauch = safeNumber(shelly_verbrauch, NaN);<br>        if (isNaN(shelly_verbrauch)) return;<br><br>        var basis_dp = shelly_DP(id, entry.extended);<br><br>        if (!existsState(basis_dp + \"aktueller_wert\")) {<br>            anzahl_ohne_objekt++;<br>            if (DEBUG) {<br>                log(\"DEBUG: Shellys Ziel-State fehlt -&gt; \" + basis_dp + \"aktueller_wert\");<br>            }<br>            return;<br>        }<br><br>        var aktueller_wert = 0;<br>        var aktueller_state = getState(basis_dp + \"aktueller_wert\");<br>        if (aktueller_state &amp;&amp; aktueller_state.val !== null &amp;&amp; aktueller_state.val !== undefined) {<br>            aktueller_wert = safeNumber(aktueller_state.val, 0);<br>        }<br><br>        var alter_wert = 0;<br><br>        if (shelly_verbrauch &gt; aktueller_wert) {<br>            setState(basis_dp + \"alter_wert\", aktueller_wert, true);<br>            alter_wert = aktueller_wert;<br>            anzahl_updates++;<br>        } else if (aktueller_wert &gt; shelly_verbrauch) {<br>            setState(basis_dp + \"alter_wert\", 0, true);<br>            alter_wert = 0;<br>            anzahl_reboots++;<br>        } else {<br>            alter_wert = aktueller_wert;<br>            anzahl_gleich++;<br>        }<br><br>        setState(basis_dp + \"aktueller_wert\", shelly_verbrauch, true);<br><br>        var verbrauch = shelly_verbrauch - alter_wert;<br>        if (verbrauch &lt; 0) verbrauch = 0;<br><br>        aktualisiere_verbrauch_objekt(basis_dp, \"heute\", verbrauch);<br>        aktualisiere_verbrauch_objekt(basis_dp, \"diese_woche\", verbrauch);<br>        aktualisiere_verbrauch_objekt(basis_dp, \"dieser_monat\", verbrauch);<br>        aktualisiere_verbrauch_objekt(basis_dp, \"dieses_jahr\", verbrauch);<br>        aktualisiere_verbrauch_objekt(basis_dp, \"gesamt\", verbrauch);<br><br>        anzahl_verarbeitet++;<br>    });<br><br>    aktualisiere_namen();<br><br>    log(<br>        \"Shelly Verbrauch: gefunden=\" + anzahl_gefunden +<br>        \" | verarbeitet=\" + anzahl_verarbeitet +<br>        \" | ohne_objekt=\" + anzahl_ohne_objekt +<br>        \" | updates=\" + anzahl_updates +<br>        \" | resets\/reboots=\" + anzahl_reboots +<br>        \" | unveraendert=\" + anzahl_gleich<br>    );<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Verbrauch addieren<br>\/\/ --------------------------------------------------<br><br>function aktualisiere_verbrauch_objekt(dp, objektname, wert) {<br>    var state = getState(dp + objektname);<br>    var alter_verbrauch = (state &amp;&amp; state.val !== null &amp;&amp; state.val !== undefined) ? parseFloat(state.val) : 0;<br><br>    if (isNaN(alter_verbrauch)) alter_verbrauch = 0;<br>    if (isNaN(wert)) wert = 0;<br><br>    var verbrauch = alter_verbrauch + wert;<br>    setState(dp + objektname, Math.round(verbrauch * 100) \/ 100, true);<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Verschieben<br>\/\/ --------------------------------------------------<br><br>function verschiebe_verbrauch_objekt(von, nach) {<br>    $('state[id=*.' + datenpunkt + '*.*.' + von + ']').each(function (id, i) {<br>        var tmp_dp = id.slice(0, -(von.length));<br>        var verbrauch = getState(id).val;<br><br>        if (verbrauch !== null &amp;&amp; verbrauch !== undefined) {<br>            setState(tmp_dp + nach, verbrauch, true);<br>        }<br><br>        setState(id, 0, true);<br>    });<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Namen aktualisieren<br>\/\/ --------------------------------------------------<br><br>function aktualisiere_namen() {<br>    if (typeof extendObject === \"function\") {<br>        shellyDpsName.each(function (id, i) {<br>            if (existsState(id)) {<br>                var name = String(getState(id).val);<br>                setState(shelly_DP_Name(id), name, true);<br><br>                extendObject(shelly_DP_Name_Main(id), {<br>                    common: {<br>                        name: name,<br>                        desc: name<br>                    },<br>                    type: \"channel\"<br>                });<br>            }<br>        });<br>    }<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Datenpunkte erstellen<br>\/\/ --------------------------------------------------<br><br>function datenpunkte_erstellen() {<br>    var anzahl_gesamt = 0;<br>    var bereits_erstellt = {};<br><br>    var states = getAllEnergyStates();<br><br>    states.forEach(function (entry) {<br>        var id = entry.id;<br>        var basis_dp = shelly_DP(id, entry.extended);<br><br>        if (bereits_erstellt[basis_dp]) return;<br>        bereits_erstellt[basis_dp] = true;<br><br>        var initial_wert = safeNumber(getState(id).val, 0.0);<br><br>        for (var i = 0; i &lt; felder.length; i++) {<br>            var startwert = felder[i].init ? initial_wert : 0.0;<br><br>            createState(basis_dp + felder[i].key, startwert, ueberschreiben, {<br>                name: felder[i].desc,<br>                desc: felder[i].desc,<br>                type: \"number\",<br>                role: \"value.power\",<br>                unit: \"Wh\"<br>            });<br>        }<br><br>        anzahl_gesamt++;<br>    });<br><br>    shellyDpsName.each(function (id, j) {<br>        createState(shelly_DP_Name(id), \"\", ueberschreiben, {<br>            name: \"Name des Shelly\",<br>            desc: \"Name des Shelly\",<br>            type: \"string\",<br>            role: \"value\",<br>            unit: \"\"<br>        });<br>    });<br><br>    log(\"Shelly Verbrauch: Datenpunkte erstellt! Anzahl Energie-Datenpunkte: \" + anzahl_gesamt);<br><br>    setTimeout(shelly_verbrauch_update, 30000);<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Pfadbildung<br>\/\/ --------------------------------------------------<br><br>function shelly_DP(dp, extended) {<br>    if (extended === undefined) extended = false;<br><br>    dp = dp.split(\".\");<br><br>    if (dp.length &lt; 5) {<br>        return javascript_instanz + datenpunkt + \"unbekannt.unbekannt.\";<br>    }<br><br>    var basis = javascript_instanz + datenpunkt + dp[2] + \".\" + dp[3];<br><br>    if (extended) {<br>        basis += \"_Returned.\";<br>    } else {<br>        basis += \".\";<br>    }<br><br>    return basis;<br>}<br><br>function shelly_DP_Name(dp) {<br>    dp = dp.split(\".\");<br>    if (dp.length &lt; 4) return javascript_instanz + datenpunkt + \"unbekannt.name\";<br>    return javascript_instanz + datenpunkt + dp[2] + \".name\";<br>}<br><br>function shelly_DP_Name_Main(dp) {<br>    dp = dp.split(\".\");<br>    if (dp.length &lt; 3) return javascript_instanz + datenpunkt + \"unbekannt\";<br>    return javascript_instanz + datenpunkt + dp[2];<br>}<br><br>\/\/ --------------------------------------------------<br>\/\/ Initialisierung<br>\/\/ --------------------------------------------------<br><br>function shelly_verbrauch_erster_start() {<br>    log(\"Shelly Verbrauch: Erster Start des Skriptes! Datenpunkte werden erstellt!\");<br>    datenpunkte_erstellen();<br>}<br><br>shelly_verbrauch_erster_start();<br><br>schedule('*\/15 * * * *', shelly_verbrauch_update);<br>schedule('0 0 * * *', shelly_verbrauch_tag);<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Wie schon in meinem Artikel https:\/\/www.md-technologie.de\/baublog\/shelly-plug-s-stromverbrauch-ermittlen-mit-iobroker\/ beschrieben kann man via Skript den Verbrauch berechnen lassen. Allerdings ist dieses Skript bereits etwas \u00e4lter und kann nicht die Werte des aktuellen Shelly EM Mini Gen4 auslesen, da die Energiewerte dort auf einer anderen Objektpunkt liegen. In den \u00e4lteren Shelly Generationen lie\u00dft man den aktuellen Verbrauch \u00fcber den [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69],"tags":[70,72],"class_list":["post-341","post","type-post","status-publish","format-standard","hentry","category-smart-home","tag-iobroker","tag-shelly"],"views":69,"_links":{"self":[{"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/posts\/341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/comments?post=341"}],"version-history":[{"count":5,"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/posts\/341\/revisions"}],"predecessor-version":[{"id":346,"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/posts\/341\/revisions\/346"}],"wp:attachment":[{"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/media?parent=341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/categories?post=341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.md-technologie.de\/baublog\/wp-json\/wp\/v2\/tags?post=341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}