Benutzer-Werkzeuge

Webseiten-Werkzeuge


wiki:projekte:shellypro3em:uebersicht

Shelly Pro 3EM Emulator

Quellen

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
#
wiki/projekte/shellypro3em/uebersicht.txt · Zuletzt geändert: von wikimaster