Skip to content

Commit

Permalink
OpenWB 2.0: add power/energy and support multiple connectors (#11010)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Dec 5, 2023
1 parent 94b0b89 commit 718bf14
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
58 changes: 44 additions & 14 deletions charger/openwb-2.0.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
type OpenWB20 struct {
conn *modbus.Connection
curr uint16
base uint16
}

const (
Expand Down Expand Up @@ -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
}
Expand All @@ -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)
Expand All @@ -78,18 +85,19 @@ func NewOpenWB20(uri string, slaveID uint8) (*OpenWB20, error) {
wb := &OpenWB20{
conn: conn,
curr: 6 * 100,
base: (connector - 1) * 100,
}

return wb, nil
}

// 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
}

Expand All @@ -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
}
Expand All @@ -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
}

Expand Down Expand Up @@ -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)
Expand All @@ -162,39 +192,39 @@ 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
}

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
}
Expand Down
3 changes: 3 additions & 0 deletions templates/definition/charger/openwb-2.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ params:
choice: ["tcpip"]
port: 1502
id: 1
- name: connector
default: 1
render: |
type: openwb-2.0
{{- include "modbus" . }}
connector: {{ .connector }}

0 comments on commit 718bf14

Please sign in to comment.