@@ -3598,6 +3598,187 @@ Set device parity to NONE
3598
3598
1,010404ffffffff@i8:1,Active Power P3,W,Power_P3,2
3599
3599
#
3600
3600
```
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
+
3601
3782
3602
3783
### SDM630 (MODBus)
3603
3784
Show how to request multiple registers.
0 commit comments