@@ -39,9 +39,9 @@ type Site struct {
3939 PrioritySoC float64 `mapstructure:"prioritySoC"` // prefer battery up to this SoC
4040
4141 // meters
42- gridMeter api.Meter // Grid usage meter
43- pvMeter api.Meter // PV generation meter
44- batteryMeter api.Meter // Battery charging meter
42+ gridMeter api.Meter // Grid usage meter
43+ pvMeters [] api.Meter // PV generation meters
44+ batteryMeter api.Meter // Battery charging meter
4545
4646 tariff api.Tariff // Tariff
4747 loadpoints []* LoadPoint // Loadpoints
@@ -54,9 +54,10 @@ type Site struct {
5454
5555// MetersConfig contains the loadpoint's meter configuration
5656type MetersConfig struct {
57- GridMeterRef string `mapstructure:"grid"` // Grid usage meter reference
58- PVMeterRef string `mapstructure:"pv"` // PV generation meter reference
59- BatteryMeterRef string `mapstructure:"battery"` // Battery charging meter reference
57+ GridMeterRef string `mapstructure:"grid"` // Grid usage meter
58+ PVMeterRef string `mapstructure:"pv"` // PV meter
59+ PVMetersRef []string `mapstructure:"pvs"` // Multiple PV meters
60+ BatteryMeterRef string `mapstructure:"battery"` // Battery charging meter
6061}
6162
6263// NewSiteFromConfig creates a new site
@@ -79,15 +80,28 @@ func NewSiteFromConfig(
7980 if site .Meters .GridMeterRef != "" {
8081 site .gridMeter = cp .Meter (site .Meters .GridMeterRef )
8182 }
83+
84+ // multiple pv
85+ for _ , ref := range site .Meters .PVMetersRef {
86+ pv := cp .Meter (ref )
87+ site .pvMeters = append (site .pvMeters , pv )
88+ }
89+
90+ // single pv
8291 if site .Meters .PVMeterRef != "" {
83- site .pvMeter = cp .Meter (site .Meters .PVMeterRef )
92+ if len (site .pvMeters ) > 0 {
93+ return nil , errors .New ("cannot have pv and pvs both" )
94+ }
95+ pv := cp .Meter (site .Meters .PVMeterRef )
96+ site .pvMeters = append (site .pvMeters , pv )
8497 }
98+
8599 if site .Meters .BatteryMeterRef != "" {
86100 site .batteryMeter = cp .Meter (site .Meters .BatteryMeterRef )
87101 }
88102
89103 // configure meter from references
90- if site .gridMeter == nil && site .pvMeter == nil {
104+ if site .gridMeter == nil && len ( site .pvMeters ) == 0 {
91105 return nil , errors .New ("missing either grid or pv meter" )
92106 }
93107
@@ -135,7 +149,7 @@ func (site *Site) DumpConfig() {
135149 site .log .INFO .Println ("site config:" )
136150 site .log .INFO .Printf (" meters: grid %s pv %s battery %s" ,
137151 presence [site .gridMeter != nil ],
138- presence [site .pvMeter != nil ],
152+ presence [len ( site .pvMeters ) > 0 ],
139153 presence [site .batteryMeter != nil ],
140154 )
141155
@@ -144,9 +158,11 @@ func (site *Site) DumpConfig() {
144158 site .log .INFO .Println (meterCapabilities ("grid" , site .gridMeter ))
145159 }
146160
147- site .publish ("pvConfigured" , site .pvMeter != nil )
148- if site .pvMeter != nil {
149- site .log .INFO .Println (meterCapabilities ("pv" , site .pvMeter ))
161+ site .publish ("pvConfigured" , len (site .pvMeters ) > 0 )
162+ if len (site .pvMeters ) > 0 {
163+ for i , pv := range site .pvMeters {
164+ site .log .INFO .Println (meterCapabilities (fmt .Sprintf ("pv %d" , i ), pv ))
165+ }
150166 }
151167
152168 site .publish ("batteryConfigured" , site .batteryMeter != nil )
@@ -247,8 +263,14 @@ func (site *Site) updateMeters() error {
247263 return err
248264 }
249265
250- // pv meter is not critical for operation
251- _ = retryMeter ("pv" , site .pvMeter , & site .pvPower )
266+ site .pvPower = 0
267+ for _ , pv := range site .pvMeters {
268+ var power float64
269+ // pv meter is not critical for operation
270+ if err := retryMeter ("pv" , pv , & power ); err != nil {
271+ site .pvPower += power
272+ }
273+ }
252274
253275 err := retryMeter ("grid" , site .gridMeter , & site .gridPower )
254276 if err == nil {
0 commit comments