Deye (bzw. allgemein ESPHome) Anbindung im iobroker (mit Steuerungsmöglichkeit)

Servus miteinander,

ich hab vor kurzem unseren Deye 12k installieren lassen und wollte diesen natürlich in unser SmartHome (iobroker) einbinden. Readonly war das Ganze auch keinerlei Problem.

Einfach einen ESP32 mit Modbus-Adapter auf Lochraster gelötet, ein kleines Display dazu, das Ganze in ein Hutschienen-Leergehäuse gepackt, verdrahtet, ESPHome drauf und fertig. Easy going :slight_smile:

Nur der Schreib-Anteil (WR Konfiguration aus dem iobroker heraus anpassen) war nicht ganz trivial - hier ist die Einbindung von MQTT bzw. ESPHome in iobroker noch nicht so ganz toll.

Den ESPHome Adapter in iobroker wollte ich nicht verwenden, da dieser noch nicht "stable" ist und anscheinend auch nicht mehr aktiv maintained wird. Deswegen - plain MQTT.

ESPHome hat die kleine Eigenheit, dass gelesene Werte unter topic_name/state landen. Will man einen Wert beschreiben, muss man topic_name/command ansprechen & befüllen.

Direkt aus der Visualisierung aus IOBroker heraus ist das Ganze so leider nicht kompatibel - deswegen musste ich mir mit einem kleinen Script weiterhelfen. Selbiges tut genau das - alle relevanten /state topics mittels standard-iobroker-Funktionen auslesen, den wert aus /state in /command schreiben mittels sendTo('mqtt... und somit die Grundlage für die Verwendung in der Visualisierung zu legen.

Vielleicht kanns ja noch jemand brauchen - deswegen hier das iobroker Script.

Gruezie
Domi

/* 
Copyright © 2025 DaDomi / ScrewThisBanana

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.

*
* Author: ScrewThisBanana
*
*  This script for IO Broker is a simple solution to enable iobroker setting configuration entries in a deye inverter
*  connected via ESPHome + Modbus Adapter
*
*  Prerequisites:
*   Working MQTT Server (e. g. Mosquitto)
*   Connected ESPHome Device (via MQTT)
*   Working MQTT Client in IOBroker
*
*  Description:
*   This script reads all ".state" entries from the mqtt adapters states
*   Foreach found ".state", a new ".command" state is sent to mqtt (containing the current value from ".state" to
*   prevent overwriting things in the inverter). This ".command" state now enables other adapters writing values
*   to ESPHome
*/

schedule('*/60 * * * *', run);

function run(){
    $("mqtt.0.deye12.**.state").each(item =>                                                // iterate over all deye state entries
        addCommandId(item)
        .catch(reason => log(
            JSON.stringify(reason))
        )
    );
};

async function addCommandId(stateId: string){
    let itemId = stateId.substring(0, stateId.length - ".state".length);                    // remove .state
    let commandId = itemId+".command";                                                      // add .command
    if($(commandId).length == 0){                                                           // create "command" topic if it does not yet exist
        let state = await $(stateId).getStateAsync();

        if(!commandId.includes(".homeassistant.") 
           && (commandId.includes('.number.') || commandId.includes(".select."))){          // create command for numbers & selects - other datapoints are readonly
            let topic = commandId.substring("mqtt.0.".length).replaceAll(".", "/");         // topic = my/topic, not mqtt.0.my.topic
            log(topic);
            sendTo('mqtt.0', 'sendMessage2Client', {topic: topic, message: state.val});
        }
    }
}
2 „Gefällt mir“

Das ist im Allgemeinen so üblich das alle via MQTT angebundenen Gerätschaften Lesedaten in irgendwas/state und Schreibdaten über irgendwas/command ablegen bzw. erwarten.

Welche Visu verwendest du denn?

Wie ist dein MQTT Adapter konfiguriert, als Client oder als Broker?

Ich gehe davon aus, dass ein Script nicht nötig ist wenn man mit den Alias(en) arbeitet. Die Aliase bilden dabei sozusagen die brigde zwischen den MQTT und der Visu. Innerhalb der Aliase sind dann auch Inline-Konvertierungen möglich was die Sache dann an sich recht übersichtlich lässt.

Der MQTT Adapter ist Client (Adapterlink) ggü mosquitto. Die Visualisierung ist Jarvis.

Das Ursprungsproblem ist, dass im IOBroker die /command topics natürlich nicht by default in den Objekten angelegt werden (wäre ja auch Blödsinn) sondern erst nach erstmaligem Beschreiben mittels sendTo('mqtt.0... {topic: .../command}.

Der MQTT Adapter bietet die Konfigurationsmöglichkeit, dass man Read & Write über unterschiedliche topics durchführen kann - nur leider eben nicht topic/command sondern topic/state/set - natürlich nicht konfigurierbar - guckst du hier - "Use different topic names for set and get".

topic/state/set bewirkt in ESPHome aber gar nix - deswegen oben der Workaround mittels script - dieses legt einem einfach nur die notwendigen "schreib"-States an und fertig.

Ob ein Alias da weiterhilft würde ich fast bezweifeln - kann man Aliasse für States vergeben die noch nicht existieren?

Prinzipiell ja, aber die müllen dann das Logfile mit Warnungen voll das der jeweilige Alias noch kein target hat.

Allerdings, warum existieren die States dann noch nicht bzw. was würde es für einen Sinn machen Aliase anzulegen die noch keinen zugeordneten State haben?

Deswegen die Idee mit dem Alias. Den MQTT Adapter lässt du bis auf Benutzer und Passwort weitestgehend unkonfiguriert, abgesehen von der Verbindung die er zum Mosquitto herstellen soll, ansonsten alle Haken raus und dann ab dafür.

Dann legst du als Beispiel einen Alias an indem du konfigurierst, dass es unterschiedliche States für lesen und schreiben geben soll. Damit kannst du dann jeweils das Ziel für den "write" und "read" Zugriff eigens festlegen - also es landet dann nicht automatisch bei topic/state/set sondern dort wo du es selbst festgelegt hast. Und die Vis greift dann auf den Alias zu und nicht mehr direkt auf den MQTT-Adapter. Hat auch den netten Vorteil dass bei einer Änderung z.B. am MQTT Adapter oder der Baumstruktur nur der Alias/die Aliase geändert werden müssen. Nicht all die Stellen wo in der Vis drauf zugegriffen wird.

Dann legst du als Beispiel einen Alias an indem du konfigurierst, dass es unterschiedliche States für lesen und schreiben geben soll. Damit kannst du dann jeweils das Ziel für den "write" und "read" Zugriff eigens festlegen

Und welches Ziel setz ich nun für "write"? Den state mqtt.0.deye12.batterycapacity.command gibts ja nicht ohne das script - genau das ist ja eben der Sinn dabei - einfach den state anlegen damit man ihn beschreiben kann. Ob das Beschreiben dann über den Alias oder direkt erfolgt ist letztendlich wurscht. Wichtig ist, dass es erstmal den State gibt.

Nichtsdestotrotz - das Thema mit dem Alias ist durchaus berechtigt. Macht natürlich Sinn, Datenquelle (mqtt) und Zugriff (vis) zu trennen - tut aber hier nichts zur Sache. Es geht drum wie kriegt ich Daten zurück an den Deye über ESPHome - dafür brauchts nunmal einen Topic in MQTT :wink:

Das erschließt sich mir nicht. Der MQTT Adapter legt doch in der Baumstruktur automatisch alle topics und States an die an ihn published werden bzw. die er abboniert hat. Folglich müsste man ja davon ausgehen dass irgendwas zwischen Mosquitto und MQTT Adapter nicht ganz rund läuft.

Ich wollte jetzt deinen Workaround auch nicht schlecht reden, hoffe das kam nicht falsch rüber. Aber es ist mir neu dass man Scripts benötigt um benötigte Topics zu erstellen - oder ich bin einfach verwöhnt dass sie bei mir immer all die Topics automatisch angelegt werden die vom jeweiligen Publisher publiziert werden da mein MQTT Adapter alles abbonniert...

Nein nein - alles gut :wink: Wir reden nur aneinander vorbei.

Nur die, die auf ihm gepublisht werden. Die, die abonniert werden, werden nicht automatisch angelegt. Soll heißen dafür brauchts nen publish (und damit das script :stuck_out_tongue:).

Oder jemanden, der mal den mqtt-client in iobroker konfigurierbar macht ^^.

Initial (soll heißen nur Abo und KEIN Publish) gibts den Topic weder in MQTT, noch als state im MQTT Adapter.

Okay, alles klar. Ich verwende den MQTT Adapter direkt als Broker ohne vorgeschalteten mosqitto.

Aber kann man an der Stelle nicht den mosqitto dazu veranlassen alle Deye topics an den MQTT Adapter zu publishen? An der Stelle bin ich nicht so bewandert.

Oder einfach mal ein Issue im Adapter Git eröffnen :stuck_out_tongue_winking_eye: