Add basic OCPP support (#395)
This commit is contained in:
parent
9bd8754b85
commit
29ea3c6549
20 changed files with 618 additions and 130 deletions
|
|
@ -86,6 +86,7 @@ type LoadPoint struct {
|
|||
|
||||
// cached state
|
||||
status api.ChargeStatus // Charger status
|
||||
remoteDemand RemoteDemand // External status demand
|
||||
charging bool // Charging cycle
|
||||
chargePower float64 // Charging power
|
||||
connectedTime time.Time // Time when vehicle was connected
|
||||
|
|
@ -412,6 +413,14 @@ func (lp *LoadPoint) climateActive() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// remoteControlled returns true if remote control status is active
|
||||
func (lp *LoadPoint) remoteControlled(demand RemoteDemand) bool {
|
||||
lp.Lock()
|
||||
defer lp.Unlock()
|
||||
|
||||
return lp.remoteDemand == demand
|
||||
}
|
||||
|
||||
// setActiveVehicle assigns currently active vehicle and configures soc estimator
|
||||
func (lp *LoadPoint) setActiveVehicle(vehicle api.Vehicle) {
|
||||
if lp.vehicle != nil {
|
||||
|
|
@ -703,7 +712,7 @@ func (lp *LoadPoint) publishSoC() {
|
|||
// Update is the main control function. It reevaluates meters and charger state
|
||||
func (lp *LoadPoint) Update(sitePower float64) {
|
||||
mode := lp.GetMode()
|
||||
lp.publish("mode", string(mode))
|
||||
lp.publish("mode", mode)
|
||||
|
||||
// read and publish meters first
|
||||
lp.updateChargeMeter()
|
||||
|
|
@ -741,6 +750,9 @@ func (lp *LoadPoint) Update(sitePower float64) {
|
|||
// check if car connected and ready for charging
|
||||
var err error
|
||||
|
||||
// track if remote disabled is actually active
|
||||
remoteDisabled := RemoteEnable
|
||||
|
||||
// execute loading strategy
|
||||
switch {
|
||||
case !lp.connected():
|
||||
|
|
@ -755,6 +767,11 @@ func (lp *LoadPoint) Update(sitePower float64) {
|
|||
}
|
||||
err = lp.handler.Ramp(targetCurrent, true)
|
||||
|
||||
// OCPP
|
||||
case lp.remoteControlled(RemoteHardDisable):
|
||||
remoteDisabled = RemoteHardDisable
|
||||
fallthrough
|
||||
|
||||
case mode == api.ModeOff:
|
||||
err = lp.handler.Ramp(0, true)
|
||||
|
||||
|
|
@ -775,9 +792,19 @@ func (lp *LoadPoint) Update(sitePower float64) {
|
|||
required = true
|
||||
}
|
||||
|
||||
// Sunny Home Manager
|
||||
if mode == api.ModePV && lp.remoteControlled(RemoteSoftDisable) {
|
||||
remoteDisabled = RemoteSoftDisable
|
||||
targetCurrent = 0
|
||||
required = true
|
||||
}
|
||||
|
||||
err = lp.handler.Ramp(targetCurrent, required)
|
||||
}
|
||||
|
||||
// effective disabled status
|
||||
lp.publish("remoteDisabled", remoteDisabled)
|
||||
|
||||
if err != nil {
|
||||
lp.log.ERROR.Println(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ type LoadPointSettingsAPI interface {
|
|||
SetTargetSoC(int) error
|
||||
GetMinSoC() int
|
||||
SetMinSoC(int) error
|
||||
RemoteControl(string, RemoteDemand)
|
||||
}
|
||||
|
||||
// LoadPointEnergyAPI is the external loadpoint API
|
||||
|
|
@ -109,6 +110,24 @@ func (lp *LoadPoint) SetMinSoC(soc int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RemoteControl sets remote status demand
|
||||
func (lp *LoadPoint) RemoteControl(source string, demand RemoteDemand) {
|
||||
lp.Lock()
|
||||
defer lp.Unlock()
|
||||
|
||||
lp.log.INFO.Println("remote demand:", demand)
|
||||
|
||||
// apply immediately
|
||||
if lp.remoteDemand != demand {
|
||||
lp.remoteDemand = demand
|
||||
|
||||
lp.publish("remoteDisabled", demand)
|
||||
lp.publish("remoteDisabledSource", source)
|
||||
|
||||
lp.requestUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
// HasChargeMeter determines if a physical charge meter is attached
|
||||
func (lp *LoadPoint) HasChargeMeter() bool {
|
||||
_, isWrapped := lp.chargeMeter.(*wrapper.ChargeMeter)
|
||||
|
|
|
|||
11
core/remote.go
Normal file
11
core/remote.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package core
|
||||
|
||||
// RemoteDemand defines external status demand
|
||||
type RemoteDemand string
|
||||
|
||||
// remote status demand definition
|
||||
const (
|
||||
RemoteEnable RemoteDemand = ""
|
||||
RemoteHardDisable RemoteDemand = "hard"
|
||||
RemoteSoftDisable RemoteDemand = "soft"
|
||||
)
|
||||
|
|
@ -62,3 +62,11 @@ func (site *Site) SetMinSoC(soc int) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoteControl sets remote status demand
|
||||
func (site *Site) RemoteControl(source string, demand RemoteDemand) {
|
||||
site.log.INFO.Println("remote demand:", demand)
|
||||
for _, lp := range site.loadpoints {
|
||||
lp.RemoteControl(source, demand)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue