Envertech Balkonkraftwerk

Hallo zusammen,

ich habe seit ein paar Tagen eine kleine Solaranlage mit einem Modulwechselrichter von Envertech.
Die haben ein ganz gutes Portal wo man die Daten einsehen kann.

Dafür notwendig ist die sogenannte Enverbridge.

Ich möchte diese Daten ganz gerne im IP-Symcon haben um diese weiter zu verarbeiten.

Allerdings gibt es bisher nichts für IP-Symcon, nur für IOBroker etc.

Zum einen:
GitHub - tkanerva/enver-cloud-access: python libs for API access for envertec cloud, for fetching the current panel production etc

und
GitHub - adcrafter27/ioBroker.envertech-pv: Read Envertech.com Web data

Sind zwei verschiedene Ansätze um an die Daten zu kommen.

Daher meine Frage, hat jemand bei sich schon so etwas am laufen oder kann mir sagen wie ich diese Daten Richtung IP-Symcon bekomme?

Danke euch!

Hallo,
ich habe es anders gemacht, da ich keinen Bock auf die Cloud habe.
Ein ShellyEM an die Zuleitung zum Wechselrichter und die Daten dann per MQTT direkt nach Symcon.
Damit bin ich zufrieden, läuft jetzt 1,5 Monate,

Hallo @TheOnlyOne, ich hab gerade eine Anlage mit einem EVT300 und einem EVT1200, also 5 PV-Modulen gebaut. Zusätzlich habe ich noch die Bridge BVB202.
Die Bridge spielt die Daten so alle 80 Sekunden in die Cloud.
Ich hab mir in IP-Symcon ein Script geschrieben um die Daten alle Minute aus der Cloud abzuholen und in IPS zu speichern.
Diese Vorgehensweise hat halt den Vorteil, das man von jedem Modul alle Daten erhällt.
Falls du interesse hast, kann ich dir das Script geben.
Gruß Schuggi

PS: Falls man die Anlaga mit der 70% Abregelung betreiben will (muß), so geht das auch über die Bridge. Dort kann man das einstellen und die überträgt es dann zu den WRs.

grafik

@Schuggi

Das wäre ja genial wenn du mir das Script zukommen lassen könntest. Ich habe bis dato immer noch keine Lösung gefunden :slight_smile:

Für das Script brauchst du deine StationID.
Die bekommst du wie folgt:
Logge dich im Envertechportal ein und schau dir den Quelltext der Hauptseite an.

Da findest du dann eine Stelle wo die ID drinsteht.
grafik

Ich hatte in meinem Script erst auch einen Login implementiert, ich hab aber festgestellt, das man den nicht braucht. Anscheinen reicht die Station ID.

Ich hab mal mein Script auf das wesentliche abgespeckt. Ich hoffe dabei ist mir kein Fehler reingerutscht.
Hier der Code. Die Varablen musst du vorher per Hand anlegen und dann die IDs ins Script eintragen. Oben muss die StationID rein.

<?php
$id="C3F04875EXXXXXXXXXXXXXXXXXX";

$ch = curl_init();

curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_POST,1);

curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

echo "*******************\n";
echo "  RealData Abfragen\n";
echo "*******************\n";

curl_setopt($ch, CURLOPT_URL,"https://www.envertecportal.com/ApiInverters/QueryTerminalReal?page=1&perPage=20&orderBy=GATEWAYSN&whereCondition=%7B%22STATIONID%22%3A%22$id%22%7D");

$headers = array( "POST /ApiStations/GetDevices HTTP/1.1",
                  "Host: www.envertecportal.com",
                  "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0",
                  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
                  "Accept-Language: de,en-US;q=0.7,en;q=0.3",
                  "Accept-Encoding: gzip, deflate, br",
                  "Connection: keep-alive",
                  "Referer: https://www.envertecportal.com/terminal/systemreal",
                  "Upgrade-Insecure-Requests: 1",
        );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 


$ret = curl_exec($ch);
$data = json_decode($ret);
print_r($data);
if(count($data->Data->QueryResults)==5)
{
  $P = 0;
  // EVT300
  $P += Werte_Setzen(1,58938,15849,16659,24042,49761,45815,47458);
  // EVT1200-1
  $P += Werte_Setzen(0,31423,10375,27361,53787,37214,17018,30879);
  // EVT1200-2
  $P += Werte_Setzen(2,19945, 15473, 59539, 55830,  17815,  56746, 37005);
  // EVT1200-3
  $P += Werte_Setzen(4,28047,20965,14809,15698,16388,33617,17410);
  // EVT1200-4
  $P += Werte_Setzen(3,56017,11574,14140,45193, 45551, 40751, 46254);

  SetValueFloat(44305,$P);
  SetValueFloat(36651,$data->Data->QueryResults[0]->ENERGY+$data->Data->QueryResults[1]->ENERGY+$data->Data->QueryResults[2]->ENERGY+$data->Data->QueryResults[3]->ENERGY+$data->Data->QueryResults[4]->ENERGY);
  SetValueFloat(11520,$data->Data->QueryResults[0]->DAYENERGY+$data->Data->QueryResults[1]->DAYENERGY+$data->Data->QueryResults[2]->DAYENERGY+$data->Data->QueryResults[3]->DAYENERGY+$data->Data->QueryResults[4]->DAYENERGY);
}
curl_close($ch);


function Werte_Setzen($Index,$ID_DC,$ID_AC,$ID_P,$ID_A,$ID_TA,$ID_T,$ID_N)
{
  global $data;
  
  $st = $data->Data->QueryResults[$Index]->STATUS;
  SetValueFloat($ID_DC,($st==0)?  $data->Data->QueryResults[$Index]->DCVOLTAGE:0);
  SetValueFloat($ID_AC,($st==0)? $data->Data->QueryResults[$Index]->ACVOLTAGE:0);
  SetValueFloat($ID_P,($st==0)? $data->Data->QueryResults[$Index]->POWER:0);
  SetValueFloat($ID_A, $data->Data->QueryResults[$Index]->ENERGY);
  SetValueFloat($ID_TA, $data->Data->QueryResults[$Index]->DAYENERGY);
  SetValueFloat($ID_T,($st==0)?  $data->Data->QueryResults[$Index]->TEMPERATURE:0);
  SetValueString($ID_N, $data->Data->QueryResults[$Index]->SNALIAS);
  Return ($st==0)? $data->Data->QueryResults[2]->POWER:0;
}

Unter welchem Betriebssystem läuft dein IP-Symcon. Eventuell müsste man da noch was im Quelltext anpassen. Mein IPS läuft unter Win10.

Gib mir Bescheid, ob es bei dir funktioniert.

Gruß Schuggi

Danke für die Anleitung. Zumindestens bekomme ich über das Script schon mal die Daten meiner zwei Module. Nur leider werden die Variablen nicht nicht gefüttert:

*******************
  RealData Abfragen
*******************
stdClass Object
(
    [Status] => 0
    [Result] => 
    [Data] => stdClass Object
        (
            [QueryResults] => Array
                (
                    [0] => stdClass Object
                        (
                            [GATEWAYALIAS] => 90023860
                            [GATEWAYSN] => 90023860
                            [SNALIAS] => 20121366
                            [SN] => 20121366
                            [DCVOLTAGE] => 35.87
                            [ACVOLTAGE] => 240.88
                            [ACCURRENCY] => 0
                            [POWER] => 107.31
                            [FREQUENCY] => 50
                            [DAYENERGY] => 0.12
                            [ENERGY] => 86.05
                            [TEMPERATURE] => 16.4
                            [SITETIME] => 3/16/2021 11:25:18 AM
                            [STATIONID] => 
                            [STATUS] => 0
                            [SNID] => 23BCA7F10B7745E4B2EFEE9170686445
                        )

                    [1] => stdClass Object
                        (
                            [GATEWAYALIAS] => 90023860
                            [GATEWAYSN] => 90023860
                            [SNALIAS] => 20121367
                            [SN] => 20121367
                            [DCVOLTAGE] => 35.84
                            [ACVOLTAGE] => 240.91
                            [ACCURRENCY] => 0
                            [POWER] => 109.81
                            [FREQUENCY] => 50
                            [DAYENERGY] => 0.15
                            [ENERGY] => 89
                            [TEMPERATURE] => 16.8
                            [SITETIME] => 3/16/2021 11:25:18 AM
                            [STATIONID] => 
                            [STATUS] => 0
                            [SNID] => AAB2E5EC5DB448609566719475453168
                        )

                )

            [PageNumber] => 1
            [PerPage] => 20
            [TotalPage] => 1
            [TotalCount] => 2
            [Lan] => en-us
        )

)

Das Script habe ich wie folgt angepasst. Vorerst einmal für das erste Modul

<?php
$id="E47CA1FB5BD14xxxx";

$ch = curl_init();

curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_POST,1);

curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookieFileName");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

echo "*******************\n";
echo "  RealData Abfragen\n";
echo "*******************\n";

curl_setopt($ch, CURLOPT_URL,"https://www.envertecportal.com/ApiInverters/QueryTerminalReal?page=1&perPage=20&orderBy=GATEWAYSN&whereCondition=%7B%22STATIONID%22%3A%22$id%22%7D");

$headers = array( "POST /ApiStations/GetDevices HTTP/1.1",
                  "Host: www.envertecportal.com",
                  "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0",
                  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
                  "Accept-Language: de,en-US;q=0.7,en;q=0.3",
                  "Accept-Encoding: gzip, deflate, br",
                  "Connection: keep-alive",
                  "Referer: https://www.envertecportal.com/terminal/systemreal",
                  "Upgrade-Insecure-Requests: 1",
        );
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 


$ret = curl_exec($ch);
$data = json_decode($ret);
print_r($data);
if(count($data->Data->QueryResults)==5)
{
  $P = 0;
  // EVT300
  $P += Werte_Setzen(1,49468,39096,30433,54155,28835,43571,35888);
  

  SetValueFloat(47115,$P);
  SetValueFloat(24367,$data->Data->QueryResults[0]->ENERGY+$data->Data->QueryResults[1]->ENERGY+$data->Data->QueryResults[2]->ENERGY+$data->Data->QueryResults[3]->ENERGY+$data->Data->QueryResults[4]->ENERGY);
  SetValueFloat(35820,$data->Data->QueryResults[0]->DAYENERGY+$data->Data->QueryResults[1]->DAYENERGY+$data->Data->QueryResults[2]->DAYENERGY+$data->Data->QueryResults[3]->DAYENERGY+$data->Data->QueryResults[4]->DAYENERGY);
}
curl_close($ch);


function Werte_Setzen($Index,$ID_DC,$ID_AC,$ID_P,$ID_A,$ID_TA,$ID_T,$ID_N)
{
  global $data;
  
  $st = $data->Data->QueryResults[$Index]->STATUS;
  SetValueFloat($ID_DC,($st==0)?  $data->Data->QueryResults[$Index]->DCVOLTAGE:0);
  SetValueFloat($ID_AC,($st==0)? $data->Data->QueryResults[$Index]->ACVOLTAGE:0);
  SetValueFloat($ID_P,($st==0)? $data->Data->QueryResults[$Index]->POWER:0);
  SetValueFloat($ID_A, $data->Data->QueryResults[$Index]->ENERGY);
  SetValueFloat($ID_TA, $data->Data->QueryResults[$Index]->DAYENERGY);
  SetValueFloat($ID_T,($st==0)?  $data->Data->QueryResults[$Index]->TEMPERATURE:0);
  SetValueString($ID_N, $data->Data->QueryResults[$Index]->SNALIAS);
  Return ($st==0)? $data->Data->QueryResults[2]->POWER:0;
}

?>

Siehst du einen Fehler?

grafik
Die 1 ist der Index in das Ergebnisarray und die fangen immer bei 0 an.
Also trag hier mal eine 0 ein!

und diese 3 Variablen musst du noch anlegen oder den Code auskommentieren.
grafik

habe ich gemacht, ändert aber nichts.
Bekomme im HTML auch eine Fehlermeldung zurück:

******************* RealData Abfragen ******************* stdClass Object ( [Status] => 0 [Result] => [Data] => stdClass Object ( [QueryResults] => [PageNumber] => 1 [PerPage] => 20 [TotalPage] => 0 [TotalCount] => 0 [Lan] => en-us ) )
Warning: count(): Parameter must be an array or an object that implements Countable in C:\ProgramData\Symcon\scripts\20186.ips.php on line 35

danke der Hilfe von @Schuggi läuft das Script jetzt ohne Probleme. Zum einen musste ich in der Zeile 36

if(count($data->Data->QueryResults)==2)

den Index auf 2 ändern bei mir. Ich habe 2x Module und nicht 5 wie Schuggi.

Zum anderen muss man beim anlegen der Variablen auf den richtigen Typ (float und string) achten sowie die richtige Reihenfolge. Dann klappt es auch :slight_smile:

Mir ist noch ein grober Fehler aufgefallen!

function Werte_Setzen($Index,$ID_DC,$ID_AC,$ID_P,$ID_A,$ID_TA,$ID_T,$ID_N)
{
  global $data;
  
  $st = $data->Data->QueryResults[$Index]->STATUS;
  SetValueFloat($ID_DC,($st==0)?  $data->Data->QueryResults[$Index]->DCVOLTAGE:0);
  SetValueFloat($ID_AC,($st==0)? $data->Data->QueryResults[$Index]->ACVOLTAGE:0);
  SetValueFloat($ID_P,($st==0)? $data->Data->QueryResults[$Index]->POWER:0);
  SetValueFloat($ID_A, $data->Data->QueryResults[$Index]->ENERGY);
  SetValueFloat($ID_TA, $data->Data->QueryResults[$Index]->DAYENERGY);
  SetValueFloat($ID_T,($st==0)?  $data->Data->QueryResults[$Index]->TEMPERATURE:0);
  SetValueString($ID_N, $data->Data->QueryResults[$Index]->SNALIAS);
  Return ($st==0)? $data->Data->QueryResults[2]->POWER:0;
}

In der Zeile mit dem „Return“ muss „$Index“ statt der „2“ rein!

 Return ($st==0)? $data->Data->QueryResults[$Index]->POWER:0;

Hallo Zusammen,
ich habe seit heute auch eine Envertech Anlage. Leider blicke ich bei euren Skripten da nicht ganz durch.
Muss man hier jede Variabel für jedes Modul per Hand anlegen?
Wisst ihr ob es evlt. etwas einfacheres gibt? über Github oder den Store :slight_smile:

danke.

Hallo @Dustin723,
mittlerweile habe ich ein Modul für die Envertech-Anlagen entwickelt.
Voraussetzung ist das eine Bridge verbaut ist (EVB202 oder EVB300 oder …) , die die Daten in das Envertechportal übermittelt.

Download weiter unten!

Installation 1:
Den Ordner musst du ins Verzeichnis „modules“ von deinem IPS auspacken.
Dann gibst du in der Schnellausführung der Console folgendes ein:
MC_ReloadModule(IDmodules,“Envertech“);
grafik
(Die vordere ID mus die ID von deiner Instanz „modules“ rein
grafik

Installation 2: (alternativ zu 1)
Den Ordner musst du ins Verzeichnis „modules“ von deinem IPS auspacken.
IPS neu starten!

grafik

„Envertech“ brauchst du ein mal. Da kommt die Station ID rein.
(Die StationID steht im Quelltext vom Envertechportal)

„Envertech_MI“ brauchst du pro Wechselrichter ein mal. Da kommt die SN des WR rein.
„Enmvertech_PV“ brauchst du ein mal. Da kommt die SN deiner Bridge rein.

„Envertech“ holt die Daten ab und verteilt sie. Hier kannst du auch einstellen welche Variablen in den anderen Komponenten automatisch angelegt werden. (Taucht unter Splitter auf)

„Envertech_MI“ bekommt die Daten eines MI (Modulinverters oder auch Wechslerichter)
„Envertech_PV“ sammelt die Daten der ganzen Anlage.

Bin mal gespannt, ob das bei euch gleich läuft!

Das sollte dann so aussehen:
grafik

grafik

Zusätzlich ist in dem Modul noch eine Ertragsanzeige:

grafik

die sieht im Webfront dann so aus.

grafik
Diese Anzeige ist unabhängig von einer Envertech-Anlage und braucht nur eine Variable in der die Leistung steht und eine Variable in der die Arbeit der Anlage steht. Bei der Variable der Arbeit muss das Logging als Zähler aktiviert sein. Die Darstellung erfolgt als HTML.

Das ist mein erstes IP-Symcon Modul.
Daher habt etwas Nachsicht :grin:

Gruß
Schuggi

@Dustin723
Welchen Envertech Wechselrichter und Bridge hats du denn.

1 „Gefällt mir“

Hi @Schuggi,

sieht ja schon mal gega gut aus!!
Den Evertech mit ID konnte ich erstellen, hier sagt er bei Portdatenlesen " OK! - 4 MIs gelesen!"

wenn ich dann aber „Envertech_MI“ oder „Envertech_PV“ erstellen möchte kommt die Meldung (siehe unten).
Unser Splitter kann ich den leider nicht erstellen, wenn ich dort etwas erstellen möchte zeigt er den Envertech nicht in der Auswahl an.

Konnte Instanz nicht erstellen


Warning: Geräte/Konfigurator/Discovery/Visualisierung/Splitter Instanzen können nur zu anderen Splitter oder I/O Instanzen verbunden werden in C:\ProgramData\Symcon\modules\Envertech\Envertech_MI\module.php on line 12

(Code: -32603)

Ich habe den EVB300 mit EVT300S, dazu 4 Module.

Welche IPS version hast du?
Ich versteh nicht warum das bei dir nicht geht da ich das ja jetzt schon seit Wochen bei mir am laufen habe.
Ich kümmere mich darum indem ich mal die Experten frage.
Ich melde mich dann wieder.
Falls es möglich wäre könntest du IPS mal neu starten und schauen, ob es dann geht?

Gruß Schuggi

Hab die neuste IPS Version (am WE das Update installiert).

Neustart von IPS hatte ich schon gemacht, weil das mit dem Module Reload nicht geklappt hat, da sagte er das es kein Envertech Modul gibt, vermutlich geht das erst wenn es einmal drin ist.

ich danke Dir!

Nein, das muss gleich gehen. Bist du sicher, das du das an die richtige Stelle kopiert hast?

Der ausgepackte Ordner muss hier rein:
C:\ProgramData\Symcon\modules
Das sollte dann so aussehen!
grafik

Hast du eventuell einen Ordner zu viel dazwischen?

Im Modul Control
grafik

Muss das dann so aussehen!

HI, korrekt, so sieht es bei mir aus.

Aber ich habe auch keine Splitter (unter Splitter), brauche ich da nicht einen?

Nein, das Modul braucht keinen Splitter.
Ich schau mal was ich rausfinde und melde mich dann wieder.

1 „Gefällt mir“