Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Tester
    4. Test Adapter Midea Dimstal Klimaanlagen v0.0.x

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Test Adapter Midea Dimstal Klimaanlagen v0.0.x

    This topic has been deleted. Only users with topic management privileges can see it.
    • BananaJoe
      BananaJoe Most Active last edited by BananaJoe

      @bananajoe sagte in Test Adapter Midea Dimstal Klimaanlagen v0.0.x:

      Ich habe hier mal ein Update zur Steuerung meiner Dimstal-Anlage. Die kann ich mit diesem Adapter (oder über den HAM-Weg) zwar abrufen, aber nicht steuern.
      Und zwar habe ich noch eine andere CLI-gefunden welche erheblich(!) schneller reagiert als die midea-beautiful-air-cli die ich in einem Beitrag weiter oben erwähnt (und modifiziert habe):

      https://pypi.org/project/msmart-ng/

      Ich spiel hier mal den Totengräber für meinen eigenen Beitrag:
      Es gibt eine neuere Version von msmart-ng
      Beim testen habe ich festgestellt das mein Beispielaufruf falsch ist, das -d ist überflüssig bzw. aktiviert nur den Debug-Modus. Der (vor-)letzte Parameter muss immer die IP-Adresse sein, richtig wäre also:

      msmart-ng control --token c19a404c808656a83c...08f19efc0b6a5 --key d714e6c7ad56...ea32d44776474fb --id 534971451351917 -192.168.1.30 power_state=True
      

      Zudem habe ich entdeckt, das die eingebaute Hilfe mehr bietet als gedacht:

      msmart-ng query -h
      

      liefert die ganzen Parameter für die Abfrage:

      usage: msmart-ng query [-h] [-d] [--region {DE,KR,US}] [--account ACCOUNT] [--password PASSWORD] [--capabilities] [--auto] [--id DEVICE_ID] [--token TOKEN] [--key KEY] host
      
      Query information from a device on the local network.
      
      positional arguments:
        host                 Hostname or IP address of device.
      
      options:
        -h, --help           show this help message and exit
        -d, --debug          Enable debug logging.
        --region {DE,KR,US}  Country/region for built-in cloud credential selection.
        --account ACCOUNT    Manually specify a username for cloud authentication.
        --password PASSWORD  Manually specify a password for cloud authentication.
        --capabilities       Query device capabilities instead of state.
        --auto               Automatically authenticate V3 devices.
        --id DEVICE_ID       Device ID for V3 devices.
        --token TOKEN        Authentication token for V3 devices.
        --key KEY            Authentication key for V3 devices.
      

      Dementsprechend liefert

      msmart-ng control -h
      

      die Anleitung zur Steuerung:

      usage: msmart-ng control [-h] [-d] [--region {DE,KR,US}] [--account ACCOUNT] [--password PASSWORD] [--capabilities] [--auto] [--id DEVICE_ID] [--token TOKEN] [--key KEY]
                               host setting=value [setting=value ...]
      
      Control a device on the local network.
      
      positional arguments:
        host                 Hostname or IP address of device.
        setting=value        Space separated key-value pairs of settings to control.
      
      options:
        -h, --help           show this help message and exit
        -d, --debug          Enable debug logging.
        --region {DE,KR,US}  Country/region for built-in cloud credential selection.
        --account ACCOUNT    Manually specify a username for cloud authentication.
        --password PASSWORD  Manually specify a password for cloud authentication.
        --capabilities       Query device capabilities before sending commands.
        --auto               Automatically authenticate V3 devices.
        --id DEVICE_ID       Device ID for V3 devices.
        --token TOKEN        Authentication token for V3 devices.
        --key KEY            Authentication key for V3 devices.
      

      Da ich das ganze aus ioBroker-Skripts heraus startet, habe ich dafür ein eigenes Environment für den Benutzer ioBroker eingerichtet, in der Bash per SSH:
      Zum Benutzer ioBroker wechseln:

      sudo -u iobroker /usr/bin/bash
      

      In das Home-Verzeichnis des Benutzers ioBroker wechseln

      cd ~
      

      Python Environment anlegen (falls noch nicht vorhanden):

      python3 -m venv python-venv
      

      und in die Umgebung wechseln:

      source python-venv/bin/activate
      

      Jetzt kann man per pip das Modul installieren

      pip install msmart-ng
      

      und dann per

      msmart-ng
      

      Nutzen. Vor der Nutzung muss dann aber immer erst das Envirtonment geladen werden.
      Intelligenter weise wird das in den nachinstallierten Python-Modulen gleich richtig hinterlegt:

      which msmart-ng
      

      Ausgabe:

      /home/iobroker/python-venv/bin/msmart-ng
      

      Inhalt:

      cat /home/iobroker/python-venv/bin/msmart-ng
      

      Die erste Zeile ist

      #!/home/iobroker/python-venv/bin/python3
      

      Womit die richtige Umgebung genutzt wird.
      In euren ioBroker Skripten müsst Ihr dann z.B. im Exec Block von Blockly beim Befehl Parameter den ganzen Pfad aufrufen:

      /home/iobroker/python-venv/bin/msmart-ng
      
      1 Reply Last reply Reply Quote 0
      • U
        uweabc last edited by Homoran

        Ich habe vor einiger Zeit mal ein JavaScript für msmart-ng gebastelt. Dies habe ich mit den Erkenntnissen von BananaJoe neu überarbeitet. Anbei das JavaScript. midea.js

        Steuert eine Midea-Klimaanlage direkt über das Python-Programm 'msmart-ng' lokal im WLAN.

        Das Gerät wurde einmalig mit der Android-App in das WLAN integriert.
        Anschließend wurde der Internetzugang für diese Gerät über die FritzBox deaktiviert, um eine Fremdsteuerung zu unterbinden.
        Keine Cloud erforderlich für dieses JavaScript!

        Dieses JavaScript übernimmt folgende Funktionen:
        - Es liest die aktuellen Werte des Geräts im lokalen Netzwerk ab, siehe dazu Variable 'mideaPortaSplit'.
        Variable 'mideaPortaSplit' muss entsprechend geändert werden. Dazu id, ip, token und key entsprechend ändern.
        - Es erstellt eigenständig die passenden Objekte in ioBroker (unter javascript.0.midea.*).
        - Wird ein schreibbares Objekt geändert, so schreibt das JavaScript die Änderung direkt ins Gerät,
        indem es die Befehle über 'msmart-ng' sendet.
        Gültige Werte für FanSpeed / OperationalMode / SwingMode / SwingAngle / RateSelect / BreezeMode / AuxHeatMode
        siehe Variable 'AirConditioner'.
        - Der Loglevel (javascript.0.media.loglevel) kann während der Laufzeit des Skripts angepasst werden.
        Mögliche Werte sind 0=aus, 1=minimal, 2=alles.

        BananaJoe Homoran 2 Replies Last reply Reply Quote 0
        • BananaJoe
          BananaJoe Most Active @uweabc last edited by

          @uweabc

          ist die Verwendung von Apostophen statt Hochkommas Absicht?
          Zeile 163 und folgend,
          Zeile 173
          Zeile 196
          ???

          U 1 Reply Last reply Reply Quote 0
          • Homoran
            Homoran Global Moderator Administrators @uweabc last edited by

            @uweabc bitte das Script nicht als Datei/Link posten.
            Hier in code-tags einstellen!

            U 1 Reply Last reply Reply Quote 0
            • U
              uweabc @Homoran last edited by uweabc

              @homoran
              Danke für den Hinweis. Ich bin da vorsichtig. Leider ändert der code-tag den Sourcecode an manchen Stellen, also der gibt den Code nicht 1:1 wieder der eingeben wurde.

              1 Reply Last reply Reply Quote 0
              • U
                uweabc @BananaJoe last edited by uweabc

                @bananajoe
                @BananaJoe
                Ja, das ist die normale Formatierung bei JavaScript mit Variablen.
                Zur Sicherheit nochmal hier den Code mit leichten Verbesserungen (leider ändert der code-tag den Sourcecode, also die {1} ignorieren!):

                /*
                    Steuert eine Midea-Klimaanlage direkt über das Python-Programm 'msmart-ng' (siehe unten Installation 'msmart-ng') lokal im WLAN.
                    
                    Das Gerät wurde einmalig mit der Android-App in das WLAN integriert. 
                    Anschließend wurde der Internetzugang für diese Gerät über die FritzBox deaktiviert, um eine Fremdsteuerung zu unterbinden.
                    Keine Cloud erforderlich für dieses JavaScript!
                
                    Dieses JavaScript übernimmt folgende Funktionen:  
                    - Es liest die aktuellen Werte des Geräts im lokalen Netzwerk ab, siehe dazu Variable 'mideaPortaSplit'.  
                      Variable 'mideaPortaSplit' muss entsprechend geändert werden. Dazu id, ip, token und key entsprechend ändern.
                    - Es erstellt eigenständig die passenden Objekte in ioBroker (unter javascript.0.midea.*).  
                    - Wird ein schreibbares Objekt geändert, so schreibt das JavaScript die Änderung direkt ins Gerät, 
                      indem es die Befehle über 'msmart-ng' sendet.
                      Gültige Werte für FanSpeed / OperationalMode / SwingMode / SwingAngle / RateSelect / BreezeMode / AuxHeatMode
                      siehe Variable 'AirConditioner'.
                    - Der Loglevel (javascript.0.media.loglevel) kann während der Laufzeit des Skripts angepasst werden. 
                      Mögliche Werte sind 0=aus, 1=minimal, 2=alles.
                
                    Idee abgeleitet aus den Beitrag: https://forum.iobroker.net/topic/33198/test-adapter-midea-dimstal-klimaanlagen-v0-0-x/346?lang=de
                
                    Installation 'msmart-ng':
                    =========================
                    Zum Benutzer ioBroker wechseln:
                        sudo -u iobroker /usr/bin/bash
                    In das Home-Verzeichnis des Benutzers ioBroker wechseln
                        cd ~
                    Python Environment anlegen (falls noch nicht vorhanden):
                        python3 -m venv python-venv
                    und in die Umgebung wechseln:
                        source python-venv/bin/activate
                    Jetzt kann man per pip das Modul installieren
                        pip install msmart-ng
                    und dann per
                        msmart-ng
                    Nutzen. Vor der Nutzung muss dann aber immer erst das Envirtonment geladen werden.
                    Intelligenter weise wird das in den nachinstallierten Python-Modulen gleich richtig hinterlegt:
                        which msmart-ng
                    Ausgabe:
                        /home/iobroker/python-venv/bin/msmart-ng
                    Inhalt:
                        cat /home/iobroker/python-venv/bin/msmart-ng
                    Die erste Zeile ist
                        #!/home/iobroker/python-venv/bin/python3
                    Womit die richtige Umgebung genutzt wird.
                    In ioBroker Skripten den ganzen Pfad aufrufen:
                        /home/iobroker/python-venv/bin/msmart-ng
                */
                
                // id + token + key ermittelbar über 'msmart-ng query --region DE --auto 192.168.178.205'
                const mideaPortaSplit = { 
                    ip: '192.168.178.205',
                    id: '999832117233304',
                    token: 'BadBad132c05bab57aad3833ce247729d2f880e6fd5b8e1d2ca0eec82395d7edb85cf70d339faf7d0c8baf3b8275d86b183d430347bae6eba4a009cb38d1147f',
                    key: 'BadBadc06c854aa6ba7b200174327ed7fc9fb0fd0032407992403b9e4104c1d3',
                    controlSettings: [], // temp. Speicher für alle änderbaren Objekte, für on({id: device.controlSettings, change: 'any'}...
                };
                
                const basePath = 'javascript.0.midea'; // Basis-Objektpfad
                var LOGLEVEL = 2; // 0=aus, 1=minimal, 2=alles
                const msmartLoglevel = basePath + '.loglevel';
                const region = 'DE'; // --region {DE,KR,US}
                const msmart_ng = '/home/iobroker/python-venv/bin/msmart-ng';
                
                // enums siehe https://github.com/mill1000/midea-msmart/blob/main/msmart/device/AC/device.py
                class AirConditioner {
                    static FanSpeed = {
                        AUTO: 102,
                        MAX: 100,
                        HIGH: 80,
                        MEDIUM: 60,
                        LOW: 40,
                        SILENT: 20,
                        DEFAULT: 102
                    };
                
                    static OperationalMode = {
                        AUTO: 1,
                        COOL: 2,
                        DRY: 3,
                        HEAT: 4,
                        FAN_ONLY: 5,
                        SMART_DRY: 6,
                        DEFAULT: 5
                    };
                
                    static SwingMode = {
                        OFF: 0x0,
                        VERTICAL: 0xC,
                        HORIZONTAL: 0x3,
                        BOTH: 0xF,
                        DEFAULT: 0
                    };
                
                    static SwingAngle = {
                        OFF: 0,
                        POS_1: 1,
                        POS_2: 25,
                        POS_3: 50,
                        POS_4: 75,
                        POS_5: 100,
                        DEFAULT: 0
                    };
                
                    static RateSelect = {
                        OFF: 100,
                        GEAR_50: 50,
                        GEAR_75: 75,
                        LEVEL_1: 1,
                        LEVEL_2: 20,
                        LEVEL_3: 40,
                        LEVEL_4: 60,
                        LEVEL_5: 80,
                        DEFAULT: 100
                    };
                
                    static BreezeMode = {
                        OFF: 1,
                        BREEZE_AWAY: 2,
                        BREEZE_MILD: 3,
                        BREEZELESS: 4,
                        DEFAULT: 1
                    };
                
                    static AuxHeatMode = {
                        OFF: 0,
                        AUX_HEAT: 1,
                        AUX_ONLY: 2,
                        DEFAULT: 0
                    };
                }
                
                function convertToValidJSON(str) {
                    str = str.replace(/<[^>]*:\s*(\d+)>/g, '$1'); // Entfernt alles in <...>, Zahl nach : bleibt erhalten
                    str = str.replace(/\bNone\b/g, 'null'); // Ersetzt 'None' durch null
                    str = str.replace(/'/g, '"'); // Optional: Ersetze einzelne Anführungszeichen durch doppelte
                    str = str.replace(/\bTrue\b/g, 'true').replace(/\bFalse\b/g, 'false'); // Ersetze True/False durch true/false
                    str = str.replace('"power"', '"power_state"'); // Korrektur power control
                    return str;
                }
                
                function extractJsonFromLine(line) {
                    const index = line.indexOf('{');
                    if (index !== -1) {
                        try {
                            const jsonStr = convertToValidJSON(line.substring(index));
                            if (LOGLEVEL > 1) log(jsonStr);
                            return JSON.parse(jsonStr);
                        } catch (e) {
                            console.error('JSON konnte nicht geparst werden' + e);
                            return null;
                        }
                    }
                    return null;
                }
                
                // msmart-ng query 
                // usage: msmart-ng query [-h] [-d] [--region {DE,KR,US}] [--account ACCOUNT] [--password PASSWORD] [--capabilities] 
                //                        [--auto] 
                //                        [--id DEVICE_ID] [--token TOKEN] [--key KEY]
                //                        host
                function queryDevice(device) {
                    const queryMsmart = msmart_ng +
                        ' query' + 
                        ` --region ${region}` +
                        ` --token ${device.token}` +
                        ` --key ${device.key}` +
                        ` --id ${device.id}` +
                        ` ${device.ip}`;
                
                    if (LOGLEVEL > 1) log(queryMsmart);
                
                    exec(queryMsmart, (error, stdout, stderr) => {
                        if (error) {
                            console.error(`Fehler beim Ausführen: ${error}`);
                            return;
                        }
                
                        // Funktion, um nach JSON zu suchen
                        [stdout, stderr].forEach(output => {
                            const lines = output.split('\n');
                            for (let line of lines) {
                                if (line.includes('INFO:msmart.cli:')) {
                                    const data = extractJsonFromLine(line);
                                    if (data) {
                                        handleData(device, data);
                                        break; // nur die erste gefundene JSON-Zeile
                                    }
                                }
                            }
                        });
                    });
                }
                
                function handleData(device, data) {
                    const installOnControlSettings = (device.controlSettings.length == 0);
                    const id = data.id ? data.id.toString() : 'device';
                    const devicePath = `${basePath}.${id}`;
                
                    Object.keys(data).forEach(key => {
                        var keyL = key.toLowerCase();
                        if (keyL === 'id') return;
                        if (keyL === 'sn') return;
                        if (keyL === 'key') return;
                        if (keyL === 'token') return;
                        
                        const value = data[key];
                        const statePath = `${devicePath}.${key}`;
                
                        // Konfiguration für createState
                        var isControl = true;
                        if ((keyL === 'ip') ||
                            (keyL === 'online') ||
                            (keyL === 'port') ||
                            (keyL === 'type') ||
                            (keyL === 'name')) {
                            isControl = false;
                        }
                        const stateOptions = {
                            type: typeof value,
                            name: key,
                            read: true,
                        };
                
                        // Zusätzliche Eigenschaften basierend auf dem Schlüssel
                        if (typeof value !== 'boolean') {
                            if (keyL.includes('temperature')) {
                                stateOptions.unit = '°C';
                                stateOptions.role = 'value.temperature';
                                stateOptions.type = 'number';
                                if (!keyL.includes('target_'))
                                    isControl = false;
                            } else if (keyL.includes('humidity')) {
                                stateOptions.unit = '%';
                                stateOptions.role = 'value.humidity';
                                stateOptions.min = 0;
                                stateOptions.max = 100;
                                stateOptions.type = 'number';
                                if (!keyL.includes('target_'))
                                    isControl = false;
                            } else if (keyL.includes('energy')) {
                                stateOptions.unit = 'Wh';
                                stateOptions.min = 0;
                                stateOptions.max = 999999999;
                                stateOptions.type = 'number';
                                isControl = false;
                            } else if (keyL.includes('power')) {
                                stateOptions.unit = 'W';
                                stateOptions.role = 'value.power';
                                stateOptions.min = 0;
                                stateOptions.max = 4000;
                                stateOptions.type = 'number';
                                isControl = false;
                            }
                        }
                        stateOptions.write = isControl;
                        if (value != null) stateOptions.def = value;
                
                        // State erstellen, falls nicht vorhanden
                        createState(statePath, stateOptions, () => {
                            // Nach Erstellung Wert holen und ggf aktualisieren
                            getState(statePath, (err, state) => {
                                if (err || !state) {
                                    setState(statePath, value, true);
                                } else {
                                    if (state.val !== value) {
                                        if (LOGLEVEL > 1) log(`${statePath}:${value}`);
                                        setState(statePath, value, true);
                                    }
                                }
                            });
                        });
                        if (installOnControlSettings && 
                            stateOptions.write && 
                            !device.controlSettings.includes(statePath)) {
                            device.controlSettings.push(statePath);
                        }
                    });
                    if (installOnControlSettings) {
                        // Events
                        on({id: device.controlSettings, change: 'any'}, function (obj) {
                            if (obj.state.ack) return; // Diese Änderung wurde vom Skript selbst gemacht, ignorieren
                            if (LOGLEVEL > 0) log(`geändert ${obj.id} auf ${obj.state.val}`);
                            var parts = obj.id.split('.');
                            controlDevice(device, parts[4] ,obj.state.val);
                        });
                    }
                }
                
                // msmart-ng control
                // usage: msmart-ng control [-h] [-d] [--region {DE,KR,US}] [--account ACCOUNT] [--password PASSWORD] 
                //                          [--capabilities] 
                //                          [--auto] 
                //                          [--id DEVICE_ID] [--token TOKEN] [--key KEY]
                //                          host setting=value [setting=value ...]
                function controlDevice(device, setting, value) {
                    if (LOGLEVEL > 0) log(`control ${device.id}, setting ${setting}=${value}`);
                
                    var pyValue = value;
                    if (typeof pyValue == 'boolean') {
                        pyValue = value == true ? 'True':'False';
                    }
                
                    const controlMsmart = msmart_ng +
                        ' control' +
                        ` --region ${region}` +
                        ` --token ${device.token}` +
                        ` --key ${device.key}` +
                        ` --id ${device.id}` +
                        ` ${device.ip}` +
                        ` ${setting}=${pyValue}`;
                
                    if (LOGLEVEL > 1) log(controlMsmart);
                
                    exec(controlMsmart, (error, stdout, stderr) => {
                        if (error) {
                            console.error(`Fehler beim Ausführen: ${error}`);
                            return;
                        }
                
                        // Funktion, um nach JSON zu suchen
                        [stdout, stderr].forEach(output => {
                            if (output.includes('ERROR:')) {
                                console.error(`Fehler beim Ausführen: ${output}`);
                            }
                        });
                    });
                }
                
                function initVar() {
                    createState(msmartLoglevel, undefined, false, {
                        name: 'Loglevel',
                        type: 'number',
                        def: LOGLEVEL,
                        role: 'state'
                    });
                    LOGLEVEL = getState(msmartLoglevel).val;
                }
                
                // Main:
                initVar();
                queryDevice(mideaPortaSplit);
                schedule("*/5 * * * *", function () { // alle 5 Minuten
                    queryDevice(mideaPortaSplit); 
                });
                
                // Events:
                on({id: msmartLoglevel, change: 'any'}, function (obj) {
                    // Loglevel geändert
                    log(`msmartLoglevel ist ${obj.state.val}`);
                    LOGLEVEL = obj.state.val;
                });
                
                
                BananaJoe 1 Reply Last reply Reply Quote 0
                • BananaJoe
                  BananaJoe Most Active @uweabc last edited by

                  @uweabc sagte in Test Adapter Midea Dimstal Klimaanlagen v0.0.x:

                  Ja, das ist die normale Formatierung bei JavaScript mit Variablen.

                  Also ich sehe das zum ersten mal so ... hab das halt bisher getrennt verbunden, erst den Text, dann die Variable.

                  1 Reply Last reply Reply Quote 0
                  • Jolly
                    Jolly last edited by

                    Hallo, vielen Dank für die Anleitung.
                    ich versuche meine Klimananlage mit folgendem Befehl zu steuern.

                    msmart-ng control --account meineEmail --password meinPasswort --auto -d 192.168.1.34 power_state=false
                    

                    Funktioniert aber leider nicht, es kommt folgender Error

                    ERROR:msmart.discover:Failed to login to cloud. Error: Code: 3102, Message: Account or password incorrect, please re-enter
                    ERROR:msmart.discover:Could not establish cloud connection.
                    
                    
                    

                    Mit dem Befehler "discover" erhalte ich diese Rückmeldung

                    (python-venv) jolly@iobroker:~$ msmart-ng discover
                    INFO:msmart.cli:Discovering all devices on local network.
                    INFO:msmart.cloud:Using Midea cloud server: https://mp-prod.appsmb.com (China: False).
                    ERROR:msmart.discover:Failed to login to cloud. Error: Code: 3102, Message: Account or password incorrect, please re-enter
                    ERROR:msmart.discover:Could not establish cloud connection.
                    INFO:msmart.cli:Found 1 devices.
                    INFO:msmart.cli:Found device:
                    {'ip': '192.168.1.34', 'port': 6444, 'id': 152832117239990, 'online': False, 'supported': False, 'type': <DeviceType.AIR_CONDITIONER: 172>, 'name': 'net_ac_2190', 'sn': '000000P0000000Q1C084FF7421900000', 'key': None, 'token': None}
                    

                    Bedeutet das meine Klimaanlage ist nicht unterstützt? Weil ich die Rückmeldung 'supported': 'False' bekomme.
                    Oder an was könnte es sonst liegen? Benutzername und Passwort sind zu 100% richtig, selbes nutze ich auch für die Midea Air bzw. NetHome Plus App.

                    Vielen Dank

                    U 2 Replies Last reply Reply Quote 0
                    • U
                      uweabc @Jolly last edited by

                      @jolly
                      Die "Midea cloud" ist bei mir gesperrt, also ohne email & pw (war nur zum WLAN einrichten nötig).
                      Ich habe es so gemacht:
                      msmart-ng query --region DE --auto 192.168.1.34

                      dann bekommst du ein token, key und id

                      mit diesen dann control aufrufen:

                      msmart-ng control --region DE --token abcabcabcc05bab57aad3833ce247729d2f880e6fd5b8e1d2ca0eec82395d7edb85cf70d339faf7d0c8baf3b8275d86b183d430347bae6eba4a009cb38d1147f --key abcabcabcd854aa6ba7b200174327ed7fc9fb0fd0032407992403b9e4104c1d3 --id 999832117233304 192.168.1.34 power_state=False

                      Gruß Uwe

                      Jolly 1 Reply Last reply Reply Quote 0
                      • U
                        uweabc @Jolly last edited by uweabc

                        @bananajoe
                        mit der neuen Version von
                        msmart-ng -v
                        Ausgabe: msmart-ng version: 2025.7.0
                        werden auch die Energiewerte im ioBroker gefüllt.
                        Hier die neue Version des JavaScripts (vorher die alten midea-Objekte, den ganzen Baum, löschen):

                        /*
                            Version 06.07.2025 Add option to CLI to request energy information
                                               ID & Token & Key for msmart-ng are automatically determined
                            
                            Steuert eine Midea-Klimaanlage direkt über das Python-Programm 'msmart-ng' (siehe unten Installation 'msmart-ng') lokal im WLAN.
                            
                            Das Gerät wurde einmalig mit der Android-App in das WLAN integriert. 
                            Anschließend wurde der Internetzugang für diese Gerät über die FritzBox deaktiviert, um eine Fremdsteuerung zu unterbinden.
                            Keine Cloud erforderlich für dieses JavaScript!
                        
                            Dieses JavaScript übernimmt folgende Funktionen:  
                            - Es liest die aktuellen Werte des Geräts im lokalen Netzwerk ab, siehe dazu Variable 'mideaPortaSplit'.  
                              IP in Variable 'mideaPortaSplit' muss entsprechend geändert werden. 
                              ID + Token + Key werden über 'msmart-ng query --region DE --auto <ip>' automatisch ermittelt.
                            - Es erstellt eigenständig die passenden Objekte in ioBroker (unter javascript.0.midea.*).  
                            - Wird ein schreibbares Objekt geändert, so schreibt das JavaScript die Änderung direkt ins Gerät, 
                              indem es die Befehle über 'msmart-ng' sendet.
                              Gültige Werte für FanSpeed / OperationalMode / SwingMode / SwingAngle / RateSelect / BreezeMode / AuxHeatMode
                              siehe Variable 'AirConditioner'.
                            - Der Loglevel (javascript.0.media.loglevel) kann während der Laufzeit des Skripts angepasst werden. 
                              Mögliche Werte sind 0=aus, 1=minimal, 2=alles.
                        
                            Idee abgeleitet aus den Beitrag: https://forum.iobroker.net/topic/33198/test-adapter-midea-dimstal-klimaanlagen-v0-0-x/346?lang=de
                        
                            Installation 'msmart-ng':
                            =========================
                            Zum Benutzer ioBroker wechseln:
                                sudo -u iobroker /usr/bin/bash
                            In das Home-Verzeichnis des Benutzers ioBroker wechseln
                                cd ~
                            Python Environment anlegen (falls noch nicht vorhanden):
                                python3 -m venv python-venv
                            und in die Umgebung wechseln:
                                source python-venv/bin/activate
                            Jetzt kann man per pip das Modul installieren
                                pip install msmart-ng
                            und dann Version anzeigen:
                                msmart-ng -v
                            Ausgabe:        
                                msmart-ng version: 2025.7.0
                            Vor der Nutzung muss dann aber immer erst das Envirtonment geladen werden.
                            Intelligenter weise wird das in den nachinstallierten Python-Modulen gleich richtig hinterlegt:
                                which msmart-ng
                            Ausgabe:
                                /home/iobroker/python-venv/bin/msmart-ng
                            Inhalt:
                                cat /home/iobroker/python-venv/bin/msmart-ng
                            Die erste Zeile ist
                                #!/home/iobroker/python-venv/bin/python3
                            Womit die richtige Umgebung genutzt wird.
                            In ioBroker Skripten den ganzen Pfad aufrufen:
                                /home/iobroker/python-venv/bin/msmart-ng
                        */
                        
                        // id + token + key ermittelbar über 'msmart-ng query --region DE --auto 192.168.178.205'
                        const mideaPortaSplit = { 
                            ip: '192.168.178.205',
                            id: null, // Temporary storage, ID for msmart-ng is automatically determined
                            token: null, // Temporary storage, token for msmart-ng is automatically determined
                            key: null, // Temporary storage, key for msmart-ng is automatically determined
                            controlSettings: [], // Temporary storage for all modifiable objects, used in on({id: mideaPortaSplit.controlSettings, change: 'any'}...
                        };
                        let controlListener;
                        
                        const basePath = 'javascript.0.midea'; // Base object path
                        var LOGLEVEL = 2; // 0=off, 1=minimal, 2=all
                        const msmartLoglevel = basePath + '.loglevel';
                        const region = 'DE'; // --region {DE,KR,US}
                        const msmart_ng = '/home/iobroker/python-venv/bin/msmart-ng';
                        
                        // Enums see https://github.com/mill1000/midea-msmart/blob/main/msmart/device/AC/device.py
                        // Note: The above link is for reference; it contains enum definitions for the device.
                        class AirConditioner {
                            static FanSpeed = {
                                AUTO: 102,
                                MAX: 100,
                                HIGH: 80,
                                MEDIUM: 60,
                                LOW: 40,
                                SILENT: 20,
                                DEFAULT: 102
                            };
                        
                            static OperationalMode = {
                                AUTO: 1,
                                COOL: 2,
                                DRY: 3,
                                HEAT: 4,
                                FAN_ONLY: 5,
                                SMART_DRY: 6,
                                DEFAULT: 5
                            };
                        
                            static SwingMode = {
                                OFF: 0,
                                VERTICAL: 12,
                                HORIZONTAL: 3,
                                BOTH: 15,
                                DEFAULT: 0
                            };
                        
                            static SwingAngle = {
                                OFF: 0,
                                POS_1: 1,
                                POS_2: 25,
                                POS_3: 50,
                                POS_4: 75,
                                POS_5: 100,
                                DEFAULT: 0
                            };
                        
                            static RateSelect = {
                                OFF: 100,
                                GEAR_50: 50,
                                GEAR_75: 75,
                                LEVEL_1: 1,
                                LEVEL_2: 20,
                                LEVEL_3: 40,
                                LEVEL_4: 60,
                                LEVEL_5: 80,
                                DEFAULT: 100
                            };
                        
                            static BreezeMode = {
                                OFF: 1,
                                BREEZE_AWAY: 2,
                                BREEZE_MILD: 3,
                                BREEZELESS: 4,
                                DEFAULT: 1
                            };
                        
                            static AuxHeatMode = {
                                OFF: 0,
                                AUX_HEAT: 1,
                                AUX_ONLY: 2,
                                DEFAULT: 0
                            };
                        }
                        
                        function convertToValidJSON(str) {
                            return str
                                .replace(/<[^>]*:\s*(\d+)>/g, '$1') // Remove everything in <...>, keep number after :
                                .replace(/\bNone\b/g, 'null') // Replace 'None' with null
                                .replace(/'/g, '"') // Optional: replace single quotes with double quotes
                                .replace(/\bTrue\b/g, 'true').replace(/\bFalse\b/g, 'false') // Convert True/False to true/false
                                .replace('"power"', '"power_state"') // name correction for power control
                                .replace('"mode"', '"operational_mode"'); // name correction for operational mode control
                        }
                        
                        function extractJsonFromLine(line) {
                            const index = line.indexOf('{');
                            if (index !== -1) {
                                try {
                                    const jsonStr = convertToValidJSON(line.substring(index));
                                    if (LOGLEVEL > 1) log(jsonStr);
                                    return JSON.parse(jsonStr);
                                } catch (e) {
                                    console.error(`Could not parse JSON ${e}`);
                                    return null;
                                }
                            }
                            return null;
                        }
                        
                        // msmart-ng query 
                        // usage: msmart-ng query [-h] [-d] [--region {DE,KR,US}] [--account ACCOUNT] [--password PASSWORD] [--capabilities] 
                        //                        [--auto] [--energy]
                        //                        [--id DEVICE_ID] [--token TOKEN] [--key KEY]
                        //                        host
                        function queryDevice(device) {
                            const auto = (device.token == null); // query with --auto is slow, login with token,key&id it is faster
                            const login = auto ? 
                                ' --auto' : 
                                ` --region ${region}` +
                                ` --token ${device.token}` +
                                ` --key ${device.key}` +
                                ` --id ${device.id}`;
                            const queryMsmart = msmart_ng +
                                ' query' + login +
                                ' --energy' +
                                ` ${device.ip}`;
                        
                            if (LOGLEVEL > 1) log(queryMsmart);
                            const devicePath = `${basePath}.${device.id}`;
                            exec(queryMsmart, (error, stdout, stderr) => {
                                if (error) {
                                    var s = `${error}`;
                                    if (s.includes('Connect failed') || s.includes('Connect timeout')) {
                                        if (getState(`${devicePath}.online`).val) {
                                            log(`${devicePath}.online=false`);
                                            setState(`${devicePath}.online`, false, true);
                                        }
                                    } else {
                                        console.error(`Error executing query: ${error}`);
                                    }
                                    return;
                                }
                        
                                // Function to search for JSON in output
                                [stdout, stderr].forEach(output => {
                                    const lines = output.split('\n');
                                    for (let line of lines) {
                                        if (line.includes('INFO:msmart.cli:')) {
                                            const data = extractJsonFromLine(line);
                                            if (data) {
                                                handleData(device, data);
                                                break; // only the first found JSON line
                                            }
                                        }
                                    }
                                });
                            });
                        }
                        
                        /*
                        const stateName = [
                            {control: true,  key: 'eco', name: 'Energy Saving Mode'},
                            {control: true,  key: 'power_save', name: 'Power Saving'},
                            {control: true,  key: 'swing_mode', name: 'Airflow Direction'},
                            {control: true,  key: 'fan_speed', name: 'Fan Speed'},
                            {control: true,  key: 'operational_mode', name: 'Operating Mode'},
                            {control: true,  key: 'power_state', name: 'On/Off'},
                            {control: false, key: 'indoor_temperature', name: 'Indoor Temperature'},
                            {control: false, key: 'outdoor_temperature', name: 'Outdoor Temperature'},
                            {control: true,  key: 'target_temperature', name: 'Target Temperature'},
                            {control: true,  key: 'fahrenheit', name: 'Temperature Unit'},
                            {control: true,  key: 'target_humidity', name: 'Target Humidity'},
                            {control: true,  key: 'horizontal_swing_angle', name: 'Horizontal Swing Angle'},
                            {control: false, key: 'indoor_humidity', name: 'Indoor Humidity'},
                            {control: true,  key: 'vertical_swing_angle', name: 'Vertical Swing Angle'},
                            {control: true,  key: 'turbo', name: 'Turbo Mode'},
                            {control: true,  key: 'freeze_protection', name: 'Frost Protection'},
                            {control: true,  key: 'sleep', name: 'Sleep Mode'},
                            {control: true,  key: 'display_on', name: 'Display On/Off'},
                            {control: true,  key: 'beep', name: 'Beep Sound'},
                            {control: false, key: 'filter_alert', name: 'Filter Warning'},
                            {control: true,  key: 'follow_me', name: 'Follow Me'},
                            {control: true,  key: 'purifier', name: 'Air Purifier'},
                            {control: true,  key: 'self_clean', name: 'Self-Cleaning'},
                            {control: false, key: 'total_energy_usage', name: 'Total Energy Usage'},
                            {control: false, key: 'current_energy_usage', name: 'Current Energy Usage'},
                            {control: false, key: 'real_time_power_usage', name: 'Real-Time Power Usage'},
                            {control: true,  key: 'rate_select', name: 'Performance Level'},
                            {control: true,  key: 'aux_mode', name: 'Auxiliary Mode'},
                            {control: false, key: 'ip', name: 'IP Address'},
                            {control: false, key: 'name', name: 'Device Name'},
                            {control: false, key: 'supported', name: 'Supported Features'},
                            {control: false, key: 'type', name: 'Device Type'},
                            {control: false, key: 'online', name: 'Connection Status'},
                            {control: false, key: 'port', name: 'Port'},
                            {control: false, key: 'cascade_mode', name: 'Cascade Control'},   
                            {control: false, key: 'sn', name: 'Serial Number'},   
                        ];
                        */
                        const stateName = [
                            {control: true,  key: 'eco', name: 'Energiesparmodus'},
                            {control: true,  key: 'power_save', name: 'Energiesparen'},
                            {control: true,  key: 'swing_mode', name: 'Luftstromrichtung'},
                            {control: true,  key: 'fan_speed', name: 'Lüftergeschwindigkeit'},
                            {control: true,  key: 'operational_mode', name: 'Betriebsmodus'},
                            {control: true,  key: 'power_state', name: 'Ein/Aus'},
                            {control: false, key: 'indoor_temperature', name: 'Innentemperatur'},
                            {control: false, key: 'outdoor_temperature', name: 'Außentemperatur'},
                            {control: true,  key: 'target_temperature', name: 'Zieltemperatur'},
                            {control: true,  key: 'fahrenheit', name: 'Temperatureinheit'},
                            {control: true,  key: 'target_humidity', name: 'Zielfeuchtigkeit'},
                            {control: true,  key: 'horizontal_swing_angle', name: 'Horizontaler Schwenkwinkel'},
                            {control: false, key: 'indoor_humidity', name: 'Raumluftfeuchtigkeit'},
                            {control: true,  key: 'vertical_swing_angle', name: 'Vertikaler Schwenkwinkel'},
                            {control: true,  key: 'turbo', name: 'Turbomodus'},
                            {control: true,  key: 'freeze_protection', name: 'Frostschutz'},
                            {control: true,  key: 'sleep', name: 'Schlafmodus'},
                            {control: true,  key: 'display_on', name: 'Display Ein/Aus'},
                            {control: true,  key: 'beep', name: 'Signalton'},
                            {control: false, key: 'filter_alert', name: 'Filterwarnung'},
                            {control: true,  key: 'follow_me', name: 'Follow Me'},
                            {control: true,  key: 'purifier', name: 'Luftreiniger'},
                            {control: true,  key: 'self_clean', name: 'Selbstreinigung'},
                            {control: false, key: 'total_energy_usage', name: 'Gesamtenergieverbrauch'},
                            {control: false, key: 'current_energy_usage', name: 'Aktueller Energieverbrauch'},
                            {control: false, key: 'real_time_power_usage', name: 'Echtzeitleistung'},
                            {control: true,  key: 'rate_select', name: 'Leistungsstufe'},
                            {control: true,  key: 'aux_mode', name: 'Zusatzmodus'},
                            {control: false, key: 'ip', name: 'IP-Adresse'},
                            {control: false, key: 'name', name: 'Gerätename'},
                            {control: false, key: 'supported', name: 'Unterstützt'},
                            {control: false, key: 'type', name: 'Gerätetyp'},
                            {control: false, key: 'online', name: 'Verbindungsstatus'},
                            {control: false, key: 'port', name: 'Port'},
                            {control: false, key: 'cascade_mode', name: 'Kaskadensteuerung'},   
                            {control: false, key: 'sn', name: 'Seriennummer'},   
                        ];
                        
                        function initControlSettings(device) {
                            device.controlSettings = [];
                            const devicePath = `${basePath}.${device.id}`;
                            const controlStates = stateName.filter(state => state.control);
                            controlStates.forEach(state => {
                                const statePath = `${devicePath}.${state.key}`;
                                device.controlSettings.push(statePath);
                            });
                            log('initControlSettings() device.controlSettings.length=' + device.controlSettings.length);
                        }
                        
                        function handleData(device, data) {
                            const id = data.id ? data.id.toString() : 'device';
                            const devicePath = `${basePath}.${id}`;
                        
                            Object.keys(data).forEach(key => {
                                const value = data[key];
                                var keyL = key.toLowerCase();
                                if (keyL === 'id') {
                                    if (device.id == null) device.id = value;
                                    return;
                                } else if (keyL === 'key') {
                                    if (device.key == null) device.key = value;
                                    return;
                                } else if (keyL === 'token') {
                                    if (device.token == null) device.token = value;
                                    return;
                                }       
                                if (['sn', 'name'].includes(keyL) && (value == null)) {
                                    return;
                                }
                                const statePath = `${devicePath}.${key}`;
                        
                                // Configuration for createState
                                const stateOptions = {
                                    type: typeof value,
                                    name: stateName.find(item => item.key === keyL)?.name || key,
                                    write: stateName.find(item => item.key === keyL)?.control || false,
                                    read: true,
                                };
                                if (value != null) stateOptions.def = value;
                        
                                // Additional properties based on the key
                                if (typeof value !== 'boolean') {
                                    if (keyL.includes('temperature')) {
                                        stateOptions.unit = '°C';
                                        stateOptions.role = 'value.temperature';
                                        stateOptions.type = 'number';
                                    } else if (keyL.includes('humidity')) {
                                        stateOptions.unit = '%';
                                        stateOptions.role = 'value.humidity';
                                        stateOptions.min = 0;
                                        stateOptions.max = 100;
                                        stateOptions.type = 'number';
                                    } else if (keyL.includes('energy')) {
                                        stateOptions.unit = 'Wh';
                                        stateOptions.min = 0;
                                        stateOptions.max = 999999999;
                                        stateOptions.type = 'number';
                                    } else if (keyL.includes('power')) {
                                        stateOptions.unit = 'W';
                                        stateOptions.role = 'value.power';
                                        stateOptions.min = 0;
                                        stateOptions.max = 4000;
                                        stateOptions.type = 'number';
                                    }
                                }
                        
                                // Create state if it does not exist
                                createState(statePath, stateOptions, () => {
                                    // After creation, get the value and update if necessary
                                    getState(statePath, (err, state) => {
                                        if (err || !state) {
                                            setState(statePath, value, true);
                                        } else {
                                            if (state.val !== value) {
                                                if (LOGLEVEL > 1) log(`Updating ${statePath} to ${value}`);
                                                setState(statePath, value, true);
                                            }
                                        }
                                    });
                                });
                            });
                            if ((device.controlSettings.length == 0) && (device.id != null)) {
                                initControlSettings(device);
                                if (controlListener && typeof controlListener === 'function') controlListener(); // remove old listener
                                controlListener = on({id: mideaPortaSplit.controlSettings, change: 'any'}, function (obj) {
                                    var parts = obj.id.split('.');
                                    var setting = parts[4];
                                    if ((setting == 'online') && obj.state.val) powerStateOnRepeat = -1;
                                    if (obj.state.ack) return; // change was made by script, ignore
                                    if (LOGLEVEL > 0) log(`Changed ${obj.id} to ${obj.state.val}`);
                                    controlDevice(mideaPortaSplit, setting ,obj.state.val);
                                });        
                            }
                        }
                        
                        // msmart-ng control
                        // usage: msmart-ng control [-h] [-d] [--region {DE,KR,US}] [--account ACCOUNT] [--password PASSWORD] 
                        //                          [--capabilities] 
                        //                          [--auto] 
                        //                          [--id DEVICE_ID] [--token TOKEN] [--key KEY]
                        //                          host setting=value [setting=value ...]
                        var powerStateOnRepeat = -1;
                        function controlDevice(device, setting, value) {
                            if (LOGLEVEL) log(`Controlling device ${device.id}, setting ${setting}=${value}`);
                        
                            const stateEntry = stateName.find(entry => entry.key === setting);    
                            if (!stateEntry || stateEntry.control === false) {
                                if (LOGLEVEL > 1) log(`${setting} is not controllable!`);
                                return;
                            }
                        
                            if ((setting == 'power_state') && (value == false)) {
                                powerStateOnRepeat = -1;
                                setTimeout(function () {
                                    queryDevice(device);
                                    setTimeout(function () {
                                        queryDevice(device);
                                    }, 30 * 1000);   
                                }, 30 * 1000);   
                            }
                        
                            var pyValue = value;
                            if (typeof pyValue == 'boolean') {
                                pyValue = value == true ? 'True':'False';
                            }
                        
                            const controlMsmart = msmart_ng +
                                ' control' +
                                ` --region ${region}` +
                                ` --token ${device.token}` +
                                ` --key ${device.key}` +
                                ` --id ${device.id}` +
                                ` ${device.ip}` +
                                ` ${setting}=${pyValue}`;
                        
                            if (LOGLEVEL > 1) log(controlMsmart);
                            const devicePath = `${basePath}.${device.id}`;
                            exec(controlMsmart, (error, stdout, stderr) => {
                                if (error) {
                                    var s = `${error}`;
                                    if (s.includes('Connect failed') || s.includes('Connect timeout')) {
                                        if (getState(`${devicePath}.online`).val) {
                                            log(`${devicePath}.online=false`);
                                            setState(`${devicePath}.online`, false, true);
                                        }
                                        if ((setting == 'power_state') && (powerStateOnRepeat < (25 * 1000))) {
                                            setTimeout(function () {
                                                log('Repeating control: power_state=True');
                                                controlDevice(device, setting, value);
                                                powerStateOnRepeat += 2 * 1000;
                                            }, 2 * 1000);                    
                                        }
                                    } else {
                                        console.error(`Error executing control: ${error}`);
                                    }
                                    return;
                                }
                                powerStateOnRepeat = -1;
                                // Funktion, um nach JSON zu suchen
                                [stdout, stderr].forEach(output => {
                                    if (output.length) {
                                        if (output.includes('ERROR:')) {
                                            console.error(`Error during execution: ${output}`);
                                            if (getState(`${devicePath}.online`).val)
                                                setState(`${devicePath}.online`, false, true);
                                        } else {
                                            if (LOGLEVEL > 1) log(output);
                                            if (getState(`${devicePath}.online`).val == false)
                                                setState(`${devicePath}.online`, true, true);
                                        }
                                    }
                                });
                            });
                        }
                        
                        function initVar() {
                            createState(msmartLoglevel, undefined, false, {
                                name: 'Loglevel',
                                type: 'number',
                                def: LOGLEVEL,
                                role: 'state'
                            });
                            LOGLEVEL = getState(msmartLoglevel).val;
                        }
                        
                        // Main:
                        initVar();
                        queryDevice(mideaPortaSplit);
                        schedule("*/2 * * * *", function () { // every 2 minutes
                            queryDevice(mideaPortaSplit); 
                        });
                        
                        // Events:
                        on({id: msmartLoglevel, change: 'any'}, function (obj) {
                            // Log level changed
                            log(`msmartLoglevel is now ${obj.state.val}`);
                            LOGLEVEL = obj.state.val;
                        });
                        

                        Die generierten Objekte im ioBroker sehen dann so aus:
                        ksnip_20250706-122153.png
                        Und in meiner smartVisu (ja, ich benutze smartVisu!) sieht das so aus:
                        Handy:
                        photo_2025-07-06_12-15-56.jpg
                        photo_2025-07-06_12-07-46.jpg
                        photo_2025-07-06_12-08-18.jpg
                        photo_2025-07-06_12-13-42.jpg
                        Tablet:
                        ksnip_20250706-123230.png

                        BananaJoe 1 Reply Last reply Reply Quote 0
                        • BananaJoe
                          BananaJoe Most Active @uweabc last edited by

                          @uweabc cool, unterstützt mein Modell leider nicht, hier die Query-Abfrage (Tokens, Ids etc sind geändert)

                          {'ip': '192.168.1.29', 'port': 6444, 'id': 133402613440365, 'online': True, 'supported': True, 'type': <DeviceType.AIR_CONDITIONER: 172>, 'name': None, 'sn': None, 'key': 'a5409a86c04b3d1834ed59ead3e083349fa8b6537878443d0ac794351b818a4f', 'token': '86389f141a1fe5188cad648496607d0e1ca032530a74c267909fff5f3237e73c77cf363c2bf6d4509cd0bb5ec9173ee7e479136f8667ef8a0563ae1bd894c712', 'power': False, 'mode': <OperationalMode.COOL: 2>, 'fan_speed': <FanSpeed.AUTO: 102>, 'swing_mode': <SwingMode.BOTH: 15>, 'horizontal_swing_angle': <SwingAngle.OFF: 0>, 'vertical_swing_angle': <SwingAngle.OFF: 0>, 'cascade_mode': <CascadeMode.OFF: 0>, 'target_temperature': 22.0, 'indoor_temperature': 26.3, 'outdoor_temperature': 26.0, 'target_humidity': 0, 'indoor_humidity': None, 'eco': False, 'turbo': False, 'freeze_protection': False, 'sleep': False, 'display_on': True, 'beep': False, 'fahrenheit': False, 'filter_alert': False, 'follow_me': False, 'purifier': False, 'self_clean': False, 'total_energy_usage': None, 'current_energy_usage': None, 'real_time_power_usage': None, 'rate_select': <RateSelect.OFF: 100>, 'aux_mode': <AuxHeatMode.OFF: 0>}
                          
                          U 1 Reply Last reply Reply Quote 0
                          • Jolly
                            Jolly @uweabc last edited by

                            @uweabc

                            danke für die Antwort.
                            Leider kommt auf den von dir vorgeschlagenen Befehle folgende Rückmeldung

                            jolly@iobroker:~$ msmart-ng query --region DE --auto 192.168.1.34
                            usage: msmart-ng [-h] [-v] {discover,query,control,download} ...
                            msmart-ng: error: unrecognized arguments: --region 192.168.1.34
                            
                            U 1 Reply Last reply Reply Quote 0
                            • U
                              uweabc @Jolly last edited by

                              @jolly
                              Sollte schon gehen, evtl. altes msmart-ng, mach mal
                              msmart-ng -v
                              Ausgabe: msmart-ng version: 2025.7.0

                              Jolly 1 Reply Last reply Reply Quote 0
                              • U
                                uweabc @BananaJoe last edited by

                                @bananajoe
                                Bei den neuen msmart-ng 2025.7.0 mit --energy angegeben, z.B. so?
                                msmart-ng query --region DE --auto --energy 192.168.1.29
                                oder auch mit id token und key anstatt --auto

                                1 Reply Last reply Reply Quote 0
                                • Jolly
                                  Jolly @uweabc last edited by

                                  @uweabc
                                  Du hast recht ich habe noch die Version 2024.9.0
                                  Blöde frage, aber wie kann ich das updaten.
                                  Habe es so versucht.

                                  jolly@iobroker:~$ pip install --upgrade msmart-ng
                                  Requirement already up-to-date: msmart-ng in ./.local/lib/python3.8/site-packages (2024.9.0)
                                  
                                  U BananaJoe 2 Replies Last reply Reply Quote 0
                                  • U
                                    uweabc @Jolly last edited by uweabc

                                    @jolly
                                    Ich habe das gemacht:
                                    pip uninstall msmart-ng
                                    dann
                                    pip install msmart-ng

                                    oder so:
                                    https://forum.iobroker.net/topic/33198/test-adapter-midea-dimstal-klimaanlagen-v0-0-x/346

                                    1 Reply Last reply Reply Quote 0
                                    • BananaJoe
                                      BananaJoe Most Active @Jolly last edited by

                                      @jolly

                                      pip install msmart-ng --upgrade
                                      

                                      hat bei mir funktioniert und auf die aktuelle Version gehoben

                                      1 Reply Last reply Reply Quote 0
                                      • First post
                                        Last post

                                      Support us

                                      ioBroker
                                      Community Adapters
                                      Donate

                                      418
                                      Online

                                      31.9k
                                      Users

                                      80.1k
                                      Topics

                                      1.3m
                                      Posts

                                      dimstal midea nethome nethome plus
                                      63
                                      363
                                      63174
                                      Loading More Posts
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      Community
                                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                      The ioBroker Community 2014-2023
                                      logo