Skip to content

Commit ec54012

Browse files
authored
add sdm630 emulator script
1 parent 86505b5 commit ec54012

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

docs/Smart-Meter-Interface.md

+181
Original file line numberDiff line numberDiff line change
@@ -3598,6 +3598,187 @@ Set device parity to NONE
35983598
1,010404ffffffff@i8:1,Active Power P3,W,Power_P3,2
35993599
#
36003600
```
3601+
3602+
### SDM630-Emulator (MODBus)
3603+
Show how to emulate an SDM630 e.g. to interact with a GROWATT solar inverter.
3604+
3605+
??? summary "View script"
3606+
```
3607+
>D
3608+
; simulate eastron sdm630 modbus meter
3609+
IP=192.168.188.114
3610+
; need this additional defs
3611+
; due to speed requirements this script needs an ESP32
3612+
;#define USE_SCRIPT_TASK
3613+
;#define USE_SCRIPT_SERIAL
3614+
;#define USE_SML_M
3615+
; for debugging uncomment print statements below
3616+
; receive pin
3617+
rec=21
3618+
; transmit pin
3619+
trx=20
3620+
; meter address
3621+
addr=2
3622+
; current meter power, negativ on export
3623+
cmpwr=0
3624+
res=0
3625+
M:req=0 8
3626+
M:resp=0 128
3627+
regs=0
3628+
startreg=0
3629+
cnt=0
3630+
index=0
3631+
mtime=0
3632+
curr1=0
3633+
cpw1=0
3634+
cvol1=230
3635+
>B
3636+
=>sensor53 r
3637+
>BS
3638+
; should be hardware serial pins
3639+
res=so(rec trx 9600 8N1 1024)
3640+
if res==0 {
3641+
print serial open failed
3642+
} else {
3643+
; create task every 1 ms
3644+
ct(1 1 1 3 8000)
3645+
}
3646+
; meter descriptor
3647+
\>M 1
3648+
; sml serial receive GPIO, here pin4
3649+
+1,4,s,0,9600,SML
3650+
1,77070100010800ff@1000,Verbrauch,KWh,Total_in,4
3651+
1,77070100020800ff@1000,Einspeisung,KWh,Total_out,4
3652+
1,77070100100700ff@1,Aktueller Verbrauch,W,Power_curr,0
3653+
1,77070100000009ff@#,Zähler Nr,,Meter_number,0
3654+
#
3655+
; respond to request
3656+
#response
3657+
index=1
3658+
for cnt 1 regs 1
3659+
switch startreg
3660+
case 0
3661+
; voltage p1
3662+
resp[index]=cvol1
3663+
case 2
3664+
; voltage p2
3665+
resp[index]=cvol1
3666+
case 4
3667+
; voltage p3
3668+
resp[index]=cvol1
3669+
case 6
3670+
; current p1
3671+
resp[index]=curr1
3672+
case 8
3673+
; current p2
3674+
resp[index]=curr1
3675+
case 10
3676+
; current p3
3677+
resp[index]=curr1
3678+
case 12
3679+
; power p1
3680+
resp[index]=cpw1
3681+
case 14
3682+
; power p2
3683+
resp[index]=cpw1
3684+
case 16
3685+
; power p3
3686+
resp[index]=cpw1
3687+
case 18
3688+
; app power p1
3689+
resp[index]=cpw1
3690+
case 20
3691+
; app power p2
3692+
resp[index]=cpw1
3693+
case 22
3694+
; app power p3
3695+
resp[index]=cpw1
3696+
case 30
3697+
; power factor p1
3698+
resp[index]=1
3699+
case 32
3700+
; power factor p2
3701+
resp[index]=1
3702+
case 34
3703+
; power factor p3
3704+
resp[index]=1
3705+
case 48
3706+
; current sum
3707+
resp[index]=230/cmpwr
3708+
case 52
3709+
; total system power
3710+
resp[index]=cmpwr
3711+
case 56
3712+
; total system va
3713+
resp[index]=cmpwr
3714+
case 70
3715+
; 50 Hz frequency
3716+
resp[index]=50
3717+
case 72
3718+
;total Import
3719+
resp[index]=sml[1]
3720+
case 74
3721+
;total export
3722+
resp[index]=sml[2]
3723+
case 342
3724+
;total kWh
3725+
resp[index]=sml[1]
3726+
ends
3727+
index+=1
3728+
startreg+=2
3729+
next
3730+
; write response
3731+
smw(addr 3 resp regs)
3732+
3733+
; multitasking every 1 ms
3734+
\>t1
3735+
3736+
; get current power from meter
3737+
cmpwr=sml[3]
3738+
3739+
; fake power
3740+
;cmpwr=3000+rnd(1000)
3741+
curr1=cmpwr/230/3
3742+
cpw1=cmpwr/3
3743+
3744+
; check for incomming request
3745+
res=sa()
3746+
if res>=8 {
3747+
mtime=millis
3748+
; read request, returns 8 if OK
3749+
res=sra(req)
3750+
if res==8
3751+
and req[1]==addr
3752+
and req[2]==4 {
3753+
; valid request
3754+
;print request = %0req[1]% - %0req[2]% - %0req[3]% - %0req[4]% - %0req[5]% - %0req[6]%
3755+
; slave adress,function code,start adress Hi,start adress Lo,np Hi,np Lo,crc Lo,crc Hi
3756+
regs=req[6]/2
3757+
startreg=req[3]<<8|req[4]
3758+
;print addr= %0req[1]%, startaddr=%0startreg%, numregs=%0regs%
3759+
=#response
3760+
res=sa()
3761+
res=sra(resp)
3762+
;print duration %0(millis-mtime)%
3763+
} else {
3764+
if res<0 {
3765+
print crc error
3766+
} else {
3767+
print iqnore request
3768+
}
3769+
; empty serial queue
3770+
res=sa()
3771+
res=sra(resp)
3772+
}
3773+
3774+
}
3775+
3776+
3777+
\>R
3778+
; close serial port
3779+
sc()
3780+
```
3781+
36013782
36023783
### SDM630 (MODBus)
36033784
Show how to request multiple registers.

0 commit comments

Comments
 (0)