Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ocpp: move get/set charging profile to connector #15660

Merged
merged 11 commits into from
Sep 5, 2024
47 changes: 2 additions & 45 deletions charger/ocpp.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/evcc-io/evcc/core/loadpoint"
"github.com/evcc-io/evcc/util"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/core"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
)

Expand Down Expand Up @@ -289,7 +288,7 @@ func (c *OCPP) Enabled() (bool, error) {
}

// fallback to querying the active charging profile schedule limit
if v, err := c.getScheduleLimit(); err == nil {
if v, err := c.conn.GetScheduleLimit(60); err == nil {
return v > 0, nil
}

Expand Down Expand Up @@ -329,58 +328,16 @@ func (c *OCPP) initTransaction() error {
return ocpp.Wait(err, rc)
}

func (c *OCPP) setChargingProfile(profile *types.ChargingProfile) error {
rc := make(chan error, 1)
err := ocpp.Instance().SetChargingProfile(c.cp.ID(), func(resp *smartcharging.SetChargingProfileConfirmation, err error) {
if err == nil && resp != nil && resp.Status != smartcharging.ChargingProfileStatusAccepted {
err = errors.New(string(resp.Status))
}

rc <- err
}, c.conn.ID(), profile)

return ocpp.Wait(err, rc)
}

// setCurrent sets the TxDefaultChargingProfile with given current
func (c *OCPP) setCurrent(current float64) error {
err := c.setChargingProfile(c.createTxDefaultChargingProfile(math.Trunc(10*current) / 10))
err := c.conn.SetChargingProfile(c.createTxDefaultChargingProfile(math.Trunc(10*current) / 10))
if err != nil {
err = fmt.Errorf("set charging profile: %w", err)
}

return err
}

// getScheduleLimit queries the current or power limit the charge point is currently set to offer
func (c *OCPP) getScheduleLimit() (float64, error) {
const duration = 60 // duration of requested schedule in seconds

var limit float64

rc := make(chan error, 1)
err := ocpp.Instance().GetCompositeSchedule(c.cp.ID(), func(resp *smartcharging.GetCompositeScheduleConfirmation, err error) {
if err == nil && resp != nil && resp.Status != smartcharging.GetCompositeScheduleStatusAccepted {
err = errors.New(string(resp.Status))
}

if err == nil {
if resp.ChargingSchedule != nil && len(resp.ChargingSchedule.ChargingSchedulePeriod) > 0 {
// return first (current) period limit
limit = resp.ChargingSchedule.ChargingSchedulePeriod[0].Limit
} else {
err = fmt.Errorf("invalid ChargingSchedule")
}
}

rc <- err
}, c.conn.ID(), duration)

err = ocpp.Wait(err, rc)

return limit, err
}

// createTxDefaultChargingProfile returns a TxDefaultChargingProfile with given current
func (c *OCPP) createTxDefaultChargingProfile(current float64) *types.ChargingProfile {
phases := c.phases
Expand Down
21 changes: 21 additions & 0 deletions charger/ocpp/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ func (conn *Connector) TriggerMessageRequest(feature remotetrigger.MessageTrigge
})
}

func (conn *Connector) SetChargingProfile(profile *types.ChargingProfile) error {
return Instance().SetChargingProfileRequest(conn.cp.ID(), conn.id, profile)
}

// getScheduleLimit queries the current or power limit the charge point is currently set to offer
func (conn *Connector) GetScheduleLimit(duration int) (float64, error) {
andig marked this conversation as resolved.
Show resolved Hide resolved
var limit float64
schedule, err := Instance().GetCompositeScheduleRequest(conn.cp.ID(), conn.id, duration)

if err == nil {
if schedule != nil && len(schedule.ChargingSchedulePeriod) > 0 {
// return first (current) period limit
limit = schedule.ChargingSchedulePeriod[0].Limit
} else {
err = fmt.Errorf("invalid ChargingSchedule")
}
}

return limit, err
}

// WatchDog triggers meter values messages if older than timeout.
// Must be wrapped in a goroutine.
func (conn *Connector) WatchDog(timeout time.Duration) {
Expand Down
35 changes: 35 additions & 0 deletions charger/ocpp/cs_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/lorenzodonini/ocpp-go/ocpp1.6/core"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/firmware"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
)

// cs actions
Expand Down Expand Up @@ -52,6 +54,39 @@ func (cs *CS) ChangeAvailabilityRequest(id string, connector int, availabilityTy
return Wait(err, rc)
}

func (cs *CS) SetChargingProfileRequest(id string, connector int, profile *types.ChargingProfile) error {
rc := make(chan error, 1)

err := cs.SetChargingProfile(id, func(request *smartcharging.SetChargingProfileConfirmation, err error) {
if err == nil && request != nil && request.Status != smartcharging.ChargingProfileStatusAccepted {
err = errors.New(string(request.Status))
}

rc <- err
}, connector, profile)

return Wait(err, rc)
}

func (cs *CS) GetCompositeScheduleRequest(id string, connector int, duration int) (*types.ChargingSchedule, error) {
var schedule *types.ChargingSchedule
rc := make(chan error, 1)

err := cs.GetCompositeSchedule(id, func(request *smartcharging.GetCompositeScheduleConfirmation, err error) {
if err == nil && request != nil && request.Status != smartcharging.GetCompositeScheduleStatusAccepted {
err = errors.New(string(request.Status))
}

schedule = request.ChargingSchedule

rc <- err
}, connector, duration)

err = Wait(err, rc)

return schedule, err
}

// cp actions

func (cs *CS) OnAuthorize(id string, request *core.AuthorizeRequest) (*core.AuthorizeConfirmation, error) {
Expand Down
Loading