package ocpp import ( "net/http" "sync" "time" "github.com/evcc-io/evcc/util" "github.com/lorenzodonini/ocpp-go/ocpp" ocpp16 "github.com/lorenzodonini/ocpp-go/ocpp1.6" "github.com/lorenzodonini/ocpp-go/ocpp1.6/core" "github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger" "github.com/lorenzodonini/ocpp-go/ocpp1.6/security" "github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging" "github.com/lorenzodonini/ocpp-go/ocppj" "github.com/lorenzodonini/ocpp-go/ws" ) var ( once sync.Once instance *CS ) func Instance() *CS { once.Do(func() { log := util.NewLogger("ocpp") server := ws.NewServer() server.SetCheckOriginHandler(func(r *http.Request) bool { return true }) dispatcher := ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(0)) dispatcher.SetTimeout(Timeout) endpoint := ocppj.NewServer(server, dispatcher, nil, core.Profile, remotetrigger.Profile, smartcharging.Profile, security.Profile) endpoint.SetInvalidMessageHook(func(client ws.Channel, err *ocpp.Error, rawMessage string, parsedFields []any) *ocpp.Error { log.ERROR.Printf("%v (%s)", err, rawMessage) return nil }) cs := ocpp16.NewCentralSystem(endpoint, server) instance = &CS{ log: log, regs: make(map[string]*registration), CentralSystem: cs, } instance.txnId.Store(time.Now().UTC().Unix()) ocppj.SetLogger(instance) cs.SetCoreHandler(instance) cs.SetSecurityHandler(instance) cs.SetNewChargePointHandler(instance.NewChargePoint) cs.SetChargePointDisconnectedHandler(instance.ChargePointDisconnected) go instance.errorHandler(cs.Errors()) go cs.Start(8887, "/{ws}") // wait for server to start for range time.Tick(10 * time.Millisecond) { if dispatcher.IsRunning() { break } } }) return instance }