diff --git a/charger/easee.go b/charger/easee.go index 75249a6be..55a67f844 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -192,9 +192,31 @@ func NewEasee(user, password, charger string, timeout time.Duration, authorize b err = os.ErrDeadlineExceeded } + if err == nil { + c.waitForOptionalState() + } + return c, err } +func (c *Easee) waitForOptionalState() { + for i := 0; i < 30; i++ { + if c.optionalStatePresent() { + return + } + time.Sleep(100 * time.Millisecond) + } + c.log.WARN.Println("did not receive full state from cloud") +} + +// check c.obsTime for presence of ALL of the following keys: easee.SESSION_ENERGY, easee.LIFETIME_ENERGY +func (c *Easee) optionalStatePresent() bool { + c.mux.Lock() + defer c.mux.Unlock() + wanted := []easee.ObservationID{easee.SESSION_ENERGY, easee.LIFETIME_ENERGY, easee.TOTAL_POWER} + return len(wanted) == len(lo.Intersect(wanted, lo.Keys(c.obsTime))) +} + func (c *Easee) chargerSite(charger string) (easee.Site, error) { var res easee.Site uri := fmt.Sprintf("%s/chargers/%s/site", easee.API, charger) diff --git a/charger/easee_test.go b/charger/easee_test.go index a7243f275..68e23f399 100644 --- a/charger/easee_test.go +++ b/charger/easee_test.go @@ -61,6 +61,32 @@ func TestProductUpdate_IgnoreOutdatedProductUpdate(t *testing.T) { assert.Equal(t, 2, e.opMode) } +func TestProductUpdate_InitialStateCheck(t *testing.T) { + now := time.Now().UTC().Truncate(0) //truncate removes sub nanos + + e := newEasee() + + assert.False(t, e.optionalStatePresent()) + + tc := []struct { + obsId easee.ObservationID + dataType easee.DataType + value string + expectInitState bool + }{ + {easee.TOTAL_POWER, easee.Double, "11.0", false}, + {easee.SESSION_ENERGY, easee.Double, "22.0", false}, + {easee.LIFETIME_ENERGY, easee.Double, "1000.0", true}, + } + + for _, tc := range tc { + t.Logf("%+v", tc) + + e.ProductUpdate(createPayload(tc.obsId, now, tc.dataType, tc.value)) + assert.Equal(t, tc.expectInitState, e.optionalStatePresent()) + } +} + // TestInExpectedOpMode tests the inExpectedOpMode function with different scenarios func TestInExpectedOpMode(t *testing.T) { tc := []struct {