diff --git a/charger/openwb-2.0.go b/charger/openwb-2.0.go index bf24a16e1..4565a4624 100644 --- a/charger/openwb-2.0.go +++ b/charger/openwb-2.0.go @@ -13,6 +13,7 @@ import ( type OpenWB20 struct { conn *modbus.Connection curr uint16 + base uint16 } const ( @@ -42,15 +43,21 @@ func init() { // NewOpenWB20FromConfig creates a OpenWB20 charger from generic config func NewOpenWB20FromConfig(other map[string]interface{}) (api.Charger, error) { - cc := modbus.TcpSettings{ - ID: 1, + cc := struct { + Connector uint16 + modbus.TcpSettings `mapstructure:",squash"` + }{ + Connector: 1, + TcpSettings: modbus.TcpSettings{ + ID: 1, + }, } if err := util.DecodeOther(other, &cc); err != nil { return nil, err } - wb, err := NewOpenWB20(cc.URI, cc.ID) + wb, err := NewOpenWB20(cc.URI, cc.ID, cc.Connector) if err != nil { return nil, err } @@ -64,7 +71,7 @@ func NewOpenWB20FromConfig(other map[string]interface{}) (api.Charger, error) { } // NewOpenWB20 creates OpenWB20 charger -func NewOpenWB20(uri string, slaveID uint8) (*OpenWB20, error) { +func NewOpenWB20(uri string, slaveID uint8, connector uint16) (*OpenWB20, error) { uri = util.DefaultPort(uri, 1502) conn, err := modbus.NewConnection(uri, "", "", 0, modbus.Tcp, slaveID) @@ -78,6 +85,7 @@ func NewOpenWB20(uri string, slaveID uint8) (*OpenWB20, error) { wb := &OpenWB20{ conn: conn, curr: 6 * 100, + base: (connector - 1) * 100, } return wb, nil @@ -85,11 +93,11 @@ func NewOpenWB20(uri string, slaveID uint8) (*OpenWB20, error) { // Status implements the api.Charger interface func (wb *OpenWB20) Status() (api.ChargeStatus, error) { - if b, err := wb.conn.ReadInputRegisters(openwbRegCharging, 1); err != nil || binary.BigEndian.Uint16(b) == 1 { + if b, err := wb.conn.ReadInputRegisters(wb.base+openwbRegCharging, 1); err != nil || binary.BigEndian.Uint16(b) == 1 { return api.StatusC, err } - if b, err := wb.conn.ReadInputRegisters(openwbRegPlugged, 1); err != nil || binary.BigEndian.Uint16(b) == 1 { + if b, err := wb.conn.ReadInputRegisters(wb.base+openwbRegPlugged, 1); err != nil || binary.BigEndian.Uint16(b) == 1 { return api.StatusB, err } @@ -98,7 +106,7 @@ func (wb *OpenWB20) Status() (api.ChargeStatus, error) { // Enabled implements the api.Charger interface func (wb *OpenWB20) Enabled() (bool, error) { - b, err := wb.conn.ReadInputRegisters(openwbRegActualAmps, 1) + b, err := wb.conn.ReadInputRegisters(wb.base+openwbRegActualAmps, 1) if err != nil { return false, err } @@ -107,7 +115,7 @@ func (wb *OpenWB20) Enabled() (bool, error) { } func (wb *OpenWB20) setCurrent(u uint16) error { - _, err := wb.conn.WriteSingleRegister(openwbRegCurrent, u) + _, err := wb.conn.WriteSingleRegister(wb.base+openwbRegCurrent, u) return err } @@ -143,6 +151,28 @@ func (wb *OpenWB20) MaxCurrentMillis(current float64) error { return err } +var _ api.Meter = (*OpenWB20)(nil) + +// CurrentPower implements the api.Meter interface +func (wb *OpenWB20) CurrentPower() (float64, error) { + b, err := wb.conn.ReadInputRegisters(wb.base+openwbRegPower, 2) + if err != nil { + return 0, err + } + return float64(int32(binary.BigEndian.Uint32(b))), nil +} + +var _ api.MeterEnergy = (*OpenWB20)(nil) + +// TotalEnergy implements the api.MeterEnergy interface +func (wb *OpenWB20) TotalEnergy() (float64, error) { + b, err := wb.conn.ReadInputRegisters(wb.base+openwbRegImport, 2) + if err != nil { + return 0, err + } + return float64(binary.BigEndian.Uint32(b)) / 1e3, nil +} + // getPhaseValues returns phase values func (wb *OpenWB20) getPhaseValues(reg uint16) (float64, float64, float64, error) { b, err := wb.conn.ReadInputRegisters(reg, 3) @@ -162,25 +192,25 @@ var _ api.PhaseCurrents = (*OpenWB20)(nil) // Currents implements the api.PhaseCurrents interface func (wb *OpenWB20) Currents() (float64, float64, float64, error) { - return wb.getPhaseValues(openwbRegCurrents) + return wb.getPhaseValues(wb.base + openwbRegCurrents) } var _ api.PhaseVoltages = (*OpenWB20)(nil) // Voltages implements the api.PhaseVoltages interface func (wb *OpenWB20) Voltages() (float64, float64, float64, error) { - return wb.getPhaseValues(openwbRegVoltages) + return wb.getPhaseValues(wb.base + openwbRegVoltages) } var _ api.PhaseSwitcher = (*OpenWB20)(nil) // Phases1p3p implements the api.PhaseSwitcher interface func (wb *OpenWB20) Phases1p3p(phases int) error { - if _, err := wb.conn.WriteSingleRegister(openwbRegPhaseTarget, uint16(phases)); err != nil { + if _, err := wb.conn.WriteSingleRegister(wb.base+openwbRegPhaseTarget, uint16(phases)); err != nil { return err } - _, err := wb.conn.WriteSingleRegister(openwbRegPhaseTrigger, 1) + _, err := wb.conn.WriteSingleRegister(wb.base+openwbRegPhaseTrigger, 1) return err } @@ -188,13 +218,13 @@ var _ api.Resurrector = (*OpenWB20)(nil) // WakeUp implements the api.Resurrector interface func (wb *OpenWB20) WakeUp() error { - _, err := wb.conn.WriteSingleRegister(openwbRegCpTrigger, 1) + _, err := wb.conn.WriteSingleRegister(wb.base+openwbRegCpTrigger, 1) return err } // Identify implements the api.Identifier interface func (wb *OpenWB20) identify() (string, error) { - b, err := wb.conn.ReadInputRegisters(openwbRegRfid, 10) + b, err := wb.conn.ReadInputRegisters(wb.base+openwbRegRfid, 10) if err != nil { return "", err } diff --git a/templates/definition/charger/openwb-2.0.yaml b/templates/definition/charger/openwb-2.0.yaml index 1edb10dd3..3564f4206 100644 --- a/templates/definition/charger/openwb-2.0.yaml +++ b/templates/definition/charger/openwb-2.0.yaml @@ -13,6 +13,9 @@ params: choice: ["tcpip"] port: 1502 id: 1 + - name: connector + default: 1 render: | type: openwb-2.0 {{- include "modbus" . }} + connector: {{ .connector }}