From e5377d1d46125cea00df1598d5df6e5b0a5e7aac Mon Sep 17 00:00:00 2001 From: premultiply <4681172+premultiply@users.noreply.github.com> Date: Sun, 8 Sep 2024 22:05:28 +0000 Subject: [PATCH] decorate --- charger/delta.go | 65 +++++++++++++++++++++++-------------- charger/delta_decorators.go | 35 ++++++++++++++++++++ 2 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 charger/delta_decorators.go diff --git a/charger/delta.go b/charger/delta.go index 4b921fe93e..c43a45b91b 100644 --- a/charger/delta.go +++ b/charger/delta.go @@ -23,7 +23,7 @@ type Delta struct { curr float64 base uint16 enabled bool - isBasic bool + statusG func(uint16) (api.ChargeStatus, error) } const ( @@ -102,9 +102,14 @@ func NewDelta(uri, device, comset string, baudrate int, proto modbus.Protocol, s wb.base = connector * 1000 - // check for basic or smart register set - if _, err := wb.conn.ReadInputRegisters(wb.base+deltaRegEvseChargerState, 1); err != nil { - wb.isBasic = true + var statusReasonG func() (api.Reason, error) + + wb.statusG = wb.statusBasic + + // check for smart register set + if _, err := wb.conn.ReadInputRegisters(wb.base+deltaRegEvseChargerState, 1); err == nil { + wb.statusG = wb.statusSmart + statusReasonG = wb.statusReason } b, err := wb.conn.ReadHoldingRegisters(deltaRegCommunicationTimeoutEnabled, 1) @@ -122,9 +127,11 @@ func NewDelta(uri, device, comset string, baudrate int, proto modbus.Protocol, s } } - return wb, nil + return decorateDelta(wb, statusReasonG), nil } +//go:generate go run ../cmd/tools/decorate.go -f decorateDelta -b *Delta -r api.Charger -t "api.StatusReasoner,StatusReason,func() (api.Reason, error)" + func (wb *Delta) heartbeat(timeout time.Duration) { for range time.Tick(timeout) { wb.mu.Lock() @@ -156,14 +163,13 @@ func (wb *Delta) Status() (api.ChargeStatus, error) { // 7: Suspended EVSE // 8: Not ready // 9: Faulted - switch s := encoding.Uint16(b); s { - case 0, 1, 2: + return wb.statusG(encoding.Uint16(b)) +} + +func (wb *Delta) statusBasic(s uint16) (api.ChargeStatus, error) { + switch s { + case 0, 1, 2, 3: return api.StatusA, nil - case 3: - if wb.isBasic { - return api.StatusA, nil - } - return api.StatusB, nil case 5, 6, 7, 9: return api.StatusB, nil case 4: @@ -173,22 +179,31 @@ func (wb *Delta) Status() (api.ChargeStatus, error) { } } -var _ api.StatusReasoner = (*Delta)(nil) +func (wb *Delta) statusSmart(s uint16) (api.ChargeStatus, error) { + switch s { + case 0, 1, 2: + return api.StatusA, nil + case 3, 5, 6, 7, 9: + return api.StatusB, nil + case 4: + return api.StatusC, nil + default: + return api.StatusNone, fmt.Errorf("invalid status: %0x", s) + } +} // statusReason implements the api.StatusReasoner interface -func (wb *Delta) StatusReason() (api.Reason, error) { - if !wb.isBasic { - b, err := wb.conn.ReadInputRegisters(wb.base+deltaRegEvseState, 1) - if err != nil { - return api.ReasonUnknown, err - } +func (wb *Delta) statusReason() (api.Reason, error) { + b, err := wb.conn.ReadInputRegisters(wb.base+deltaRegEvseState, 1) + if err != nil { + return api.ReasonUnknown, err + } - switch s := encoding.Uint16(b); s { - case 3: - return api.ReasonWaitingForAuthorization, nil - case 5: - return api.ReasonDisconnectRequired, nil - } + switch s := encoding.Uint16(b); s { + case 3: + return api.ReasonWaitingForAuthorization, nil + case 5: + return api.ReasonDisconnectRequired, nil } return api.ReasonUnknown, nil diff --git a/charger/delta_decorators.go b/charger/delta_decorators.go new file mode 100644 index 0000000000..53a8de5ea9 --- /dev/null +++ b/charger/delta_decorators.go @@ -0,0 +1,35 @@ +package charger + +// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT. + +import ( + "github.com/evcc-io/evcc/api" +) + +func decorateDelta(base *Delta, statusReasoner func() (api.Reason, error)) api.Charger { + switch { + case statusReasoner == nil: + return base + + case statusReasoner != nil: + return &struct { + *Delta + api.StatusReasoner + }{ + Delta: base, + StatusReasoner: &decorateDeltaStatusReasonerImpl{ + statusReasoner: statusReasoner, + }, + } + } + + return nil +} + +type decorateDeltaStatusReasonerImpl struct { + statusReasoner func() (api.Reason, error) +} + +func (impl *decorateDeltaStatusReasonerImpl) StatusReason() (api.Reason, error) { + return impl.statusReasoner() +}