diff --git a/charger/em2go.go b/charger/em2go.go index 693682b77..2a4e413f3 100644 --- a/charger/em2go.go +++ b/charger/em2go.go @@ -32,8 +32,11 @@ import ( // Em2Go charger implementation type Em2Go struct { - log *util.Logger - conn *modbus.Connection + log *util.Logger + conn *modbus.Connection + current int64 + workaround bool + phases int } const ( @@ -59,18 +62,14 @@ const ( ) func init() { - registry.Add("em2go", func(other map[string]any) (api.Charger, error) { - return NewEm2GoFromConfig(other, true) - }) - registry.Add("em2go-home", func(other map[string]any) (api.Charger, error) { - return NewEm2GoFromConfig(other, false) - }) + registry.Add("em2go", NewEm2GoFromConfig) + registry.Add("em2go-home", NewEm2GoFromConfig) } //go:generate go run ../cmd/tools/decorate.go -f decorateEm2Go -b *Em2Go -r api.Charger -t "api.ChargerEx,MaxCurrentMillis,func(float64) error" -t "api.PhaseSwitcher,Phases1p3p,func(int) error" -t "api.PhaseGetter,GetPhases,func() (int, error)" // NewEm2GoFromConfig creates a Em2Go charger from generic config -func NewEm2GoFromConfig(other map[string]interface{}, milli bool) (api.Charger, error) { +func NewEm2GoFromConfig(other map[string]interface{}) (api.Charger, error) { cc := modbus.TcpSettings{ ID: 255, } @@ -79,11 +78,11 @@ func NewEm2GoFromConfig(other map[string]interface{}, milli bool) (api.Charger, return nil, err } - return NewEm2Go(cc.URI, cc.ID, milli) + return NewEm2Go(cc.URI, cc.ID) } // NewEm2Go creates Em2Go charger -func NewEm2Go(uri string, slaveID uint8, milli bool) (api.Charger, error) { +func NewEm2Go(uri string, slaveID uint8) (api.Charger, error) { uri = util.DefaultPort(uri, 502) conn, err := modbus.NewConnection(uri, "", "", 0, modbus.Tcp, slaveID) @@ -98,8 +97,10 @@ func NewEm2Go(uri string, slaveID uint8, milli bool) (api.Charger, error) { conn.Logger(log.TRACE) wb := &Em2Go{ - log: log, - conn: conn, + log: log, + conn: conn, + current: 6, + workaround: false, } var ( @@ -108,7 +109,20 @@ func NewEm2Go(uri string, slaveID uint8, milli bool) (api.Charger, error) { phasesG func() (int, error) ) - if milli { + // test if workaround is needed (Home fw <1.3) + if err := wb.maxCurrentMillis(6.1); err != nil { + return nil, err + } + + chargerCurrent, err := wb.GetMaxCurrent() + if err != nil { + return nil, err + } + + // did rounding occur? + if chargerCurrent == 6 { + wb.workaround = true + } else { maxCurrent = wb.maxCurrentMillis } @@ -158,8 +172,22 @@ func (wb *Em2Go) Enable(enable bool) error { b := make([]byte, 2) binary.BigEndian.PutUint16(b, map[bool]uint16{true: 1, false: 2}[enable]) - _, err := wb.conn.WriteMultipleRegisters(em2GoRegChargeCommand, 1, b) - return err + if _, err := wb.conn.WriteMultipleRegisters(em2GoRegChargeCommand, 1, b); err != nil { + return err + } + + // re-set 1p if required + if wb.workaround && wb.phases == 1 && enable { + binary.BigEndian.PutUint16(b, uint16(wb.phases)) + if _, err := wb.conn.WriteMultipleRegisters(em2GoRegPhases, 1, b); err != nil { + return err + } + + // send default current + return wb.MaxCurrent(wb.current) + } + + return nil } // MaxCurrent implements the api.Charger interface @@ -268,10 +296,34 @@ func (wb *Em2Go) ChargeDuration() (time.Duration, error) { // phases1p3p implements the api.PhaseSwitcher interface func (wb *Em2Go) phases1p3p(phases int) error { + if wb.workaround { + // when enabled, disable, wait 10 seconds, enable and set phases + enabled, err := wb.Enabled() + if err != nil { + return err + } + + if enabled { + if err := wb.Enable(false); err != nil { + return err + } + + time.Sleep(10 * time.Second) + + if err := wb.Enable(true); err != nil { + return err + } + } + } + b := make([]byte, 2) binary.BigEndian.PutUint16(b, uint16(phases)) _, err := wb.conn.WriteMultipleRegisters(em2GoRegPhases, 1, b) + if err == nil { + wb.phases = phases + } + return err } diff --git a/templates/definition/charger/em2go-home.yaml b/templates/definition/charger/em2go-home.yaml index 2334fa2b5..0da1e4b21 100644 --- a/templates/definition/charger/em2go-home.yaml +++ b/templates/definition/charger/em2go-home.yaml @@ -3,11 +3,11 @@ products: - brand: EM2GO description: generic: Home -capabilities: ["1p3p"] +capabilities: ["1p3p", "mA"] requirements: description: - de: "Benötigt Firmware version E3C_V1.1 oder neuer." - en: "Requires Firmware version E3C_V1.1 or newer." + de: "Benötigt FW version >= E3C_V1.1. mA Regelung benötigt FW version >= E3C_V1.3." + en: "Requires FW Version >= E3C_V1.1. mA regulation requires FW version >= E3C_V1.3." params: - name: host render: |