[70_ENPHASE.pm] Modul zur Integration Enphase Gateway

Begonnen von Christian83, 17 November 2023, 12:51:36

Vorheriges Thema - Nächstes Thema

Christian83

Zitat von: StefanT am 23 März 2024, 20:11:27Hi Christian,

danke für die Info. Mein "Home-Automation-PC" läuft unter Ubuntu 22.04.4 LTS. Fhem läuft bei mir allerdings darauf als Docker-Image. Dort wird die Perl-Version 5.32.1 genutzt. Habe mir auch nochmal eine zweite aktuelle FHEM-Installation erzeugt und dort das Modul installiert. Dort laufe ich aber auf denselben Fehler. Schade eigentlich.
Aber vielen Dank für deine Unterstützung.

Gruß Stefan


Kannst du rauszufinden, welche JSON Version dein perl nutzt?

StefanT

Hast du 'ne Idee, wo man das nachsehen kann. Bin jetzt aber erstmal ein paar Tage auf Schulung.
LG Stefan

Christian83

Zitat von: StefanT am 24 März 2024, 12:08:14Hast du 'ne Idee, wo man das nachsehen kann. Bin jetzt aber erstmal ein paar Tage auf Schulung.
LG Stefan

In der Kommandozeile (putty)
perl -MJSON\ 999

StefanT

Zitat von: Christian83 am 25 März 2024, 13:11:54In der Kommandozeile (putty)
Code Auswählen Erweitern
perl -MJSON\ 999

Da sagt er mir: JSON version 999 required--this is only version 4.10.

Christian83

Hallo Stefan,

ich hatte 4.03. Habe jetzt auf 4.10 umgestellt. Funktioniert trotzdem.

Kann das Problem leider nicht nachstellen und dementsprechend auch nicht versuchen es zu umgehen.

StefanT

Hallo Christian,

das ist ja schon sehr merkwürdig... Keine Ahnung, was da bei meiner Installation das Problem ist...

Aber egal, ich habe jetzt eine Lösung gefunden. Ich habe dein Modul bei mir ein wenig angepasst. Vor dem JSON-decode entferne ich aus den Daten jeweils das Kapitel mit den doppelten Schlüsseln.
    "dry_contacts": {
        " \u0011": {
            "dry_contact_id": " \u0011",
            "dry_contact_type": " \u0011",
            "dry_contact_load_name": "\u0006",
            "dry_contact_status": 3047892
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3047892
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3047892
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3047892
        }
    }
bzw.
        "10": {
            "SOC": 5,
            "BMU_Comm_State": 3,
            "Num Acive PCUs": 4,
            "LED Status": 17,
            "Enc Grid State": 0,
            "Enc Internal State": 1,
            "Timestamp": 1712524028,
            "Serial": "122249010830",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0,
            "Serial": "122249010598",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0,
            "Serial": "122249015697",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0,
            "Serial": "122249015777",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0
        }

Damit funktioniert es jetzt bei mir. Die Readings werden gelesen und auch regelmäßig aktualisiert.

Vielen Dank für deine Mühe und deine Unterstützung.

Lieben Gruß
Stefan

Der Olaf

Hallo Stefan,
würdest Du Dein modifiziertes Modul hier bereitstellen?
Gruß Olaf

Christian83

Zitat von: StefanT am 08 April 2024, 13:14:28Hallo Christian,

das ist ja schon sehr merkwürdig... Keine Ahnung, was da bei meiner Installation das Problem ist...

Aber egal, ich habe jetzt eine Lösung gefunden. Ich habe dein Modul bei mir ein wenig angepasst. Vor dem JSON-decode entferne ich aus den Daten jeweils das Kapitel mit den doppelten Schlüsseln.
    "dry_contacts": {
        " \u0011": {
            "dry_contact_id": " \u0011",
            "dry_contact_type": " \u0011",
            "dry_contact_load_name": "\u0006",
            "dry_contact_status": 3047892
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3047892
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3047892
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3047892
        }
    }
bzw.
        "10": {
            "SOC": 5,
            "BMU_Comm_State": 3,
            "Num Acive PCUs": 4,
            "LED Status": 17,
            "Enc Grid State": 0,
            "Enc Internal State": 1,
            "Timestamp": 1712524028,
            "Serial": "122249010830",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0,
            "Serial": "122249010598",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0,
            "Serial": "122249015697",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0,
            "Serial": "122249015777",
            "Oper state": 1,
            "Enph Oper state": 0,
            "Comm State": 6,
            "Grid State": 0,
            "pcu_events": 0
        }

Damit funktioniert es jetzt bei mir. Die Readings werden gelesen und auch regelmäßig aktualisiert.

Vielen Dank für deine Mühe und deine Unterstützung.

Lieben Gruß
Stefan


Hi,

zeig mal wie du das machst. Dann baue ich das bei mir ein.

Gruß

StefanT

#23
Zitat von: Christian83 am 08 April 2024, 15:06:51Hi,

zeig mal wie du das machst. Dann baue ich das bei mir ein.

Gruß

Einmal für getLiveData hinzugefügt:
    # Abschnitt "dry_contacts" wegen duplicate Keys vor dem decode entfernen
    $data = substr($data,0,index($data,"dry_contacts"));
    $data = substr($data,0,rindex($data,","))."}";

sub ENPHASE_getnewliveData($) {

    my ( $param, $err, $data ) = @_;
    my $hash = $param->{hash};
    my $name = $hash->{NAME};

    readingsSingleUpdate( $hash, "state", "reading newlive", 1 );

    my $retVal = checkHttpResponse( $param, $err, $data );
    if ($retVal) {
        return;
    }

    # Abschnitt "dry_contacts" wegen duplicate Keys vor dem decode entfernen
    $data = substr($data,0,index($data,"dry_contacts"));
    $data = substr($data,0,rindex($data,","))."}";
   
    my $decoded_json;
    eval {
        my $json_bytes = encode( 'UTF-8', $data );
        $decoded_json = JSON->new->utf8->decode($json_bytes);
    };
    if ($@) {
        Debug("eval Fehler");
        Debug($@);
        Debug($data);
        InternalTimer( gettimeofday() + $updateinterval, "ENPHASE_getnewliveStart", $hash );
        return;

    }
    ...

Und einmal für getStorageData hinzugefügt:
    # Abschnitt "10": wegen duplicate Keys vor dem decode entfernen
    $data = substr($data,0,index($data,"\"10\":"));
    $data = substr($data,0,rindex($data,","))."}}";

sub ENPHASE_getStorageRawData($) {

    ...
    if ( $data eq "" ) {

        #$hash->{STATE} = "no Data in Live Status";
        readingsSingleUpdate( $hash, "state", "no data in newlive", 1 );
        return;
    }

    # Abschnitt "10": wegen duplicate Keys vor dem decode entfernen
    $data = substr($data,0,index($data,"\"10\":"));
    $data = substr($data,0,rindex($data,","))."}}";

    my $decoded_json;
    eval {
        my $json_bytes = encode( 'UTF-8', $data );
        $decoded_json = JSON->new->utf8->decode($json_bytes);

        #        $decoded_json = decode_json($data);
    };
    if ($@) {
        Debug("eval Fehler");
        Debug($@);
        Debug($data);
        InternalTimer( gettimeofday() + $updateinterval, "ENPHASE_getnewliveStart", $hash );
        return;

    }
    ...

StefanT

Zitat von: Der Olaf am 08 April 2024, 14:51:46Hallo Stefan,
würdest Du Dein modifiziertes Modul hier bereitstellen?

Hi Olaf,
hast du auch die Probleme mit den "duplicate Keys"?
Da Christian die Änderung in sein Modul übernehmen möchte, schlage ich vor, dass Christian dann das geänderte Modul hier zur Verfügung stellt.
Viele Grüße
Stefan

Der Olaf

Moin Stefan, moin Christian,
ich habe jetzt einmal die beiden "Modifikationen" in das Modul eingearbeitet, im ersten Step hatte ich irgendwo noch einen Fehler, jetzt läuft's.
Sieht jedenfalls so aus.
  Du darfst diesen Dateianhang nicht ansehen.
Gruß Olaf

Der Olaf

Hallo zusammen,
das Modul funktionierte jetzt mit den obigen Anpassungen einige Tage. Leider habe ich seit gestern immer den Fehler im "state" = "Daten zu alt". Das ganze läuft in einer Dauerschleife.
Es werden auch nicht mehr alle readings angezeigt.
Nachfolgend aus dem Log (verbose 5) ein Auszug (hoffentlich komplett?).
Ich bin da nicht fit genug drin, das komplett zu lesen und zu verstehen.
Vielen Dank für Hilfe.
2024.04.14 13:36:37.812 4: Enphase (MEIN-DEVICE-NAME): ==> start livedaten
2024.04.14 13:36:38.683 5: Enphase (MEIN-DEVICE-NAME): ==> header: HTTP/1.1 200 OK
Server: openresty/1.17.8.1
Date: Sun, 14 Apr 2024 11:36:23 GMT
Content-Type: application/json
Connection: close
Pragma: no-cache
Expires: 1
Cache-Control: no-cache
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
2024.04.14 13:36:38.683 5: {"production":[{"type":"inverters","activeCount":17,"readingTime":1713094582,"wNow":4603,"whLifetime":170902},{"type":"eim","activeCount":1,"measurementType":"production","readingTime":1713094583,"wNow":4445.977,"whLifetime":173926.92,"varhLeadLifetime":20.998,"varhLagLifetime":57900.881,"vahLifetime":216355.543,"rmsCurrent":18.404,"rmsVoltage":699.422,"reactPwr":266.564,"apprntPwr":4490.787,"pwrFactor":0.98,"whToday":15206.92,"whLastSevenDays":131661.92,"vahToday":17482.543,"varhLeadToday":1.998,"varhLagToday":3677.881}],"consumption":[{"type":"eim","activeCount":1,"measurementType":"total-consumption","readingTime":1713094583,"wNow":139.9,"whLifetime":83512.512,"varhLeadLifetime":110707.133,"varhLagLifetime":-55847.188,"vahLifetime":280513.318,"rmsCurrent":0.471,"rmsVoltage":699.438,"reactPwr":-247.726,"apprntPwr":109.172,"pwrFactor":1.0,"whToday":5345.512,"whLastSevenDays":12151.512,"vahToday":17978.318,"varhLeadToday":5247.133,"varhLagToday":0.0},{"type":"eim","activeCount":1,"measurementType":"net-consumption","readingTime":1713094583,"wNow":-4306.077,"whLifetime":-90186.497,"varhLeadLifetime":110728.131,"varhLagLifetime":2053.693,"vahLifetime":280513.318,"rmsCurrent":-17.934,"rmsVoltage":699.438,"reactPwr":-514.29,"apprntPwr":-4180.388,"pwrFactor":-1.0,"whToday":0,"whLastSevenDays":0,"vahToday":0,"varhLeadToday":0,"varhLagToday":0}],"storage":[{"type":"acb","activeCount":0,"readingTime":0,"wNow":0,"whNow":0,"state":"idle"}]}
2024.04.14 13:36:38.683 5: Enphase (MEIN-DEVICE-NAME): ==> Error:
2024.04.14 13:36:38.683 5: Enphase (MEIN-DEVICE-NAME): ==> ReturnCode: 200
2024.04.14 13:36:38.684 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: 1713094583
2024.04.14 13:36:38.684 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: 14
2024.04.14 13:36:38.684 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: 14
2024.04.14 13:36:38.685 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: Sun Apr 14 13:36:23 2024
2024.04.14 13:36:39.689 4: Enphase (MEIN-DEVICE-NAME): ==> start newlive
2024.04.14 13:36:39.942 5: Enphase (MEIN-DEVICE-NAME): ==> header: HTTP/1.1 200 OK
Server: openresty/1.17.8.1
Date: Sun, 14 Apr 2024 11:36:24 GMT
Content-Length: 3515
Connection: close
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
2024.04.14 13:36:39.942 5: {
    "connection": {
        "mqtt_state": "connected",
        "prov_state": "configured",
        "auth_state": "ok",
        "sc_stream": "enabled",
        "sc_debug": "disabled"
    },
    "meters": {
        "last_update": 1713094584,
        "soc": 100,
        "main_relay_state": 1,
        "gen_relay_state": 5,
        "backup_bat_mode": 1,
        "backup_soc": 0,
        "is_split_phase": 0,
        "phase_count": 3,
        "enc_agg_soc": 100,
        "enc_agg_energy": 3500,
        "acb_agg_soc": 0,
        "acb_agg_energy": 0,
        "pv": {
            "agg_p_mw": 2740309,
            "agg_s_mva": 2756464,
            "agg_p_ph_a_mw": 966102,
            "agg_p_ph_b_mw": 990604,
            "agg_p_ph_c_mw": 783602,
            "agg_s_ph_a_mva": 971470,
            "agg_s_ph_b_mva": 995988,
            "agg_s_ph_c_mva": 789006
        },
        "storage": {
            "agg_p_mw": 0,
            "agg_s_mva": 0,
            "agg_p_ph_a_mw": 0,
            "agg_p_ph_b_mw": 0,
            "agg_p_ph_c_mw": 0,
            "agg_s_ph_a_mva": 0,
            "agg_s_ph_b_mva": 0,
            "agg_s_ph_c_mva": 0
        },
        "grid": {
            "agg_p_mw": -2572318,
            "agg_s_mva": -2642358,
            "agg_p_ph_a_mw": -805104,
            "agg_p_ph_b_mw": -994369,
            "agg_p_ph_c_mw": -772847,
            "agg_s_ph_a_mva": -858777,
            "agg_s_ph_b_mva": -999773,
            "agg_s_ph_c_mva": -783809
        },
        "load": {
            "agg_p_mw": 167991,
            "agg_s_mva": 114106,
            "agg_p_ph_a_mw": 160998,
            "agg_p_ph_b_mw": -3765,
            "agg_p_ph_c_mw": 10755,
            "agg_s_ph_a_mva": 112693,
            "agg_s_ph_b_mva": -3785,
            "agg_s_ph_c_mva": 5197
        },
        "generator": {
            "agg_p_mw": 0,
            "agg_s_mva": 0,
            "agg_p_ph_a_mw": 0,
            "agg_p_ph_b_mw": 0,
            "agg_p_ph_c_mw": 0,
            "agg_s_ph_a_mva": 0,
            "agg_s_ph_b_mva": 0,
            "agg_s_ph_c_mva": 0
        }
    },
    "tasks": {
        "task_id": -119047617,
        "timestamp": 1713091542
    },
    "counters": {
        "main_CfgLoad": 1,
        "main_CfgChanged": 1,
        "main_taskUpdate": 77,
        "MqttClient_publish": 73561,
        "MqttClient_respond": 626,
        "MqttClient_msgarrvd": 314,
        "MqttClient_create": 128,
        "MqttClient_setCallbacks": 128,
        "MqttClient_connect": 128,
        "MqttClient_connect_err": 110,
        "MqttClient_connect_Err": 110,
        "MqttClient_subscribe": 18,
        "SSL_Keys_Create": 128,
        "sc_hdlDataPub": 324750,
        "sc_SendStreamCtrl": 313,
        "sc_SendDemandRspCtrl": 1,
        "rest_Status": 21214
    },
    "dry_contacts": {
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "\u0006",
            "dry_contact_status": 3051860
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3051860
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3051860
        },
        "": {
            "dry_contact_id": "",
            "dry_contact_type": "",
            "dry_contact_load_name": "",
            "dry_contact_status": 3051860
        }
    }
}
2024.04.14 13:36:39.942 5: Enphase (MEIN-DEVICE-NAME): ==> Error:
2024.04.14 13:36:39.942 5: Enphase (MEIN-DEVICE-NAME): ==> ReturnCode: 200
2024.04.14 13:36:39.944 5: Enphase (MEIN-DEVICE-NAME): ==> Daten zu alt
2024.04.14 13:36:39.945 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: 1713094584
2024.04.14 13:36:39.945 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: 1713094599.94315
2024.04.14 13:36:39.945 5: Enphase (MEIN-DEVICE-NAME): ==> Readingtime: 15
Gruß Olaf

Christian83

Hallo Olaf,

setze mal das Attribut
readingtimevariancesec - Zeitversatz in Sekunden zwischen lokaler Zeit und Gateway (default 15)

Du bist knapp über den 15 Sekunden.

Gruß,

Christian

Der Olaf

Hallo Christian,
danke für den Tip / Hinweis. Jetzt funktioniert es.
Ich habe das Attribut readingtimevariancesec auf 30 (Sekunden) gestellt.
Damit sollte genug "Reserve" vorhanden sein.
Ich werde das jetzt mal weiter beobachten.
Noch einen schönen Restsonntag.
Gruß Olaf