{"id":30754905,"url":"https://github.com/aliml92/ocpp","last_synced_at":"2026-01-14T23:35:12.264Z","repository":{"id":37714724,"uuid":"495305254","full_name":"aliml92/ocpp","owner":"aliml92","description":"Golang implementation of the Open Charge Point Protocol (OCPP).","archived":false,"fork":false,"pushed_at":"2023-01-31T04:44:29.000Z","size":285,"stargazers_count":25,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-04T10:22:54.877Z","etag":null,"topics":["client","electric-vehicles","ocpp","ocpp16j","ocpp16j-security","server"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aliml92.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-23T07:37:23.000Z","updated_at":"2025-04-24T15:10:24.000Z","dependencies_parsed_at":"2023-02-16T16:00:46.950Z","dependency_job_id":null,"html_url":"https://github.com/aliml92/ocpp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aliml92/ocpp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliml92%2Focpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliml92%2Focpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliml92%2Focpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliml92%2Focpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aliml92","download_url":"https://codeload.github.com/aliml92/ocpp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliml92%2Focpp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28438855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T22:37:52.437Z","status":"ssl_error","status_checked_at":"2026-01-14T22:37:31.496Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","electric-vehicles","ocpp","ocpp16j","ocpp16j-security","server"],"created_at":"2025-09-04T10:01:17.447Z","updated_at":"2026-01-14T23:35:12.256Z","avatar_url":"https://github.com/aliml92.png","language":"Go","funding_links":[],"categories":["Tools and Resources"],"sub_categories":["OCPP"],"readme":"\n# ocpp\n\n[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs)\n\nGolang package implementing the JSON version of the Open Charge Point Protocol (OCPP). Currently OCPP 1.6 and 2.0.1 is supported.\nThe project is initially inspired by [mobility/ocpp](https://github.com/mobilityhouse/ocpp)\n\n## Installation\n\nGo version 1.18+ is required\n\n```bash\n  go get github.com/aliml92/ocpp\n```\n\n ## Features\n\n- [x] ocpp1.6 and ocpp2.0.1 support\n- [x] logging\n- [x] ping/pong customization on `WebSocketPingInterval`\n- [x] server initiated ping activation \n\n## Roadmap\n\n- [ ]   add unit/integration tests\n- [x]   improve logging\n- [ ]   add validation disabling feature\n- [ ]   add better queque implementation\n \n\n## Usage\n\n### Cental System  (Server)\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"go.uber.org/zap\"\n\n\t\"github.com/aliml92/ocpp\"\n\tv16 \"github.com/aliml92/ocpp/v16\"\n)\n\n\nvar csms *ocpp.Server\n\n// log replaces standard log\nvar log *zap.SugaredLogger\n\n\n\nfunc main() \n\tlogger, _ := zap.NewDevelopment()\n\tlog = logger.Sugar()\n\tdefer log.Sync()\n\n\t// set ocpp library's logger to zap logger\n\tocpp.SetLogger(log)\n\n\t// start csms server with default configurations\n\tcsms = ocpp.NewServer()\n\n\tcsms.AddSubProtocol(\"ocpp1.6\")\n\tcsms.SetCheckOriginHandler(func(r *http.Request) bool { return true })\n\tcsms.SetPreUpgradeHandler(customPreUpgradeHandler)\n\tcsms.SetCallQueueSize(32)\t\n\n\t// register charge-point-initiated action handlers\n\tcsms.On(\"BootNotification\", BootNotificationHandler)\n\tcsms.After(\"BootNotification\", SendChangeConfigration)\n\tcsms.On(\"Authorize\", AuthorizationHandler)\n\tcsms.Start(\"0.0.0.0:8999\", \"/ws/\", nil)\n\t\n}\n\nfunc SendChangeConfigration(cp *ocpp.ChargePoint, payload ocpp.Payload) {\n\tvar req ocpp.Payload = v16.ChangeConfigurationReq{\n\t\tKey: \"WebSocketPingInterval\",\n\t\tValue: \"30\",\n\t}\n\tres, err := cp.Call(\"ChangeConfiguration\", req)\n\tif err != nil {\n\t\tlog.Debug(err)\n\t}\n\tlog.Debug(res)\n}\n\n\nfunc customPreUpgradeHandler(w http.ResponseWriter, r *http.Request) bool {\n\tu, p, ok := r.BasicAuth()\n\tif !ok {\n\t\tlog.Debug(\"error parsing basic auth\")\n\t\tw.WriteHeader(401)\n\t\treturn false\n\t}\n\tpath := strings.Split(r.URL.Path, \"/\")\n\tid := path[len(path)-1]\n\tlog.Debugf(\"%s is trying to connect with %s:%s\", id, u, p)\n\tif u != id {\n\t\tlog.Debug(\"username provided is correct: %s\", u)\n\t\tw.WriteHeader(401)\n\t\treturn false\n\t}\n\treturn true\n}\n\n\n\nfunc BootNotificationHandler(cp *ocpp.ChargePoint, p ocpp.Payload) ocpp.Payload {\n\treq := p.(*v16.BootNotificationReq)\n\tlog.Debugf(\"\\nid: %s\\nBootNotification: %v\", cp.Id, req)\n\t\n    var res ocpp.Payload = \u0026v16.BootNotificationConf{\n\t\tCurrentTime: time.Now().Format(\"2006-01-02T15:04:05.000Z\"),\n\t\tInterval:    60 ,\n\t\tStatus:      \"Accepted\",\n\t}\n\treturn res\n}\n\nfunc AuthorizationHandler(cp *ocpp.ChargePoint, p ocpp.Payload) ocpp.Payload {\n\treq := p.(*v16.AuthorizeReq)\n\tlog.Debugf(\"\\nid: %s\\nAuthorizeReq: %v\", cp.Id, req)\n\t\n    var res ocpp.Payload = \u0026v16.AuthorizeConf{\n\t\tIdTagInfo: v16.IdTagInfo{\n\t\t\tStatus: \"Accepted\",\n\t\t},\n\t}\n\treturn res\n}\n```\n`ChargePoint` represents a single Charge Point (CP) connected to Central System\nand after initializing `*ocpp.Server` , register CP initiated call handlers using `csms.On` method.\nMaking a Call can be done by excuting `cp.Call` method.\n\n\n\n### Charge Point (Client)\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\t\"github.com/aliml92/ocpp\"\n\tv16 \"github.com/aliml92/ocpp/v16\"\n\t\"go.uber.org/zap\"\n)\n\n\n\nvar client *ocpp.Client\n\n// log replaces standard log\nvar log *zap.SugaredLogger\n\n// initialize zap logger\n// for deveplopment only\nfunc initLogger() {\n\tlogger, _ := zap.NewDevelopment()\n\tlog = logger.Sugar()\n}\n\nfunc main() {\n\tinitLogger()\n\tdefer log.Sync()\n\n\t// set ocpp library's logger to zap logger\n\tocpp.SetLogger(log)\n\n\t// create client\n\tclient = ocpp.NewClient()\n\tid := \"client00\"\n\tclient.SetID(id)\n\tclient.AddSubProtocol(\"ocpp1.6\")\n\tclient.SetBasicAuth(id, \"dummypass\")\n\tclient.SetCallQueueSize(32)\n\tclient.On(\"ChangeAvailability\", ChangeAvailabilityHandler)\n\tclient.On(\"GetLocalListVersion\", GetLocalListVersionHandler)\n\tclient.On(\"ChangeConfiguration\", ChangeConfigurationHandler)\n\t\n\tcp, err := client.Start(\"ws://localhost:8999\", \"/ws\")\n\tif err != nil {\n\t\tfmt.Printf(\"error dialing: %v\\n\", err)\n\t\treturn\n\t}\n\tsendBootNotification(cp)\n\tdefer cp.Shutdown()\n\tlog.Debugf(\"charge point status %v\", cp.IsConnected())\n\tselect {}\n}\n\nfunc ChangeConfigurationHandler(cp *ocpp.ChargePoint, p ocpp.Payload) ocpp.Payload {\n\treq := p.(*v16.ChangeConfigurationReq)\n\tlog.Debugf(\"ChangeConfigurationReq: %v\\n\", req)\n\tvar res ocpp.Payload = \u0026v16.ChangeConfigurationConf{\n\t\tStatus: \"Accepted\",\n\t}\n\treturn res\n}\n\nLater use\nfunc ChangeAvailabilityHandler(cp *ocpp.ChargePoint, p ocpp.Payload) ocpp.Payload {\n\treq := p.(*v16.ChangeAvailabilityReq)\n\tlog.Debugf(\"ChangeAvailability: %v\\n\", req)\n\tvar res ocpp.Payload = \u0026v16.ChangeAvailabilityConf{\n\t\tStatus: \"Accepted\",\n\t}\n\treturn res\n}\n\nfunc GetLocalListVersionHandler(cp *ocpp.ChargePoint, p ocpp.Payload) ocpp.Payload {\n\treq := p.(*v16.GetLocalListVersionReq)\n\tlog.Debugf(\"GetLocalListVersionReq: %v\\n\", req)\n\tvar res ocpp.Payload = \u0026v16.GetLocalListVersionConf{\n\t\tListVersion: 1,\n\t}\n\treturn res\n}\n\nfunc sendBootNotification(c *ocpp.ChargePoint) {\n\treq := \u0026v16.BootNotificationReq{\n\t\tChargePointModel:  \"client00\",\n\t\tChargePointVendor: \"VendorX\",\n\t}\n\tres, err := c.Call(\"BootNotification\", req)\n\tif err != nil {\n\t\tfmt.Printf(\"error dialing: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"BootNotificationConf: %v\\n\", res)\n}\n\n\nfunc sendAuthorize(c *ocpp.ChargePoint) {\n\treq := \u0026v16.AuthorizeReq{\n\t\tIdTag: \"safdasdfdsa\",\n\t}\n\tres, err := c.Call(\"Authorize\", req, 10)\n\tif err != nil {\n\t\tfmt.Printf(\"error dialing: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"AuthorizeConf: %v\\n\", res)\n}\n```\nAfter creating `*ocpp.Client` instance, register CS (Central System) initiated call handlers.\nMaking a call to CS is same as the above snippet where just call `cp.Call` method.\n## Contributing\n\nContributions are always welcome!\nImplementing higher versions of ocpp is highly appreciated!\n\nSee `CONTRIBUTING.md` for ways to get started.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliml92%2Focpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faliml92%2Focpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliml92%2Focpp/lists"}