Vehicle: don't instantiate disabled vehicles (#32919)
This commit is contained in:
parent
8cf5a44a32
commit
adfbd057b0
5 changed files with 74 additions and 12 deletions
11
cmd/setup.go
11
cmd/setup.go
|
|
@ -538,9 +538,14 @@ func configureVehicles(static []config.Named, names ...string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instance, err := vehicleInstance(cc)
|
// disabled vehicles are not instantiated
|
||||||
if err != nil {
|
var instance api.Vehicle
|
||||||
return fmt.Errorf("cannot create vehicle '%s': %w", cc.Name, err)
|
if !conf.Disable {
|
||||||
|
var err error
|
||||||
|
instance, err = vehicleInstance(cc)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot create vehicle '%s': %w", cc.Name, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,8 @@ func NewLoadpointFromConfig(log *util.Logger, settings settings.Settings, collec
|
||||||
}
|
}
|
||||||
lp.defaultVehicle = dev.Instance()
|
lp.defaultVehicle = dev.Instance()
|
||||||
if lp.defaultVehicle == nil {
|
if lp.defaultVehicle == nil {
|
||||||
return lp, errors.New("missing default vehicle instance")
|
// disabled vehicle
|
||||||
|
lp.log.DEBUG.Printf("default vehicle '%s' is disabled", lp.VehicleRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ import (
|
||||||
"github.com/evcc-io/evcc/core/soc"
|
"github.com/evcc-io/evcc/core/soc"
|
||||||
"github.com/evcc-io/evcc/messenger"
|
"github.com/evcc-io/evcc/messenger"
|
||||||
"github.com/evcc-io/evcc/util"
|
"github.com/evcc-io/evcc/util"
|
||||||
|
"github.com/evcc-io/evcc/util/config"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -882,3 +884,26 @@ func TestBatteryBoostHold(t *testing.T) {
|
||||||
// which is what keeps the sitePower priority adjustment applied to the loadpoint
|
// which is what keeps the sitePower priority adjustment applied to the loadpoint
|
||||||
assert.NotEqual(t, boostDisabled, lp.GetBatteryBoost(), "hold is active")
|
assert.NotEqual(t, boostDisabled, lp.GetBatteryBoost(), "hold is active")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default vehicle referencing a disabled vehicle must not fail loadpoint creation
|
||||||
|
func TestNewLoadpointFromConfigDisabledVehicle(t *testing.T) {
|
||||||
|
config.Reset()
|
||||||
|
t.Cleanup(config.Reset)
|
||||||
|
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
|
||||||
|
// disabled vehicle: device registered without instance
|
||||||
|
var vehicle api.Vehicle
|
||||||
|
require.NoError(t, config.Vehicles().Add(config.NewStaticDevice(config.Named{Name: "vehicle"}, vehicle)))
|
||||||
|
require.NoError(t, config.Chargers().Add(config.NewStaticDevice(config.Named{Name: "charger"}, api.Charger(api.NewMockCharger(ctrl)))))
|
||||||
|
|
||||||
|
lp, err := NewLoadpointFromConfig(util.NewLogger("foo"), nil, nil, map[string]any{
|
||||||
|
"charger": "charger",
|
||||||
|
"vehicle": "vehicle",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Nil(t, lp.defaultVehicle)
|
||||||
|
|
||||||
|
// disabled vehicle is filtered from instances
|
||||||
|
require.Empty(t, config.Instances(config.Vehicles().Devices()))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,14 +104,7 @@ type vehicles struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vv *vehicles) Instances() []api.Vehicle {
|
func (vv *vehicles) Instances() []api.Vehicle {
|
||||||
devs := config.Vehicles().Devices()
|
return config.Instances(config.Vehicles().Devices())
|
||||||
|
|
||||||
res := make([]api.Vehicle, 0, len(devs))
|
|
||||||
for _, dev := range devs {
|
|
||||||
res = append(res, dev.Instance())
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vv *vehicles) Settings() []vehicle.API {
|
func (vv *vehicles) Settings() []vehicle.API {
|
||||||
|
|
@ -119,6 +112,10 @@ func (vv *vehicles) Settings() []vehicle.API {
|
||||||
|
|
||||||
res := make([]vehicle.API, 0, len(devs))
|
res := make([]vehicle.API, 0, len(devs))
|
||||||
for _, dev := range devs {
|
for _, dev := range devs {
|
||||||
|
// skip disabled vehicles
|
||||||
|
if dev.Instance() == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
res = append(res, vehicle.Adapter(vv.log, dev))
|
res = append(res, vehicle.Adapter(vv.log, dev))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,10 @@ test.describe("disable / enable", async () => {
|
||||||
await start();
|
await start();
|
||||||
await page.goto("/#/config");
|
await page.goto("/#/config");
|
||||||
|
|
||||||
|
// loadpoint so the vehicle shows up on the dashboard
|
||||||
|
await createLoadpoint(page, "Carport");
|
||||||
|
await page.reload();
|
||||||
|
|
||||||
// add user-defined vehicle
|
// add user-defined vehicle
|
||||||
await page.getByTestId("add-vehicle").click();
|
await page.getByTestId("add-vehicle").click();
|
||||||
const modal = page.getByTestId("vehicle-modal");
|
const modal = page.getByTestId("vehicle-modal");
|
||||||
|
|
@ -277,6 +281,23 @@ soc:
|
||||||
await expectNoFatal(page);
|
await expectNoFatal(page);
|
||||||
await expect(disabledBadge(vehicleCard)).toBeVisible();
|
await expect(disabledBadge(vehicleCard)).toBeVisible();
|
||||||
|
|
||||||
|
// disabled vehicle is hidden from main ui
|
||||||
|
await page.goto("/");
|
||||||
|
await expect(page.getByTestId("loadpoint")).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.getByTestId("change-vehicle").getByRole("option", { name: "blue Honda" })
|
||||||
|
).toHaveCount(0);
|
||||||
|
|
||||||
|
// no vehicles entry in more menu
|
||||||
|
const moreTab = page.getByTestId("tab-more");
|
||||||
|
await moreTab.click();
|
||||||
|
await expect(moreTab.getByRole("button", { name: "User Interface" })).toBeVisible();
|
||||||
|
await expect(moreTab.getByRole("button", { name: "Vehicles" })).not.toBeVisible();
|
||||||
|
// close more menu
|
||||||
|
await moreTab.click();
|
||||||
|
|
||||||
|
await page.goto("/#/config");
|
||||||
|
|
||||||
// re-enable by clicking the disabled card
|
// re-enable by clicking the disabled card
|
||||||
await disabledBadge(vehicleCard).click();
|
await disabledBadge(vehicleCard).click();
|
||||||
await expect(disabledBadge(vehicleCard)).toHaveCount(0);
|
await expect(disabledBadge(vehicleCard)).toHaveCount(0);
|
||||||
|
|
@ -286,6 +307,19 @@ soc:
|
||||||
await page.reload();
|
await page.reload();
|
||||||
await expectNoFatal(page);
|
await expectNoFatal(page);
|
||||||
await expect(vehicleCard).toContainText("blue Honda");
|
await expect(vehicleCard).toContainText("blue Honda");
|
||||||
|
|
||||||
|
// vehicle is selectable on the dashboard again
|
||||||
|
await page.goto("/");
|
||||||
|
await expect(
|
||||||
|
page.getByTestId("change-vehicle").getByRole("option", { name: "blue Honda" })
|
||||||
|
).toHaveCount(1);
|
||||||
|
|
||||||
|
// vehicle is back in the more menu vehicles modal
|
||||||
|
await moreTab.click();
|
||||||
|
await moreTab.getByRole("button", { name: "Vehicles" }).click();
|
||||||
|
const settingsModal = page.getByTestId("vehicle-settings-modal");
|
||||||
|
await expectModalVisible(settingsModal);
|
||||||
|
await expect(settingsModal.getByRole("group", { name: "blue Honda" })).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue