OpenWB 2.0: add power/energy and support multiple connectors (#11010)

This commit is contained in:
andig 2023-12-05 11:31:39 +01:00 • committed by GitHub
parent 94b0b890a8
commit 718bf14137
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 14 deletions

View file

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

View file

@ -13,6 +13,9 @@ params:
choice: ["tcpip"]
port: 1502
id: 1
- name: connector
default: 1
render: |
type: openwb-2.0
{{- include "modbus" . }}
connector: {{ .connector }}