Inhaltsverzeichnis
Shelly Pro 3EM Emulator
Quellen
- TasmoCompiler - all in one compiler suite based on Docker container with comfortable web gui
Home Brew Tasmota
Um eine eigene Version des Tasmota Firmware für einen ESP8266 oder ESP32 kompilieren zu könne benötigt man nicht nur den Tasmota Quellcode und alle notwendigen Bibliotheken sonder natürlich auch die Tool chain.
Das Aufsetzten der Entwicklungsumgebung inkl. Compiler ist nicht unbedingt eine 1-klick Installation daher habe ich mich für das All-In-One Paket TasmoCompiler entschieden.
Der TasmoCompiler kann am einfachsten als Docker Container verwendet werden. Wer z.B. eine Synology DiskStation sein Eigen nennt kann mit Hilde des Container Manager einfach den TasmoCompiler als Docker Image installieren.
Die folgenden Screenshots zeigen den sehr kurzen Weg zur Home-Brew Tasmota Firmware mit einem ganz eigenen Feature-Set:
Tasmota Quellcode herunterladen oder vorhandenen Stand aktualisieren:

WLAN SSID und Schlüssel konfigurieren:

EPS Modell und benötigte Funktionen auswählen:

Tasmota Version und Sprache auswählen und Kompiliervorgang starten::

Nach erfolgreicher Kompilierung wird die erstellte Firmware zum Download angeboten:

Das fertige Firmware Image tasmota32s3.factory_15_1_0_homebrew.bin kann auf den ESP32 z.B. via Tasmota Web Installer programmiert werden.

Der Lesekopf
Verbindung zwischen ESP32 und TTL Lesekopf:
| Funktion | ESP32 Pin | Lesekopf Pin |
|---|---|---|
| VCC: 3,3 V | 3V3 | 3V3 |
| GND | GND | GND |
| Daten Senden | 43 | Tx |
| Daten Empfangen | 44 | Rx |
Einfacher Lesetest
Um das Lesen der Zählerdaten zu testen kann das folgende Skript verwendet werden.
Zu beachten ist unbedingt die korrekte Konfiguration der Tx und RX Pins am ESP32 S3 Mini.
>D >B ->sensor53 r >M 1 +1,44,s,16,9600,SGM,43 1,77070100010800ff@1000,Verbrauch,kWh,E_in,3 1,77070100020800ff@1000,Einspeisung,kWh,E_out,3 1,77070100100700ff@1,akt. Leistung,W,Power,0 1,=h---- 1,77070100600100ff@#,Server-ID,,ID,0 #
Das Shelly Pro 3EM Emulator Script
EFR SGM-D4 Konfiguration
>D 250 ; this script emulates a shelly pro, with small modifications may also emulate an ecotracker ; proven to work an marstek Venus, Jupiter and B2500 res=0 c1p=0 c2p=0 c3p=0 c1c=0 c2c=0 c3c=0 cpwr=0 str="" tstr="" cstr="" mstr1="" mstr2="" mstr3="" header="" once=0 >B =>sensor53 r ; if you modify this section you must restart tasmota >ah ; http rpc handler res=won(1 "/rpc/*") ; http status res=won(2 "/status") ; http ecotacker status res=won(3 "/v1/json") >on1 ;print here comes http rpc request str=warg res=ins(str "EM.GetStatus") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc wcs %header% =#getstat wcs %mstr1% wcs %mstr2% wcf break } res=ins(str "Shelly.GetDeviceInfo") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc =#getdefi wcs %header% wcs %mstr1% wcs %mstr2% wcf break } res=ins(str "EM.GetConfig") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc =#getcfg wcs %header% wcs %mstr1% wcf break } res=ins(str "EMData.GetStatus") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc =#egetstat wcs %header% wcs %mstr1% wcf break } print unknown http equest: %str% >on2 ;print here comes the status request wcs so(4) =#htph wcs %mstr1% dp(0 2) wcs {"Power": %cpwr%,"E_in":%sml[1]%,"E_out":%sml[2]%} wcf >on3 ;print here comes the v1/json for ecotracker wcs so(4) =#htph wcs %mstr1% dp(0 2) wcs {"energyCounterIn":%sml[1]%,"energyCounterOut":%sml[2]%,"powerAvg":%cpwr%,"energyCounterInT1":0, wcs "energyCounterInT2":0,"power":%cpwr%} wcf #htph mstr1="HTTP/1.1 200 OK\r\nContent-type: application/json\r\n\r\n" #getcfg mstr1="{\"id\":0,\"name\":null,\"blink_mode_selector\":\"active_energy\",\"phase_selector\":\"a\",\"monitor_phase_sequence\":true,\"ct_type\":\"120A\"}}" #getdefi mstr1="{\"name\":\""+tstr+"\",\"id\":\""+tstr+"\",\"mac\":\""+maca+"\",\"slot\":1,\"model\":\"SPEM-003CEBEU\"," mstr2="\"gen\":2,\"fw_id\":\"20241011-114455/1.4.4-g6d2a586\"," mstr2+="\"ver\":\"1.4.4\",\"app\":\"Pro3EM\",\"auth_en\":0,\"profile\":\"triphase\"}}" #getstat dp(0 2) mstr1="{\"id\":0,\"a_current\":"+s(c1c)+",\"a_voltage\":230,\"a_act_power\":"+s(c1p)+",\"a_aprt_power\":"+s(c1p)+",\"a_pf\":1,\"a_freq\":50," mstr1+="\"b_current\":"+s(c2c)+",\"b_voltage\":230,\"b_act_power\":"+s(c2p)+",\"b_aprt_power\":"+s(c2p)+",\"b_pf\":1,\"b_freq\":50," mstr2="\"c_current\":"+s(c3c)+",\"c_voltage\":230,\"c_act_power\":"+s(c3p)+",\"c_aprt_power\":"+s(c3p)+",\"c_pf\":1,\"c_freq\":50," mstr2+="\"total_current\":"+s(c1c+c2c+c3c)+",\"total_act_power\":"+s(cpwr)+",\"total_aprt_power\":"+s(cpwr)+"}}" #egetstat dp(0 2) mstr1="{\"id\":0,\"a_total_act_energy\":"+s(c1p)+",\"a_total_act_ret_energy\":"+s(c1p)+",\"b_total_act_energy\":"+s(c2p)+",\"b_total_act_ret_energy\":"+s(c2p)+",\"c_total_act_energy\":"+s(c3p)+",\"c_total_act_ret_energy\":"+s(c3p)+",\"total_act\":"+s(cpwr)+",\"total_act_ret\":"+s(cpwr)+"}}" #getsrc tstr="shellypro3em-"+maca header="{\"id\":0,\"src\":\""+tstr+"\",\"result\":" >S if year<2000 { break } ; adapt this to your meter ; update every 3 seconds if upsecs%3==0 { cpwr=sml[3] c1p=sml[4] c2p=sml[5] c3p=sml[6] } ; use this if you only have only one phase meter values ;c1p=cpwr/3 ;c2p=cpwr/3 ;c3p=cpwr/3 ; calculate phase currents c1c=c1p/230 c2c=c2p/230 c3c=c3p/230 if once==0 { ; start mdns for Shelly second parameter "-" means use device mac res=mdns("shellypro3em-" "-" "shelly") ; start udp rpc handler on port 1010 or on port 2220 (for b2500) res=udp(0 1010) ;res=udp(0 2220) once=1 } ; evaluate udp input str=udp(1) if str!="" { ;print udp rpc payload=%str% res=ins(str "EM.GetStatus") if res>=0 { =#getsrc =#getstat udp(2 header mstr1 mstr2) ;print >> %header% ;print >> %mstr1% ;print >> %mstr2% break } res=ins(str "Shelly.GetDeviceInfo") if res>=0 { =#getsrc =#getdefi udp(2 header mstr1 mstr2) ;print >> 1 %mstr1% ;print >> 2 %mstr2% break } res=ins(str "EM.GetConfig") if res>=0 { =#getsrc =#getcfg udp(2 header mstr1) ;print >> 1 %mstr1% break } res=ins(str "EMData.GetStatus") if res>=0 { =#getsrc =#egetstat udp(2 header mstr1) ;print >> 1 %mstr1% break } } ; adapt your own meter descriptor here ;>M 1 ;+1,5,o,16,9600,eBZ,4 ;1,1-0:1.8.0*255(@1,Verbrauch,kWh,E_in,3 ;1,1-0:2.8.0*255(@1,Einspeisung,kWh,E_out,3 ;1,1-0:16.7.0*255(@1,akt. Leistung,W,Power,0 ;1,1-0:36.7.0*255(@1,Leistung L1,W,36_7_0,0 ;1,1-0:56.7.0*255(@1,Leistung L2,W,56_7_0,0 ;1,1-0:76.7.0*255(@1,Leistung L3,W,76_7_0,0 ;1,1-0:32.7.0*255(@1,Spannung L1,V,32_7_0,1 ;1,1-0:52.7.0*255(@1,Spannung L2,V,52_7_0,1 ;1,1-0:72.7.0*255(@1,Spannung L3,V,72_7_0,1 ;1,1-0:96.1.0*255(@#),Identifikation,,96_1_0,0 ;>M 1 ;+1,44,s,16,9600,SML,43 ;1,77070100010800ff@1000,Verbrauch,kWh,E_in,3 ;1,77070100020800ff@1000,Einspeisung,kWh,E_out,3 ;1,77070100100700ff@1,akt. Leistung,W,Power,0 ;1,=h---- ;1,77070100600100ff@#,Identifikation,,96_1_0,0 >M 1 +1,44,s,0,9600,SGM-D4,43 1,77070100010800FF@1000,Zählerstand,kWh,E_in,3 1,77070100020800FF@1000,Einspeisung,kWh,E_out,3 1,77070100100700FF@1000,akt. Leistung,kW,Power,3 1,770701000E0700FF@1,Netzfrequenz,Hz,netzfrequenz,1 1,77070100200700FF@1,Phasenspannung L1,V,momentanspannung_l1,1 1,770701001F0700FF@1,Phasenstrom L1,A,momentanstrom_l1,2 1,77070100240700FF@1000,Wirkleistung L1,kW,summenwirkleistung_l1,3 1,77070100340700FF@1,Phasenspannung L2,V,momentanspannung_l2,1 1,77070100330700FF@1,Phasenstrom L2,A,momentanstrom_l2,2 1,77070100380700FF@1000,Wirkleistung L2,kW,summenwirkleistung_l2,3 1,77070100480700FF@1,Phasenspannung L3,V,momentanspannung_l3,1 1,77070100470700FF@1,Phasenstrom L3,A,momentanstrom_l3,2 1,770701004C0700FF@1000,Wirkleistung L3,kW,summenwirkleistung_l3,3 #
>D 250 M:p:sday=0 288 M:p:dcon=0 31 M:p:dprod=0 31 M:p:mcon=0 24 M:s4h=0 481 p:mval=0 p:dval=0 p:mval2=0 p:dval2=0 p:yval=0 p:yval2=0 p:da=1 t:t1=3 t:t2=30 t:t3=60 tmp=0 m5=0 cstr="cnt0/12" cstr2="cnth0/120" utm="00d 00h 00m" avgv=0 avgv2=0 avgvc=0 avgvc2=0 hr=0 swesp=0 swespflg=0 power2=0 save=0 res=0 c1p=0 c2p=0 c3p=0 c1c=0 c2c=0 c3c=0 cpwr=0 str="" tstr="" mstr1="" mstr2="" header="" once=0 throttle=1 >B =>sensor53 r tmp=is(0 "Jan|Feb|Mär|Apr|Mai|Jun|Jul|Aug|Sep|Okt|Nov|Dez|") smlj=0 header="{\"id\":0,\"src\":\"shellypro3em-"+maca+"\",\"result\":" #init dval=sml[2] dval2=sml[3] for tmp 1 dcon[-1] 1 dcon[tmp]=0 dprod[tmp]=0 next mval=sml[2] mval2=sml[3] for tmp 1 mcon[-1] 1 mcon[tmp]=0 next yval=sml[2] yval2=sml[3] for tmp 1 sday[-1] 1 sday[tmp]=0 next ->Backlog2 otaurl KEIN OTA UPGRADE VIA WEBSERVER! ->Backlog2 Timezone 99;TimeStd 0,0,10,1,3,60;TimeDst 0,0,3,1,2,120 svars #daysub if wm>0 { wcs <div id="day" style="text-align:center;width:600px;height:400px"></div> wcs <script language="JavaScript">function drawChart(){ wcs var cssc={'headerRow':'hRow','rowNumberCell':'hCol','tableCell':'tCell'}; wcs var data=google.visualization.arrayToDataTable([['Tag','Energie [kWh]',{role: 'style'}], for tmp 1 dcon[-1] 1 if (tmp==day) { wcs [%tmp%,%dcon[tmp]%,'red'], } if (tmp<day) { wcs [%tmp%,%dcon[tmp]%,'green'], } if (tmp>day) { wcs [%tmp%,%dcon[tmp]%,''], } next wcs ]); wcs var options={chartArea:{left:40,right:30,height:'75%%'},legend:'none',title:'Tagesverbräuche (Monat %is[month]%)',vAxis:{format:'# kWh'},hAxis:{title:'Tag',ticks:[1,5,10,15,20,25,30]}}; wcs var chart=new google.visualization.ColumnChart(document.getElementById('day')); wcs chart.draw(data,options);}google.charts.setOnLoadCallback(drawChart);</script> } #dayprod if wm>0 { wcs <div id="dayp" style="text-align:center;width:600px;height:400px"></div> wcs <script language="JavaScript">function drawChart(){ wcs var cssc={'headerRow':'hRow','rowNumberCell':'hCol','tableCell':'tCell'}; wcs var data=google.visualization.arrayToDataTable([['Tag','Energie [kWh]',{role: 'style'}], for tmp 1 dprod[-1] 1 if (tmp==day) { wcs [%tmp%,%dprod[tmp]%,'red'], } if (tmp<day) { wcs [%tmp%,%dprod[tmp]%,'green'], } if (tmp>day) { wcs [%tmp%,%dprod[tmp]%,''], } next wcs ]); wcs var options={chartArea:{left:40,right:30,height:'75%%'},legend:'none',title:'Tageseinspeisung (Monat %is[month]%)',vAxis:{format:'# kWh'},hAxis:{title:'Tag',ticks:[1,5,10,15,20,25,30]}}; wcs var chart=new google.visualization.ColumnChart(document.getElementById('dayp')); wcs chart.draw(data,options);}google.charts.setOnLoadCallback(drawChart);</script> } #monthsub if wm>0 { wcs <div id="month" style="text-align:center;width:600px;height:400px"></div> wcs <script language="JavaScript">function drawChart(){ wcs var cssc={'headerRow':'hRow','rowNumberCell':'hCol','tableCell':'tCell'}; wcs var data=google.visualization.arrayToDataTable([['Monat','Verbrauch [kWh]','Einspeisung[kWh]'], for tmp 1 12 1 if (tmp<month) { wcs ['%is[tmp]%',%mcon[tmp]%,%mcon[tmp+12]%], } if (tmp==month) { wcs ['%is[tmp]%',%mcon[tmp]%,%mcon[tmp+12]%], } if (tmp>month) { wcs ['%is[tmp]%',%mcon[tmp]%,%mcon[tmp+12]%], } next wcs ]); wcs var options={series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}},chartArea:{left:40,right:40,height:'75%%'},legend:'none',title:'Verbräuche / Einspeisungen (Jahr %0(year-1)%/%0year%)',vAxes:{0:{format:'# kWh'},1:{format:'# kWh'}}}; wcs var chart=new google.visualization.ColumnChart(document.getElementById('month')); wcs chart.draw(data,options);}google.charts.setOnLoadCallback(drawChart);</script> } #getstat mstr1="{\"id\":0,\"a_current\":"+s(c1c)+",\"a_voltage\":230,\"a_act_power\":"+s(0c1p)+",\"a_aprt_power\":"+s(0c1p)+",\"a_pf\":1,\"a_freq\":50," mstr1+="\"b_current\":"+s(c2c)+",\"b_voltage\":230,\"b_act_power\":"+s(0c2p)+",\"b_aprt_power\":"+s(0c2p)+",\"b_pf\":1,\"b_freq\":50," mstr2="\"c_current\":"+s(c3c)+",\"c_voltage\":230,\"c_act_power\":"+s(0c3p)+",\"c_aprt_power\":"+s(0c3p)+",\"c_pf\":1,\"c_freq\":50," mstr2+="\"total_current\":"+s(c1c+c2c+c3c)+",\"total_act_power\":"+s(0cpwr)+",\"total_aprt_power\":"+s(0cpwr)+"}}" >S if (save==1) { save=0 svars } if ((year<2020) or (sml[2]==0)) { print auf NTP/Zähler warten break } smlj=1 if (t1==0) { t1=3 avgv+=sml[1] avgv2+=sml[1] avgvc+=1 avgvc2+=1 power2=(0.9*power2)+((1-0.9)*sml[1]) if (swesp==1) { if ((power2<-300) and (swespflg==0)) { swespflg=1 } if ((power2>100) and (swespflg==1)) { swespflg=0 } } } if (t2==0) { t2=30 s4h=avgv/avgvc avgv=0 avgvc=0 cstr2="cnth"+s(1.0((((hours+20)*120)+(mins*2)+(int(secs/30)))%2880+1))+"/120" } if (t3==0) { t3=60 hr=hours utm=s(2.0(int(uptime/1440)))+"d "+s(2.0(int(uptime/60)%24))+"h "+s(2.0(uptime%60))+"m" dcon[day]=sml[2]-dval mcon[month]=sml[2]-mval dprod[day]=sml[3]-dval2 mcon[month+12]=sml[3]-mval2 m5=int((((hours*60)+mins)/5)+1) sday[0]=m5 if (chg[m5]>0) { sday[m5]=int(avgv2/avgvc2) avgv2=0 avgvc2=0 } cstr="cnth"+s(1.0(((hours)*12)+int(mins/5))+1)+"/12" if ((chg[hr]>0) and (hr==0)) { if (day>1) { da=day } else { for tmp (da+1) 31 1 dprod[tmp]=0 dcon[tmp]=0 next mval=sml[2] mval2=sml[3] } if (day*month==1) { yval=sml[2] yval2=sml[3] } dval=sml[2] dval2=sml[3] svars } } if (once==0) { res=mdns("shellypro3em-" "-" "shelly") res=udp(0 2220) once=1 } if (upsecs%throttle!=0) { break; } tmp=sml[1]-cpwr if (tmp>500) { cpwr=sml[1]-(tmp/2) } else { cpwr=sml[1] } c1p=cpwr c1c=c1p/230 str=udp(1) if (str!="") { res=ins(str "EM.GetStatus") if (res>=0) { =#getstat udp(2 header mstr1 mstr2) break } } else { ;=#getstat ;udp(2 header mstr1 mstr2) } >W bu(save "gespeichert!" "Daten sofort speichern") Leistung (gefiltert){m}%0power2% W Leistung (an Marstek Akku){m}%0cpwr% W Tagesverbrauch{m}%2(sml[2]-dval)% kWh Monatsverbrauch{m}%2(sml[2]-mval)% kWh Jahresverbrauch{m}%2(sml[2]-yval)% kWh Tageseinspeisung{m}%2(sml[3]-dval2)% kWh Monatseinspeisung{m}%2(sml[3]-mval2)% kWh Jahreseinspeisung{m}%2(sml[3]-yval2)% kWh Datum{m}%s(2.0day)%.%s(2.0month)%.%s(2.0year)% - %s(2.0hours)%:%s(2.0mins)%:%s(2.0secs)% Uptime{m}%utm% $<div style="margin-left:-30px"> $<div id="chart1" style="text-align:center;width:600px;height:400px"></div> $gc(lt s4h "wr" "Leistung [W]" cstr2) $var options = { $chartArea:{left:60,right:20,height:'75%%'}, $legend:'none', $vAxis:{format:'# W'}, $hAxis:{slantedTextAngle:45}, $explorer:{actions:['dragToZoom','rightClickToReset']}, $series: {0: {type: 'area'}}, $title:'Leistung 4 Stunden [Watt]' $}; $gc(e) $<div id="chart2" style="text-align:center;width:600px;height:400px"></div> $gc(lt sday "wr" "Leistung [W]" cstr) $var options = { $chartArea:{left:60,right:20,height:'75%%'}, $legend:'none', $vAxis:{format:'# W'}, $hAxis:{slantedTextAngle:45}, $explorer:{actions:['dragToZoom', 'rightClickToReset']}, $series: {0: {type: 'area'}}, $title:'Leistung 24 Stunden [Watt]' $}; $gc(e) %=#daysub %=#dayprod %=#monthsub $<center><span style="font-size:10px;"> $Version 02.10.2025 (PV+ShellyEmu) by ottelo.jimdo.de<br> $Credits to gemu2015 (Tasmota Script Dev)<br> $Hinweis: Die Daten (ohne 4h Chart) werden um Mitternacht gespeichert!<br> $Der Restart Button speichert ebenfalls die Daten.<br> $</span></center></div> ;>M 1 ;+1,5,s,0,9600,MT175,4 ;1,77070100100700ff@1,Leistung,W,Power_curr,0 ;1,77070100010800ff@1000,Verbrauch,KWh,Total_in,2 ;1,77070100020800ff@1000,Einspeisung,KWh,Total_out,2 ;# >M 1 +1,44,s,0,9600,SGM-D4,43 1,77070100100700FF@1,akt. Leistung,W,Power_curr,0 ;;1,77070100010800FF@1000,Zählerstand,kWh,E_in,3 1,77070100010800FF@1000,Zählerstand,kWh,Total_in,2 ;1,77070100020800FF@1000,Einspeisung,kWh,E_out,3 1,77070100020800FF@1000,Einspeisung,kWh,Total_out,2 ;;1,77070100100700FF@1000,akt. Leistung,kW,Power,3 1,770701000E0700FF@1,Netzfrequenz,Hz,netzfrequenz,1 1,77070100200700FF@1,Phasenspannung L1,V,momentanspannung_l1,1 1,770701001F0700FF@1,Phasenstrom L1,A,momentanstrom_l1,2 1,77070100240700FF@1000,Wirkleistung L1,kW,summenwirkleistung_l1,3 1,77070100340700FF@1,Phasenspannung L2,V,momentanspannung_l2,1 1,77070100330700FF@1,Phasenstrom L2,A,momentanstrom_l2,2 1,77070100380700FF@1000,Wirkleistung L2,kW,summenwirkleistung_l2,3 1,77070100480700FF@1,Phasenspannung L3,V,momentanspannung_l3,1 1,77070100470700FF@1,Phasenstrom L3,A,momentanstrom_l3,2 1,770701004C0700FF@1000,Wirkleistung L3,kW,summenwirkleistung_l3,3 #
>D 250 ; this script emulates a shelly pro, with small modifications may also emulate an ecotracker ; proven to work an marstek Venus, Jupiter and B2500 res=0 c1p=0 c2p=0 c3p=0 c1c=0 c2c=0 c3c=0 cpwr=0 str="" tstr="" cstr="" mstr1="" mstr2="" mstr3="" header="" once=0 >B =>sensor53 r ; if you modify this section you must restart tasmota >ah ; http rpc handler res=won(1 "/rpc/*") ; http status res=won(2 "/status") ; http ecotacker status res=won(3 "/v1/json") >on1 ;print here comes http rpc request str=warg res=ins(str "EM.GetStatus") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc wcs %header% =#getstat wcs %mstr1% wcs %mstr2% wcf break } res=ins(str "Shelly.GetDeviceInfo") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc =#getdefi wcs %header% wcs %mstr1% wcs %mstr2% wcf break } res=ins(str "EM.GetConfig") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc =#getcfg wcs %header% wcs %mstr1% wcf break } res=ins(str "EMData.GetStatus") if res>=0 { wcs so(4) =#htph wcs %mstr1% =#getsrc =#egetstat wcs %header% wcs %mstr1% wcf break } print unknown http equest: %str% >on2 ;print here comes the status request wcs so(4) =#htph wcs %mstr1% dp(0 2) wcs {"Power": %cpwr%,"E_in":%sml[1]%,"E_out":%sml[2]%} wcf >on3 ;print here comes the v1/json for ecotracker wcs so(4) =#htph wcs %mstr1% dp(0 2) wcs {"energyCounterIn":%sml[1]%,"energyCounterOut":%sml[2]%,"powerAvg":%cpwr%,"energyCounterInT1":0, wcs "energyCounterInT2":0,"power":%cpwr%} wcf #htph mstr1="HTTP/1.1 200 OK\r\nContent-type: application/json\r\n\r\n" #getcfg mstr1="{\"id\":0,\"name\":null,\"blink_mode_selector\":\"active_energy\",\"phase_selector\":\"a\",\"monitor_phase_sequence\":true,\"ct_type\":\"120A\"}}" #getdefi mstr1="{\"name\":\""+tstr+"\",\"id\":\""+tstr+"\",\"mac\":\""+maca+"\",\"slot\":1,\"model\":\"SPEM-003CEBEU\"," mstr2="\"gen\":2,\"fw_id\":\"20241011-114455/1.4.4-g6d2a586\"," mstr2+="\"ver\":\"1.4.4\",\"app\":\"Pro3EM\",\"auth_en\":0,\"profile\":\"triphase\"}}" #getstat dp(0 2) mstr1="{\"id\":0,\"a_current\":"+s(c1c)+",\"a_voltage\":230,\"a_act_power\":"+s(c1p)+",\"a_aprt_power\":"+s(c1p)+",\"a_pf\":1,\"a_freq\":50," mstr1+="\"b_current\":"+s(c2c)+",\"b_voltage\":230,\"b_act_power\":"+s(c2p)+",\"b_aprt_power\":"+s(c2p)+",\"b_pf\":1,\"b_freq\":50," mstr2="\"c_current\":"+s(c3c)+",\"c_voltage\":230,\"c_act_power\":"+s(c3p)+",\"c_aprt_power\":"+s(c3p)+",\"c_pf\":1,\"c_freq\":50," mstr2+="\"total_current\":"+s(c1c+c2c+c3c)+",\"total_act_power\":"+s(cpwr)+",\"total_aprt_power\":"+s(cpwr)+"}}" #egetstat dp(0 2) mstr1="{\"id\":0,\"a_total_act_energy\":"+s(c1p)+",\"a_total_act_ret_energy\":"+s(c1p)+",\"b_total_act_energy\":"+s(c2p)+",\"b_total_act_ret_energy\":"+s(c2p)+",\"c_total_act_energy\":"+s(c3p)+",\"c_total_act_ret_energy\":"+s(c3p)+",\"total_act\":"+s(cpwr)+",\"total_act_ret\":"+s(cpwr)+"}}" #getsrc tstr="shellypro3em-"+maca header="{\"id\":0,\"src\":\""+tstr+"\",\"result\":" >S if year<2000 { break } ; adapt this to your meter ; update every 3 seconds if upsecs%3==0 { cpwr=sml[3] c1p=sml[4] c2p=sml[5] c3p=sml[6] } ; use this if you only have only one phase meter values ;c1p=cpwr/3 ;c2p=cpwr/3 ;c3p=cpwr/3 ; calculate phase currents c1c=c1p/230 c2c=c2p/230 c3c=c3p/230 if once==0 { ; start mdns for Shelly second parameter "-" means use device mac res=mdns("shellypro3em-" "-" "shelly") ; start udp rpc handler on port 1010 or on port 2220 (for b2500) ;res=udp(0 1010) res=udp(0 2220) once=1 } ; evaluate udp input str=udp(1) if str!="" { ;print udp rpc payload=%str% res=ins(str "EM.GetStatus") if res>=0 { =#getsrc =#getstat udp(2 header mstr1 mstr2) ;print >> %header% ;print >> %mstr1% ;print >> %mstr2% break } res=ins(str "Shelly.GetDeviceInfo") if res>=0 { =#getsrc =#getdefi udp(2 header mstr1 mstr2) ;print >> 1 %mstr1% ;print >> 2 %mstr2% break } res=ins(str "EM.GetConfig") if res>=0 { =#getsrc =#getcfg udp(2 header mstr1) ;print >> 1 %mstr1% break } res=ins(str "EMData.GetStatus") if res>=0 { =#getsrc =#egetstat udp(2 header mstr1) ;print >> 1 %mstr1% break } } ; adapt your own meter descriptor here ;>M 1 ;+1,5,o,16,9600,eBZ,4 ;1,1-0:1.8.0*255(@1,Verbrauch,kWh,E_in,3 ;1,1-0:2.8.0*255(@1,Einspeisung,kWh,E_out,3 ;1,1-0:16.7.0*255(@1,akt. Leistung,W,Power,0 ;1,1-0:36.7.0*255(@1,Leistung L1,W,36_7_0,0 ;1,1-0:56.7.0*255(@1,Leistung L2,W,56_7_0,0 ;1,1-0:76.7.0*255(@1,Leistung L3,W,76_7_0,0 ;1,1-0:32.7.0*255(@1,Spannung L1,V,32_7_0,1 ;1,1-0 ;1 ;1,1-0:96.1.0*255(@#),Identifikation,,96_1_0,0 ;# >M 1 +1,44,s,0,9600,SGM-D4,43 ;1,77070100100700FF@1,akt. Leistung,W,Power_curr,0 1,77070100010800FF@1,Zählerstand,Wh,E_in,3 ;1,77070100010800FF@1000,Zählerstand,kWh,Total_in,2 1,77070100020800FF@1,Einspeisung,Wh,E_out,3 ;1,77070100020800FF@1000,Einspeisung,kWh,Total_out,2 1,77070100100700FF@1,akt. Leistung,W,Power,0 1,77070100240700FF@1,Leistung L1,W,36_7_0,3 1,77070100380700FF@1,Leistung L2,W,56_7_0,3 1,770701004C0700FF@1,Leistung L3,W,76_7_0,3 1,77070100200700FF@1,Spannung L1,V,32_7_0,1 1,77070100340700FF@1,Spannung L2,V,52_7_0,1 1,77070100480700FF@1,Spannung L3,V,72_7_0,1 ; ;1,770701000E0700FF@1,Netzfrequenz,Hz,netzfrequenz,1 ;1,77070100200700FF@1,Phasenspannung L1,V,momentanspannung_l1,1 ;1,770701001F0700FF@1,Phasenstrom L1,A,momentanstrom_l1,2 ;1,77070100240700FF@1000,Wirkleistung L1,kW,summenwirkleistung_l1,3 ;1,77070100340700FF@1,Phasenspannung L2,V,momentanspannung_l2,1 ;1,77070100330700FF@1,Phasenstrom L2,A,momentanstrom_l2,2 ;1,77070100380700FF@1000,Wirkleistung L2,kW,summenwirkleistung_l2,3 ;1,77070100480700FF@1,Phasenspannung L3,V,momentanspannung_l3,1 ;1,77070100470700FF@1,Phasenstrom L3,A,momentanstrom_l3,2 ;1,770701004C0700FF@1000,Wirkleistung L3,kW,summenwirkleistung_l3,3 #

