Skip to content

Commit

Permalink
openWB: fix implementation to work with "Nur Ladepunkt" mode (#1895)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig committed Nov 30, 2021
1 parent 07c8d66 commit fe49451
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 17 deletions.
93 changes: 77 additions & 16 deletions charger/openwb.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ func init() {

// OpenWB configures generic charger and charge meter for an openWB loadpoint
type OpenWB struct {
api.Charger
current int64
enabledG func() (int64, error)
statusG func() (string, error)
currentS func(int64) error
currentPowerG func() (float64, error)
totalEnergyG func() (float64, error)
currentsG []func() (float64, error)
Expand Down Expand Up @@ -72,6 +75,16 @@ func NewOpenWB(log *util.Logger, mqttconf mqtt.Config, id int, topic string, p1p
}
}

intG := func(topic string) func() (int64, error) {
g := provider.NewMqtt(log, client, topic, 1, 0).IntGetter()
return func() (val int64, err error) {
if val, err = g(); err == nil {
_, err = timer()
}
return val, err
}
}

floatG := func(topic string) func() (float64, error) {
g := provider.NewMqtt(log, client, topic, 1, 0).FloatGetter()
return func() (val float64, err error) {
Expand All @@ -93,16 +106,19 @@ func NewOpenWB(log *util.Logger, mqttconf mqtt.Config, id int, topic string, p1p
chargingG := boolG(fmt.Sprintf("%s/lp/%d/%s", topic, id, openwb.ChargingTopic))
statusG := provider.NewOpenWBStatusProvider(pluggedG, chargingG).StringGetter

// remaining getters
enabledG := boolG(fmt.Sprintf("%s/lp/%d/%s", topic, id, openwb.EnabledTopic))
// getters
enabledG := intG(fmt.Sprintf("%s/lp/%d/%s", topic, id, openwb.MaxCurrentTopic))

// setters
enableS := provider.NewMqtt(log, client,
fmt.Sprintf("%s/set/lp%d/%s", topic, id, openwb.EnabledTopic),
1, timeout).WithPayload("${enable:%d}").BoolSetter("enable")
maxcurrentS := provider.NewMqtt(log, client,
fmt.Sprintf("%s/set/lp%d/%s", topic, id, openwb.MaxCurrentTopic),
1, timeout).IntSetter("maxcurrent")
currentTopic := openwb.SlaveChargeCurrentTopic
if id == 2 {
// TODO remove after https://github.com/snaptec/openWB/issues/1757
currentTopic = "Lp2" + openwb.SlaveChargeCurrentTopic
}
currentS := provider.NewMqtt(log, client,
fmt.Sprintf("%s/set/isss/%s", topic, currentTopic),
1, timeout).IntSetter("current")

authS := provider.NewMqtt(log, client,
fmt.Sprintf("%s/set/chargepoint/%d/get/%s", topic, id, openwb.RfidTopic),
1, timeout).StringSetter("rfid")
Expand All @@ -117,25 +133,40 @@ func NewOpenWB(log *util.Logger, mqttconf mqtt.Config, id int, topic string, p1p
currentsG = append(currentsG, current)
}

charger, err := NewConfigurable(statusG, enabledG, enableS, maxcurrentS)
if err != nil {
return nil, err
}

c := &OpenWB{
Charger: charger,
currentS: currentS,
enabledG: enabledG,
statusG: statusG,
currentPowerG: currentPowerG,
totalEnergyG: totalEnergyG,
currentsG: currentsG,
authS: authS,
}

// heartbeat
go func() {
heartbeatS := provider.NewMqtt(log, client,
fmt.Sprintf("%s/set/lp%d/%s", topic, id, openwb.SlaveHeartbeatTopic),
1, timeout).IntSetter("heartbeat")

for range time.NewTicker(openwb.HeartbeatInterval).C {
if err := heartbeatS(1); err != nil {
log.ERROR.Printf("heartbeat: %v", err)
}
}
}()

// optional capabilities

var phases func(int) error
if p1p3 {
phasesTopic := openwb.SlavePhasesTopic
if id == 2 {
// TODO remove after https://github.com/snaptec/openWB/issues/1757
phasesTopic += "Lp2"
}
phasesS := provider.NewMqtt(log, client,
fmt.Sprintf("%s/set/isss/%s", topic, openwb.PhasesTopic),
fmt.Sprintf("%s/set/isss/%s", topic, phasesTopic),
1, timeout).IntSetter("phases")

phases = func(phases int) error {
Expand All @@ -151,6 +182,36 @@ func NewOpenWB(log *util.Logger, mqttconf mqtt.Config, id int, topic string, p1p
return decorateOpenWB(c, phases, soc), nil
}

func (m *OpenWB) Enable(enable bool) error {
var current int64
if enable {
current = m.current
}

return m.currentS(current)
}

func (m *OpenWB) Enabled() (bool, error) {
current, err := m.enabledG()
return current > 0, err
}

func (m *OpenWB) Status() (api.ChargeStatus, error) {
status, err := m.statusG()
if err != nil {
return api.StatusNone, err
}
return api.ChargeStatus(status), nil
}

func (m *OpenWB) MaxCurrent(current int64) error {
err := m.currentS(current)
if err == nil {
m.current = current
}
return err
}

var _ api.Meter = (*OpenWB)(nil)

// CurrentPower implements the api.Meter interface
Expand Down
21 changes: 20 additions & 1 deletion charger/openwb/topics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import "time"

// predefined openWB topic names
const (
Timeout = 15 * time.Second
Timeout = 15 * time.Second
HeartbeatInterval = 10 * time.Second // loadpoint only client heartbeat

// root topic
RootTopic = "openWB"
Expand Down Expand Up @@ -38,4 +39,22 @@ const (
// configuration
PvConfigured = "boolPVConfigured"
BatteryConfigured = "boolHouseBatteryConfigured"

// loadpoint only topics

// TODO cleanup after https://github.com/snaptec/openWB/issues/1757
// openWB/set/isss/heartbeat
// openWB/set/isss/ClearRfid
// openWB/set/isss/Cpulp1
// openWB/set/isss/Current
// openWB/set/isss/Lp2Current
// openWB/set/isss/U1p3p
// openWB/set/isss/U1p3pLp2

SlaveSetter = "set/isss"

SlaveHeartbeatTopic = "heartbeat"
SlaveChargeCurrentTopic = "Current"
SlavePhasesTopic = "U1p3p"
SlaveClearRfidTopic = "ClearRfid"
)

0 comments on commit fe49451

Please sign in to comment.