nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: evcc-io/evcc
Pull request #3888 (2022-07-18 13:53:49)

Fix loadpoint default phases overriding auto phase config for 1p3p chargers


Patch:
diff --git a/core/loadpoint.go b/core/loadpoint.go
index 2230a8c5..243a20bc 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -234,12 +234,14 @@ func NewLoadPointFromConfig(log *util.Logger, cp configProvider, other map[strin
 	lp.configureChargerType(lp.charger)
 
 	// setup fixed phases:
-	// - simple charger starts with phases config if specified
+	// - simple charger starts with phases config if specified or 3p
 	// - switchable charger starts at 0p since we don't know the current setting
 	if _, ok := lp.charger.(api.ChargePhases); !ok {
-		if lp.DefaultPhases != 0 {
-			lp.phases = lp.DefaultPhases
+		if lp.DefaultPhases == 0 {
+			lp.DefaultPhases = 3
+			lp.log.WARN.Println("phases not configured, assuming 3p")
 		}
+		lp.phases = lp.DefaultPhases
 	} else if lp.DefaultPhases != 0 {
 		lp.log.WARN.Printf("locking phase config to %dp for switchable charger", lp.DefaultPhases)
 	}
@@ -264,7 +266,6 @@ func NewLoadPoint(log *util.Logger) *LoadPoint {
 		clock:         clock, // mockable time
 		bus:           bus,   // event bus
 		Mode:          api.ModeOff,
-		phases:        3,
 		status:        api.StatusNone,
 		MinCurrent:    6,                                                     // A
 		MaxCurrent:    16,                                                    // A


Test patch:
diff --git a/core/loadpoint_test.go b/core/loadpoint_test.go
index e72a86cb..0277bfbd 100644
--- a/core/loadpoint_test.go
+++ b/core/loadpoint_test.go
@@ -82,7 +82,7 @@ func attachListeners(t *testing.T, lp *LoadPoint) {
 func TestNew(t *testing.T) {
 	lp := NewLoadPoint(util.NewLogger("foo"))
 
-	if lp.phases != 3 {
+	if lp.phases != 0 {
 		t.Errorf("Phases %v", lp.phases)
 	}
 	if lp.MinCurrent != minA {
Repository: evcc-io/evcc
Pull request #4123 (2022-08-16 09:34:30)

Validate vehicle min/max currents against loadpoint defaults
Fix https://github.com/evcc-io/evcc/issues/4113

`lp.onDisconnect` enthält die Defaults des Loadpoints.


Patch:
diff --git a/core/loadpoint.go b/core/loadpoint.go
index 71f5ea01..dfad87a6 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -477,11 +477,11 @@ func (lp *LoadPoint) applyAction(actionCfg api.ActionConfig) {
 	if actionCfg.Mode != nil {
 		lp.SetMode(*actionCfg.Mode)
 	}
-	if actionCfg.MinCurrent != nil {
-		lp.SetMinCurrent(*actionCfg.MinCurrent)
+	if min := actionCfg.MinCurrent; min != nil && *min >= *lp.onDisconnect.MinCurrent {
+		lp.SetMinCurrent(*min)
 	}
-	if actionCfg.MaxCurrent != nil {
-		lp.SetMaxCurrent(*actionCfg.MaxCurrent)
+	if max := actionCfg.MaxCurrent; max != nil && *max <= *lp.onDisconnect.MaxCurrent {
+		lp.SetMaxCurrent(*max)
 	}
 	if actionCfg.MinSoC != nil {
 		lp.SetMinSoC(*actionCfg.MinSoC)


Test patch:
diff --git a/core/loadpoint_vehicle_test.go b/core/loadpoint_vehicle_test.go
index de53ad37..5da32a74 100644
--- a/core/loadpoint_vehicle_test.go
+++ b/core/loadpoint_vehicle_test.go
@@ -172,8 +172,11 @@ func TestApplyVehicleDefaults(t *testing.T) {
 		}
 	}
 
-	oi := newConfig(api.ModePV, 7, 17, 1, 99)
-	od := newConfig(api.ModeOff, 5, 15, 2, 98)
+	// onIdentified config
+	oi := newConfig(api.ModePV, 7, 15, 1, 99)
+
+	// onDefault config
+	od := newConfig(api.ModeOff, 6, 16, 2, 98)
 
 	vehicle := mock.NewMockVehicle(ctrl)
 	vehicle.EXPECT().Title().Return("it's me").AnyTimes()
@@ -189,6 +192,10 @@ func TestApplyVehicleDefaults(t *testing.T) {
 	lp.onDisconnect = od
 	lp.ResetOnDisconnect = true
 
+	// check loadpoint default currents can't be violated
+	lp.applyAction(newConfig(*od.Mode, 5, 17, *od.MinSoC, *od.TargetSoC))
+	assertConfig(lp, od)
+
 	// vehicle identified
 	lp.setActiveVehicle(vehicle)
 	assertConfig(lp, oi)
Repository: evcc-io/evcc
Pull request #2753 (2022-03-02 10:21:46)

Use maximum possible phases for scale-up calculation


Patch:
diff --git a/core/loadpoint.go b/core/loadpoint.go
index 219db3cf..ac91119e 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -1079,7 +1079,7 @@ func (lp *LoadPoint) pvScalePhases(availablePower, minCurrent, maxCurrent float6
 	scalable := maxPhases > 1 && phases < maxPhases
 
 	// scale up phases
-	if min3pCurrent := powerToCurrent(availablePower, 3); min3pCurrent >= minCurrent && scalable {
+	if min3pCurrent := powerToCurrent(availablePower, maxPhases); min3pCurrent >= minCurrent && scalable {
 		lp.log.DEBUG.Printf("available power %.0fW > %.0fW min %dp threshold", availablePower, 3*Voltage*minCurrent, maxPhases)
 
 		if lp.phaseTimer.IsZero() {


Test patch:
diff --git a/core/loadpoint_phases_test.go b/core/loadpoint_phases_test.go
index d98eb1ee..ac764126 100644
--- a/core/loadpoint_phases_test.go
+++ b/core/loadpoint_phases_test.go
@@ -162,9 +162,12 @@ func TestPvScalePhases(t *testing.T) {
 			ctrl.Finish()
 
 			// scale up
-			min3p := 3 * minA * Voltage
+			min3p := float64(tc.maxExpected) * minA * Voltage
 			lp.phaseTimer = time.Time{}
-			lp.Phases = tc.physical // reset to initial state
+
+			// reset to initial state
+			lp.Phases = tc.physical
+			lp.measuredPhases = tc.measuredPhases
 
 			plainCharger.EXPECT().Enable(false).Return(nil).MaxTimes(1)
 			phaseCharger.EXPECT().Phases1p3p(3).Return(nil).MaxTimes(1)
Repository: evcc-io/evcc
Pull request #5971 (2023-01-31 21:09:44)

Tariff: don't re-order catch-all zone
Fix https://github.com/evcc-io/evcc/issues/5961


Patch:
diff --git a/tariff/fixed.go b/tariff/fixed.go
index 11f88ea9..3ca0f222 100644
--- a/tariff/fixed.go
+++ b/tariff/fixed.go
@@ -44,9 +44,6 @@ func NewFixedFromConfig(other map[string]interface{}) (api.Tariff, error) {
 	t := &Fixed{
 		unit:  cc.Currency,
 		clock: clock.New(),
-		zones: []fixed.Zone{
-			{Price: cc.Price}, // full week is implicit
-		},
 	}
 
 	for _, z := range cc.Zones {
@@ -79,6 +76,11 @@ func NewFixedFromConfig(other map[string]interface{}) (api.Tariff, error) {
 
 	sort.Sort(t.zones)
 
+	// prepend catch-all zone
+	t.zones = append([]fixed.Zone{
+		{Price: cc.Price}, // full week is implicit
+	}, t.zones...)
+
 	return t, nil
 }
 
diff --git a/tariff/fixed/zone.go b/tariff/fixed/zone.go
index efbf1c52..f857559f 100644
--- a/tariff/fixed/zone.go
+++ b/tariff/fixed/zone.go
@@ -1,8 +1,6 @@
 package fixed
 
 import (
-	"sort"
-
 	"golang.org/x/exp/slices"
 )
 
@@ -39,7 +37,6 @@ func (r Zones) ForDay(day Day) Zones {
 		}
 	}
 
-	sort.Sort(zones)
 	return zones
 }
 


Test patch:
diff --git a/tariff/fixed_test.go b/tariff/fixed_test.go
index 0f98349d..3a181c12 100644
--- a/tariff/fixed_test.go
+++ b/tariff/fixed_test.go
@@ -33,3 +33,46 @@ func TestFixed(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Equal(t, expect, rates)
 }
+
+func TestFixedSplitZones(t *testing.T) {
+	at, err := NewFixedFromConfig(map[string]interface{}{
+		"price": 0.5,
+		"zones": []struct {
+			Price float64
+			Hours string
+		}{
+			{0.1, "0-5:30,21-0"},
+		},
+	})
+	assert.NoError(t, err)
+
+	tf := at.(*Fixed)
+	tf.clock = clock.NewMock()
+
+	var expect api.Rates
+	for i := 0; i < 7; i++ {
+		dayStart := carbon.FromStdTime(tf.clock.Now()).StartOfDay().AddDays(i)
+
+		expect = append(expect,
+			api.Rate{
+				Price: 0.1,
+				Start: dayStart.ToStdTime(),
+				End:   dayStart.AddHours(5).AddMinutes(30).ToStdTime(),
+			},
+			api.Rate{
+				Price: 0.5,
+				Start: dayStart.AddHours(5).AddMinutes(30).ToStdTime(),
+				End:   dayStart.AddHours(21).ToStdTime(),
+			},
+			api.Rate{
+				Price: 0.1,
+				Start: dayStart.AddHours(21).ToStdTime(),
+				End:   dayStart.AddDay().ToStdTime(),
+			},
+		)
+	}
+
+	rates, err := tf.Rates()
+	assert.NoError(t, err)
+	assert.Equal(t, expect, rates)
+}
Repository: evcc-io/evcc
Pull request #7640 (2023-04-24 16:21:23)

Websocket plugin: apply jq when receiving value
Fix https://github.com/evcc-io/evcc/issues/7633


Patch:
diff --git a/go.mod b/go.mod
index 51cb7863..dcabf1f8 100644
--- a/go.mod
+++ b/go.mod
@@ -102,6 +102,7 @@ require (
 	google.golang.org/protobuf v1.30.0
 	gopkg.in/yaml.v3 v3.0.1
 	gorm.io/gorm v1.25.0
+	nhooyr.io/websocket v1.8.7
 )
 
 require (
@@ -196,7 +197,6 @@ require (
 	modernc.org/mathutil v1.5.0 // indirect
 	modernc.org/memory v1.5.0 // indirect
 	modernc.org/sqlite v1.21.1 // indirect
-	nhooyr.io/websocket v1.8.7 // indirect
 )
 
 replace github.com/foogod/go-powerwall => github.com/andig/go-powerwall v0.2.1-0.20230102102528-4d59ac6910c6
diff --git a/provider/socket.go b/provider/socket.go
index 46c5fbf7..6e57bcc5 100644
--- a/provider/socket.go
+++ b/provider/socket.go
@@ -122,10 +122,12 @@ func (p *Socket) listen() {
 
 			p.log.TRACE.Printf("recv: %s", b)
 
-			p.mux.Lock()
-			p.val = b
-			p.wait.Update()
-			p.mux.Unlock()
+			if v, err := p.pipeline.Process(b); err == nil {
+				p.mux.Lock()
+				p.val = v
+				p.wait.Update()
+				p.mux.Unlock()
+			}
 		}
 	}
 }
@@ -146,13 +148,11 @@ var _ StringProvider = (*Socket)(nil)
 // StringGetter sends string request
 func (p *Socket) StringGetter() func() (string, error) {
 	return func() (string, error) {
-		b, err := p.hasValue()
+		v, err := p.hasValue()
 		if err != nil {
 			return "", err
 		}
 
-		v, err := p.pipeline.Process(b)
-
 		return string(v), err
 	}
 }


Test patch:
diff --git a/provider/socket_test.go b/provider/socket_test.go
new file mode 100644
index 00000000..1ddae010
--- /dev/null
+++ b/provider/socket_test.go
@@ -0,0 +1,53 @@
+package provider
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+	"nhooyr.io/websocket"
+)
+
+func TestSocketProvider(t *testing.T) {
+	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
+	defer cancel()
+
+	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		c, err := websocket.Accept(w, r, nil)
+		require.NoError(t, err)
+		defer c.Close(websocket.StatusNormalClosure, "")
+
+		uuids := []string{"foo", "bar"}
+		for i := 0; ; i++ {
+			json := fmt.Sprintf(`{"data":{"uuid":"%s","tuples":[[1682319567986,%d]]}}`, uuids[i%2], i%2)
+
+			if err := c.Write(ctx, websocket.MessageText, []byte(json)); err != nil {
+				require.NoError(t, err)
+			}
+
+			select {
+			case <-time.Tick(time.Millisecond):
+			case <-ctx.Done():
+				return
+			}
+		}
+	}))
+
+	defer srv.Close()
+
+	addr := "ws://" + srv.Listener.Addr().String()
+	p, err := NewSocketProviderFromConfig(map[string]any{
+		"uri": addr,
+		"jq":  `.data | select(.uuid=="bar") .tuples[0][1]`,
+	})
+	require.NoError(t, err)
+
+	g := p.IntGetter()
+	i, err := g()
+	require.NoError(t, err)
+	require.Equal(t, int64(1), i)
+}
Repository: evcc-io/evcc
Pull request #11511 (2024-01-05 16:44:58)

Battery control: hold battery during smart charging
Fix https://github.com/evcc-io/evcc/issues/11504

premultiply: Ich glaub das macht noch Sinn.

Patch:
diff --git a/core/site.go b/core/site.go
index b41146c4..612e1ef2 100644
--- a/core/site.go
+++ b/core/site.go
@@ -807,7 +807,7 @@ func (site *Site) update(lp Updater) {
 	}
 
 	if batMode := site.GetBatteryMode(); site.batteryDischargeControl {
-		if mode := site.determineBatteryMode(site.Loadpoints()); mode != batMode {
+		if mode := site.determineBatteryMode(site.Loadpoints(), smartCostActive); mode != batMode {
 			if err := site.updateBatteryMode(mode); err != nil {
 				site.log.ERROR.Println("battery mode:", err)
 			}
diff --git a/core/site_battery.go b/core/site_battery.go
index fc26bb41..c0eb71f8 100644
--- a/core/site_battery.go
+++ b/core/site_battery.go
@@ -30,9 +30,9 @@ func (site *Site) SetBatteryMode(batMode api.BatteryMode) {
 	}
 }
 
-func (site *Site) determineBatteryMode(loadpoints []loadpoint.API) api.BatteryMode {
+func (site *Site) determineBatteryMode(loadpoints []loadpoint.API, smartCostActive bool) api.BatteryMode {
 	for _, lp := range loadpoints {
-		if lp.GetStatus() == api.StatusC && (lp.GetMode() == api.ModeNow || lp.GetPlanActive()) {
+		if lp.GetStatus() == api.StatusC && (smartCostActive || lp.GetMode() == api.ModeNow || lp.GetPlanActive()) {
 			return api.BatteryHold
 		}
 	}


Test patch:
diff --git a/core/site_battery_test.go b/core/site_battery_test.go
index 859b7898..6cd68636 100644
--- a/core/site_battery_test.go
+++ b/core/site_battery_test.go
@@ -44,7 +44,7 @@ func TestDetermineBatteryMode(t *testing.T) {
 
 		loadpoints := []loadpoint.API{lp}
 
-		mode := s.determineBatteryMode(loadpoints)
+		mode := s.determineBatteryMode(loadpoints, false)
 		assert.Equal(t, tc.expBatMode, mode, tc)
 	}
 }