diff --git a/core/loadpoint.go b/core/loadpoint.go index 67f43411a..923b066f6 100644 --- a/core/loadpoint.go +++ b/core/loadpoint.go @@ -194,6 +194,9 @@ func NewLoadPointFromConfig(log *util.Logger, cp configProvider, other map[strin // single vehicle if lp.VehicleRef != "" { + if len(lp.vehicles) > 0 { + return nil, errors.New("cannot have vehicle and vehicles both") + } vehicle := cp.Vehicle(lp.VehicleRef) lp.vehicles = append(lp.vehicles, vehicle) } diff --git a/core/site.go b/core/site.go index 067f5f280..55176ad43 100644 --- a/core/site.go +++ b/core/site.go @@ -39,9 +39,9 @@ type Site struct { PrioritySoC float64 `mapstructure:"prioritySoC"` // prefer battery up to this SoC // meters - gridMeter api.Meter // Grid usage meter - pvMeter api.Meter // PV generation meter - batteryMeter api.Meter // Battery charging meter + gridMeter api.Meter // Grid usage meter + pvMeters []api.Meter // PV generation meters + batteryMeter api.Meter // Battery charging meter tariff api.Tariff // Tariff loadpoints []*LoadPoint // Loadpoints @@ -54,9 +54,10 @@ type Site struct { // MetersConfig contains the loadpoint's meter configuration type MetersConfig struct { - GridMeterRef string `mapstructure:"grid"` // Grid usage meter reference - PVMeterRef string `mapstructure:"pv"` // PV generation meter reference - BatteryMeterRef string `mapstructure:"battery"` // Battery charging meter reference + GridMeterRef string `mapstructure:"grid"` // Grid usage meter + PVMeterRef string `mapstructure:"pv"` // PV meter + PVMetersRef []string `mapstructure:"pvs"` // Multiple PV meters + BatteryMeterRef string `mapstructure:"battery"` // Battery charging meter } // NewSiteFromConfig creates a new site @@ -79,15 +80,28 @@ func NewSiteFromConfig( if site.Meters.GridMeterRef != "" { site.gridMeter = cp.Meter(site.Meters.GridMeterRef) } - if site.Meters.PVMeterRef != "" { - site.pvMeter = cp.Meter(site.Meters.PVMeterRef) + + // multiple pv + for _, ref := range site.Meters.PVMetersRef { + pv := cp.Meter(ref) + site.pvMeters = append(site.pvMeters, pv) } + + // single pv + if site.Meters.PVMeterRef != "" { + if len(site.pvMeters) > 0 { + return nil, errors.New("cannot have pv and pvs both") + } + pv := cp.Meter(site.Meters.PVMeterRef) + site.pvMeters = append(site.pvMeters, pv) + } + if site.Meters.BatteryMeterRef != "" { site.batteryMeter = cp.Meter(site.Meters.BatteryMeterRef) } // configure meter from references - if site.gridMeter == nil && site.pvMeter == nil { + if site.gridMeter == nil && len(site.pvMeters) == 0 { return nil, errors.New("missing either grid or pv meter") } @@ -135,7 +149,7 @@ func (site *Site) DumpConfig() { site.log.INFO.Println("site config:") site.log.INFO.Printf(" meters: grid %s pv %s battery %s", presence[site.gridMeter != nil], - presence[site.pvMeter != nil], + presence[len(site.pvMeters) > 0], presence[site.batteryMeter != nil], ) @@ -144,9 +158,11 @@ func (site *Site) DumpConfig() { site.log.INFO.Println(meterCapabilities("grid", site.gridMeter)) } - site.publish("pvConfigured", site.pvMeter != nil) - if site.pvMeter != nil { - site.log.INFO.Println(meterCapabilities("pv", site.pvMeter)) + site.publish("pvConfigured", len(site.pvMeters) > 0) + if len(site.pvMeters) > 0 { + for i, pv := range site.pvMeters { + site.log.INFO.Println(meterCapabilities(fmt.Sprintf("pv %d", i), pv)) + } } site.publish("batteryConfigured", site.batteryMeter != nil) @@ -247,8 +263,14 @@ func (site *Site) updateMeters() error { return err } - // pv meter is not critical for operation - _ = retryMeter("pv", site.pvMeter, &site.pvPower) + site.pvPower = 0 + for _, pv := range site.pvMeters { + var power float64 + // pv meter is not critical for operation + if err := retryMeter("pv", pv, &power); err != nil { + site.pvPower += power + } + } err := retryMeter("grid", site.gridMeter, &site.gridPower) if err == nil { diff --git a/evcc.dist.yaml b/evcc.dist.yaml index 74bbc1fef..501543056 100644 --- a/evcc.dist.yaml +++ b/evcc.dist.yaml @@ -58,7 +58,8 @@ site: title: Home # display name for UI meters: grid: grid # grid meter - pv: pv # pv meter + pvs: + - pv # list of pv inverters/ meters battery: battery # battery meter prioritySoC: 60 # give home battery priority up to this soc (0 to disable)