├── .github ├── dco.yml └── workflows │ ├── check-links.yml │ ├── delete-deploy.yml │ ├── end-to-end-tests.yml │ ├── gateway.yml │ ├── manager.yml │ └── pre-commit.yml ├── .gitignore ├── .hook ├── check-talisman-files.sh └── sort-talismanrc.sh ├── .pre-commit-config.yaml ├── .talismanrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── adr ├── ADR-001-TechChoiceForCsms.md ├── ADR-002-TechChoiceForMocks.md ├── ADR-003-HowToEnableHorizontalScalability.md └── ADR-004-Datastore.md ├── config ├── certificates │ ├── .gitkeep │ └── Makefile ├── envoy │ └── envoy.yaml ├── manager │ └── config.toml └── mosquitto │ └── mosquitto.conf ├── docker-compose-with-lb.yml ├── docker-compose.yml ├── docs ├── assets │ ├── gateway.png │ ├── manager.png │ └── scaling.png ├── design.md ├── extending-manager.md ├── gateway.md └── manager.md ├── e2e_tests ├── Makefile ├── README.md ├── docker-compose.yml ├── everest │ ├── config │ │ ├── certificates │ │ │ ├── HUBOpenProvCert001.pem │ │ │ ├── HUBOpenProvCert002.pem │ │ │ ├── HUBOpenProvCert003.pem │ │ │ ├── HUBOpenProvCert005-EMP77TWTW99999-Revoked.pem │ │ │ ├── root-V2G-cert.pem │ │ │ └── trust.pem │ │ └── everest │ │ │ ├── README.md │ │ │ ├── certs │ │ │ ├── ca │ │ │ │ ├── csms │ │ │ │ │ └── .gitkeep │ │ │ │ ├── cso │ │ │ │ │ └── .gitkeep │ │ │ │ ├── oem │ │ │ │ │ └── .gitkeep │ │ │ │ └── v2g │ │ │ │ │ └── .gitkeep │ │ │ └── client │ │ │ │ ├── csms │ │ │ │ └── .gitkeep │ │ │ │ ├── cso │ │ │ │ └── .gitkeep │ │ │ │ └── oem │ │ │ │ └── .gitkeep │ │ │ ├── config-sil-ocpp-pnc.yaml │ │ │ ├── config-sil-ocpp.yaml │ │ │ ├── config-sil-ocpp201.yaml │ │ │ ├── default_logging.cfg │ │ │ ├── ocpp │ │ │ ├── OCPP │ │ │ │ ├── config.json │ │ │ │ ├── init.sql │ │ │ │ ├── logging.ini │ │ │ │ ├── profile_schemas │ │ │ │ │ ├── Config.json │ │ │ │ │ ├── Core.json │ │ │ │ │ ├── Custom.json │ │ │ │ │ ├── FirmwareManagement.json │ │ │ │ │ ├── Internal.json │ │ │ │ │ ├── LocalAuthListManagement.json │ │ │ │ │ ├── PnC.json │ │ │ │ │ ├── Reservation.json │ │ │ │ │ ├── Security.json │ │ │ │ │ └── SmartCharging.json │ │ │ │ └── user_config.json │ │ │ └── OCPP201 │ │ │ │ ├── config.json │ │ │ │ ├── device_model_storage.db │ │ │ │ ├── init_core.sql │ │ │ │ └── logging.ini │ │ │ ├── release.json │ │ │ ├── rise_v2g │ │ │ ├── EVCCConfig.properties │ │ │ ├── SECCConfig.properties │ │ │ └── log4j2.properties │ │ │ └── user-config │ │ │ ├── .gitkeep │ │ │ └── ocpp │ │ │ └── user_config.json │ └── scripts │ │ ├── copy-csms-cert.sh │ │ ├── generate-cs-cert.sh │ │ ├── generate-mo-cert.sh │ │ ├── generate-oem-cert.sh │ │ ├── get-ca-cert.sh │ │ ├── register-oem-cert.sh │ │ └── setup-everest.sh ├── run-e2e-tests.sh └── test_driver │ ├── README.md │ ├── doc.go │ ├── end_to_end_test.go │ ├── go.mod │ └── go.sum ├── gateway ├── Dockerfile ├── cmd │ ├── root.go │ └── serve.go ├── go.mod ├── go.sum ├── main.go ├── ocpp │ ├── ocppj.go │ └── ocppj_test.go ├── pipe │ ├── doc.go │ ├── message.go │ ├── pipe.go │ └── pipe_test.go ├── registry │ ├── api.go │ ├── doc.go │ ├── mock.go │ ├── remote.go │ └── remote_test.go └── server │ ├── broker.go │ ├── broker_test.go │ ├── doc.go │ ├── middleware.go │ ├── middleware_test.go │ ├── server.go │ ├── server_test.go │ ├── status.go │ ├── status_test.go │ ├── tracing.go │ ├── ws.go │ └── ws_test.go ├── loadtests ├── .DS_Store ├── README.md └── ws_load_test.js ├── manager ├── Dockerfile ├── adminui │ ├── server.go │ ├── server_test.go │ └── templates │ │ ├── connect.gohtml │ │ ├── error.gohtml │ │ ├── index.gohtml │ │ ├── post-connect.gohtml │ │ ├── post-token.gohtml │ │ └── token.gohtml ├── api │ ├── API.md │ ├── README.md │ ├── api-spec.yaml │ ├── api.gen.go │ ├── api.go │ ├── cfg.yaml │ ├── error.go │ ├── render.go │ ├── req.json │ ├── server.go │ ├── server_test.go │ ├── validation.go │ └── validation_test.go ├── cmd │ ├── auth.go │ ├── auth_encode_password.go │ ├── auth_generate_credential.go │ ├── auth_hash_certificate.go │ ├── contract.go │ ├── contract_validate.go │ ├── emaid.go │ ├── emaid_normalize.go │ ├── root.go │ ├── serve.go │ ├── transaction.go │ ├── transaction_convert.go │ └── transaction_get.go ├── config │ ├── README.md │ ├── base_config.go │ ├── base_config_test.go │ ├── charge_station_cert_provider_config.go │ ├── config.go │ ├── config_test.go │ ├── contract_cert_provider_config.go │ ├── contract_cert_validator_config.go │ ├── doc.go │ ├── http_token_config.go │ ├── ocpi_config.go │ ├── root_cert_provider_config.go │ ├── settings_config.go │ ├── storage_config.go │ ├── tariff_service_config.go │ ├── testdata │ │ ├── ca.key │ │ ├── ca.pem │ │ ├── config.toml │ │ └── root_ca.pem │ └── transport_config.go ├── go.mod ├── go.sum ├── handlers │ ├── call_maker.go │ ├── call_maker_test.go │ ├── doc.go │ ├── has2be │ │ ├── authorize.go │ │ ├── authorize_test.go │ │ ├── certificate_signed_result.go │ │ ├── doc.go │ │ ├── get_15118_ev_certificate.go │ │ ├── get_15118_ev_certificate_test.go │ │ ├── get_certificate_status.go │ │ ├── get_certificate_status_test.go │ │ ├── sign_certificate.go │ │ └── sign_certificate_test.go │ ├── ocpp16 │ │ ├── authorize.go │ │ ├── authorize_test.go │ │ ├── boot_notification.go │ │ ├── boot_notification_test.go │ │ ├── change_configuration_result.go │ │ ├── data_transfer.go │ │ ├── data_transfer_result.go │ │ ├── data_transfer_result_test.go │ │ ├── data_transfer_test.go │ │ ├── doc.go │ │ ├── heartbeat.go │ │ ├── heartbeat_test.go │ │ ├── meter_values.go │ │ ├── meter_values_test.go │ │ ├── routing.go │ │ ├── routing_test.go │ │ ├── security_event_notification.go │ │ ├── security_event_notification_test.go │ │ ├── start_transaction.go │ │ ├── start_transaction_test.go │ │ ├── status_notification.go │ │ ├── status_notification_test.go │ │ ├── stop_transaction.go │ │ ├── stop_transaction_test.go │ │ └── trigger_message_result.go │ ├── ocpp201 │ │ ├── authorize.go │ │ ├── authorize_test.go │ │ ├── boot_notification.go │ │ ├── boot_notification_test.go │ │ ├── certificate_id.go │ │ ├── certificate_signed_result.go │ │ ├── certificate_signed_result_test.go │ │ ├── change_availability_result.go │ │ ├── change_availability_result_test.go │ │ ├── clear_cache.go │ │ ├── clear_cache_test.go │ │ ├── delete_certificate_result.go │ │ ├── delete_certificate_result_test.go │ │ ├── doc.go │ │ ├── firmware_status_notification.go │ │ ├── firmware_status_notification_test.go │ │ ├── get_15118_ev_certificate.go │ │ ├── get_15118_ev_certificate_test.go │ │ ├── get_base_report_result.go │ │ ├── get_base_report_result_test.go │ │ ├── get_certificate_status.go │ │ ├── get_certificate_status_test.go │ │ ├── get_installed_certificate_ids_result.go │ │ ├── get_installed_certificate_ids_result_test.go │ │ ├── get_local_list_version_result.go │ │ ├── get_local_list_version_result_test.go │ │ ├── get_report_result.go │ │ ├── get_report_result_test.go │ │ ├── get_transaction_status_result.go │ │ ├── get_transaction_status_result_test.go │ │ ├── get_variables_result.go │ │ ├── get_variables_result_test.go │ │ ├── heartbeat.go │ │ ├── heartbeat_test.go │ │ ├── install_certificate_result.go │ │ ├── install_certificate_result_test.go │ │ ├── log_status_notification.go │ │ ├── log_status_notification_test.go │ │ ├── meter_values.go │ │ ├── meter_values_test.go │ │ ├── notify_report.go │ │ ├── notify_report_test.go │ │ ├── request_start_transaction_result.go │ │ ├── request_start_transaction_result_test.go │ │ ├── request_stop_transaction_result.go │ │ ├── request_stop_transaction_result_test.go │ │ ├── reset_result.go │ │ ├── reset_result_test.go │ │ ├── routing.go │ │ ├── routing_test.go │ │ ├── security_event_notification.go │ │ ├── security_event_notification_test.go │ │ ├── send_local_list_result.go │ │ ├── send_local_list_result_test.go │ │ ├── set_network_profile_result.go │ │ ├── set_network_profile_result_test.go │ │ ├── set_variables_result.go │ │ ├── set_variables_result_test.go │ │ ├── sign_certificate.go │ │ ├── sign_certificate_test.go │ │ ├── status_notification.go │ │ ├── status_notification_test.go │ │ ├── transaction_event.go │ │ ├── transaction_event_test.go │ │ ├── trigger_message_result.go │ │ ├── unlock_connector_result.go │ │ └── unlock_connector_result_test.go │ ├── router.go │ ├── router_test.go │ ├── testdata │ │ └── schemas │ │ │ ├── EmptySchema.json │ │ │ └── RequiredFieldSchema.json │ └── types.go ├── main.go ├── ocpi │ ├── auth.go │ ├── auth_test.go │ ├── cfg.yaml │ ├── correlation.go │ ├── doc.go │ ├── error.go │ ├── ocpi.gen.go │ ├── ocpi.go │ ├── ocpi22-spec.yaml │ ├── ocpi_test.go │ ├── register.go │ ├── register_test.go │ ├── render.go │ ├── server.go │ ├── server_test.go │ └── status.go ├── ocpp │ ├── doc.go │ ├── emaid.go │ ├── emaid_test.go │ ├── has2be │ │ ├── authorize_request.go │ │ ├── authorize_response.go │ │ ├── certificate_signed_request.go │ │ ├── certificate_signed_response.go │ │ ├── get_15118_ev_certificate_request.go │ │ ├── get_15118_ev_certificate_response.go │ │ ├── get_certificate_status_request.go │ │ ├── get_certificate_status_response.go │ │ ├── sign_certificate_request.go │ │ ├── sign_certificate_response.go │ │ └── types.go │ ├── ocpp16 │ │ ├── authorize.go │ │ ├── authorize_response.go │ │ ├── boot_notification.go │ │ ├── boot_notification_response.go │ │ ├── change_configuration.go │ │ ├── change_configuration_response.go │ │ ├── data_transfer.go │ │ ├── data_transfer_response.go │ │ ├── doc.go │ │ ├── heartbeat.go │ │ ├── heartbeat_response.go │ │ ├── meter_values.go │ │ ├── meter_values_response.go │ │ ├── remote_start_transaction.go │ │ ├── remote_start_transaction_response.go │ │ ├── security_event_notification.go │ │ ├── security_event_notification_response.go │ │ ├── start_transaction.go │ │ ├── start_transaction_response.go │ │ ├── status_notification.go │ │ ├── status_notification_response.go │ │ ├── stop_transaction.go │ │ ├── stop_transaction_response.go │ │ ├── trigger_message.go │ │ └── trigger_message_response.go │ ├── ocpp201 │ │ ├── additional_info_type.go │ │ ├── authorization_status_enum_type.go │ │ ├── authorize_request.go │ │ ├── authorize_response.go │ │ ├── boot_notification_request.go │ │ ├── boot_notification_response.go │ │ ├── certificate_signed_request.go │ │ ├── certificate_signed_response.go │ │ ├── change_availability_request.go │ │ ├── change_availability_response.go │ │ ├── clear_cache_request.go │ │ ├── clear_cache_response.go │ │ ├── custom_data.go │ │ ├── delete_certificate_request.go │ │ ├── delete_certificate_response.go │ │ ├── doc.go │ │ ├── firmware_status_notification_request.go │ │ ├── firmware_status_notification_response.go │ │ ├── get_15118_ev_certificate_request.go │ │ ├── get_15118_ev_certificate_response.go │ │ ├── get_base_report_request.go │ │ ├── get_base_report_response.go │ │ ├── get_certificate_status_request.go │ │ ├── get_certificate_status_response.go │ │ ├── get_installed_certificate_ids_request.go │ │ ├── get_installed_certificate_ids_response.go │ │ ├── get_local_list_version_request.go │ │ ├── get_local_list_version_response.go │ │ ├── get_report_request.go │ │ ├── get_report_response.go │ │ ├── get_transaction_status_request.go │ │ ├── get_transaction_status_response.go │ │ ├── get_variables_request.go │ │ ├── get_variables_response.go │ │ ├── heartbeat_request.go │ │ ├── heartbeat_response.go │ │ ├── id_token_enum_type.go │ │ ├── id_token_info_type.go │ │ ├── id_token_type.go │ │ ├── install_certificate_request.go │ │ ├── install_certificate_response.go │ │ ├── log_status_notification_request.go │ │ ├── log_status_notification_response.go │ │ ├── message_content_type.go │ │ ├── message_format_enum_type.go │ │ ├── meter_values_request.go │ │ ├── meter_values_response.go │ │ ├── notify_report_request.go │ │ ├── notify_report_response.go │ │ ├── request_start_transaction_request.go │ │ ├── request_start_transaction_response.go │ │ ├── request_stop_transaction_request.go │ │ ├── request_stop_transaction_response.go │ │ ├── reset_request.go │ │ ├── reset_response.go │ │ ├── security_event_notification_request.go │ │ ├── security_event_notification_response.go │ │ ├── send_local_list_request.go │ │ ├── send_local_list_response.go │ │ ├── set_network_profile_request.go │ │ ├── set_network_profile_response.go │ │ ├── set_variables_request.go │ │ ├── set_variables_response.go │ │ ├── sign_certificate_request.go │ │ ├── sign_certificate_response.go │ │ ├── status_info_type.go │ │ ├── status_notification_request.go │ │ ├── status_notification_response.go │ │ ├── transactionevent_request.go │ │ ├── transactionevent_response.go │ │ ├── trigger_message_request.go │ │ ├── trigger_message_response.go │ │ ├── unlock_connector_request.go │ │ └── unlock_connector_response.go │ └── types.go ├── schemas │ ├── has2be │ │ ├── AuthorizeRequest.json │ │ ├── AuthorizeResponse.json │ │ ├── CertificateSignedRequest.json │ │ ├── CertificateSignedResponse.json │ │ ├── DeleteCertificateRequest.json │ │ ├── DeleteCertificateResponse.json │ │ ├── Get15118EVCertificateRequest.json │ │ ├── Get15118EVCertificateResponse.json │ │ ├── GetCertificateStatusRequest.json │ │ ├── GetCertificateStatusResponse.json │ │ ├── GetInstalledCertificateIdsRequest.json │ │ ├── GetInstalledCertificateIdsResponse.json │ │ ├── InstallCertificateRequest.json │ │ ├── InstallCertificateResponse.json │ │ ├── SignCertificateRequest.json │ │ ├── SignCertificateResponse.json │ │ ├── TriggerMessageRequest.json │ │ └── TriggerMessageResponse.json │ ├── ocpp16 │ │ ├── Authorize.json │ │ ├── AuthorizeResponse.json │ │ ├── BootNotification.json │ │ ├── BootNotificationResponse.json │ │ ├── CancelReservation.json │ │ ├── CancelReservationResponse.json │ │ ├── CertificateSigned.json │ │ ├── CertificateSignedResponse.json │ │ ├── ChangeAvailability.json │ │ ├── ChangeAvailabilityResponse.json │ │ ├── ChangeConfiguration.json │ │ ├── ChangeConfigurationResponse.json │ │ ├── ClearCache.json │ │ ├── ClearCacheResponse.json │ │ ├── ClearChargingProfile.json │ │ ├── ClearChargingProfileResponse.json │ │ ├── DataTransfer.json │ │ ├── DataTransferResponse.json │ │ ├── DeleteCertificate.json │ │ ├── DeleteCertificateResponse.json │ │ ├── DiagnosticsStatusNotification.json │ │ ├── DiagnosticsStatusNotificationResponse.json │ │ ├── ExtendedTriggerMessage.json │ │ ├── ExtendedTriggerMessageResponse.json │ │ ├── FirmwareStatusNotification.json │ │ ├── FirmwareStatusNotificationResponse.json │ │ ├── GetCompositeSchedule.json │ │ ├── GetCompositeScheduleResponse.json │ │ ├── GetConfiguration.json │ │ ├── GetConfigurationResponse.json │ │ ├── GetDiagnostics.json │ │ ├── GetDiagnosticsResponse.json │ │ ├── GetInstalledCertificateIds.json │ │ ├── GetInstalledCertificateIdsResponse.json │ │ ├── GetLocalListVersion.json │ │ ├── GetLocalListVersionResponse.json │ │ ├── GetLog.json │ │ ├── GetLogResponse.json │ │ ├── Heartbeat.json │ │ ├── HeartbeatResponse.json │ │ ├── InstallCertificate.json │ │ ├── InstallCertificateResponse.json │ │ ├── LogStatusNotification.json │ │ ├── LogStatusNotificationResponse.json │ │ ├── MeterValues.json │ │ ├── MeterValuesResponse.json │ │ ├── RemoteStartTransaction.json │ │ ├── RemoteStartTransactionResponse.json │ │ ├── RemoteStopTransaction.json │ │ ├── RemoteStopTransactionResponse.json │ │ ├── ReserveNow.json │ │ ├── ReserveNowResponse.json │ │ ├── Reset.json │ │ ├── ResetResponse.json │ │ ├── SecurityEventNotification.json │ │ ├── SecurityEventNotificationResponse.json │ │ ├── SendLocalList.json │ │ ├── SendLocalListResponse.json │ │ ├── SetChargingProfile.json │ │ ├── SetChargingProfileResponse.json │ │ ├── SignCertificate.json │ │ ├── SignCertificateResponse.json │ │ ├── SignedFirmwareStatusNotification.json │ │ ├── SignedFirmwareStatusNotificationResponse.json │ │ ├── SignedUpdateFirmware.json │ │ ├── SignedUpdateFirmwareResponse.json │ │ ├── StartTransaction.json │ │ ├── StartTransactionResponse.json │ │ ├── StatusNotification.json │ │ ├── StatusNotificationResponse.json │ │ ├── StopTransaction.json │ │ ├── StopTransactionResponse.json │ │ ├── TriggerMessage.json │ │ ├── TriggerMessageResponse.json │ │ ├── UnlockConnector.json │ │ ├── UnlockConnectorResponse.json │ │ ├── UpdateFirmware.json │ │ └── UpdateFirmwareResponse.json │ ├── ocpp201 │ │ ├── AuthorizeRequest.json │ │ ├── AuthorizeResponse.json │ │ ├── BootNotificationRequest.json │ │ ├── BootNotificationResponse.json │ │ ├── CancelReservationRequest.json │ │ ├── CancelReservationResponse.json │ │ ├── CertificateSignedRequest.json │ │ ├── CertificateSignedResponse.json │ │ ├── ChangeAvailabilityRequest.json │ │ ├── ChangeAvailabilityResponse.json │ │ ├── ClearCacheRequest.json │ │ ├── ClearCacheResponse.json │ │ ├── ClearChargingProfileRequest.json │ │ ├── ClearChargingProfileResponse.json │ │ ├── ClearDisplayMessageRequest.json │ │ ├── ClearDisplayMessageResponse.json │ │ ├── ClearVariableMonitoringRequest.json │ │ ├── ClearVariableMonitoringResponse.json │ │ ├── ClearedChargingLimitRequest.json │ │ ├── ClearedChargingLimitResponse.json │ │ ├── CostUpdatedRequest.json │ │ ├── CostUpdatedResponse.json │ │ ├── CustomerInformationRequest.json │ │ ├── CustomerInformationResponse.json │ │ ├── DataTransferRequest.json │ │ ├── DataTransferResponse.json │ │ ├── DeleteCertificateRequest.json │ │ ├── DeleteCertificateResponse.json │ │ ├── FirmwareStatusNotificationRequest.json │ │ ├── FirmwareStatusNotificationResponse.json │ │ ├── Get15118EVCertificateRequest.json │ │ ├── Get15118EVCertificateResponse.json │ │ ├── GetBaseReportRequest.json │ │ ├── GetBaseReportResponse.json │ │ ├── GetCertificateStatusRequest.json │ │ ├── GetCertificateStatusResponse.json │ │ ├── GetChargingProfilesRequest.json │ │ ├── GetChargingProfilesResponse.json │ │ ├── GetCompositeScheduleRequest.json │ │ ├── GetCompositeScheduleResponse.json │ │ ├── GetDisplayMessagesRequest.json │ │ ├── GetDisplayMessagesResponse.json │ │ ├── GetInstalledCertificateIdsRequest.json │ │ ├── GetInstalledCertificateIdsResponse.json │ │ ├── GetLocalListVersionRequest.json │ │ ├── GetLocalListVersionResponse.json │ │ ├── GetLogRequest.json │ │ ├── GetLogResponse.json │ │ ├── GetMonitoringReportRequest.json │ │ ├── GetMonitoringReportResponse.json │ │ ├── GetReportRequest.json │ │ ├── GetReportResponse.json │ │ ├── GetTransactionStatusRequest.json │ │ ├── GetTransactionStatusResponse.json │ │ ├── GetVariablesRequest.json │ │ ├── GetVariablesResponse.json │ │ ├── HeartbeatRequest.json │ │ ├── HeartbeatResponse.json │ │ ├── InstallCertificateRequest.json │ │ ├── InstallCertificateResponse.json │ │ ├── LogStatusNotificationRequest.json │ │ ├── LogStatusNotificationResponse.json │ │ ├── MeterValuesRequest.json │ │ ├── MeterValuesResponse.json │ │ ├── NotifyChargingLimitRequest.json │ │ ├── NotifyChargingLimitResponse.json │ │ ├── NotifyCustomerInformationRequest.json │ │ ├── NotifyCustomerInformationResponse.json │ │ ├── NotifyDisplayMessagesRequest.json │ │ ├── NotifyDisplayMessagesResponse.json │ │ ├── NotifyEVChargingNeedsRequest.json │ │ ├── NotifyEVChargingNeedsResponse.json │ │ ├── NotifyEVChargingScheduleRequest.json │ │ ├── NotifyEVChargingScheduleResponse.json │ │ ├── NotifyEventRequest.json │ │ ├── NotifyEventResponse.json │ │ ├── NotifyMonitoringReportRequest.json │ │ ├── NotifyMonitoringReportResponse.json │ │ ├── NotifyReportRequest.json │ │ ├── NotifyReportResponse.json │ │ ├── PublishFirmwareRequest.json │ │ ├── PublishFirmwareResponse.json │ │ ├── PublishFirmwareStatusNotificationRequest.json │ │ ├── PublishFirmwareStatusNotificationResponse.json │ │ ├── ReportChargingProfilesRequest.json │ │ ├── ReportChargingProfilesResponse.json │ │ ├── RequestStartTransactionRequest.json │ │ ├── RequestStartTransactionResponse.json │ │ ├── RequestStopTransactionRequest.json │ │ ├── RequestStopTransactionResponse.json │ │ ├── ReservationStatusUpdateRequest.json │ │ ├── ReservationStatusUpdateResponse.json │ │ ├── ReserveNowRequest.json │ │ ├── ReserveNowResponse.json │ │ ├── ResetRequest.json │ │ ├── ResetResponse.json │ │ ├── SecurityEventNotificationRequest.json │ │ ├── SecurityEventNotificationResponse.json │ │ ├── SendLocalListRequest.json │ │ ├── SendLocalListResponse.json │ │ ├── SetChargingProfileRequest.json │ │ ├── SetChargingProfileResponse.json │ │ ├── SetDisplayMessageRequest.json │ │ ├── SetDisplayMessageResponse.json │ │ ├── SetMonitoringBaseRequest.json │ │ ├── SetMonitoringBaseResponse.json │ │ ├── SetMonitoringLevelRequest.json │ │ ├── SetMonitoringLevelResponse.json │ │ ├── SetNetworkProfileRequest.json │ │ ├── SetNetworkProfileResponse.json │ │ ├── SetVariableMonitoringRequest.json │ │ ├── SetVariableMonitoringResponse.json │ │ ├── SetVariablesRequest.json │ │ ├── SetVariablesResponse.json │ │ ├── SignCertificateRequest.json │ │ ├── SignCertificateResponse.json │ │ ├── StatusNotificationRequest.json │ │ ├── StatusNotificationResponse.json │ │ ├── TransactionEventRequest.json │ │ ├── TransactionEventResponse.json │ │ ├── TriggerMessageRequest.json │ │ ├── TriggerMessageResponse.json │ │ ├── UnlockConnectorRequest.json │ │ ├── UnlockConnectorResponse.json │ │ ├── UnpublishFirmwareRequest.json │ │ ├── UnpublishFirmwareResponse.json │ │ ├── UpdateFirmwareRequest.json │ │ └── UpdateFirmwareResponse.json │ ├── schemas.go │ ├── validator.go │ └── validator_test.go ├── server │ ├── api.go │ ├── api_test.go │ ├── doc.go │ ├── log.go │ ├── ocpi.go │ ├── ocpi_test.go │ ├── server.go │ └── server_test.go ├── services │ ├── certificate_validation.go │ ├── certificate_validation_hubject_test.go │ ├── certificate_validation_test.go │ ├── charge_station_certificate_provider.go │ ├── charge_station_certificate_provider_test.go │ ├── contract_certificate_provider.go │ ├── contract_certificate_provider_test.go │ ├── doc.go │ ├── http_token_hubject_test.go │ ├── http_token_service.go │ ├── http_token_service_test.go │ ├── local_source.go │ ├── local_source_test.go │ ├── root_certificate_provider.go │ ├── root_certificate_provider_hubject_test.go │ ├── root_certificate_provider_test.go │ ├── tariff.go │ ├── tariff_test.go │ ├── testdata │ │ └── root_ca.pem │ ├── token_auth.go │ └── token_auth_test.go ├── store │ ├── cert.go │ ├── cs.go │ ├── doc.go │ ├── engine.go │ ├── firestore │ │ ├── cert.go │ │ ├── cert_test.go │ │ ├── cs.go │ │ ├── cs_test.go │ │ ├── doc.go │ │ ├── location.go │ │ ├── location_test.go │ │ ├── main_test.go │ │ ├── ocpi.go │ │ ├── ocpi_test.go │ │ ├── store.go │ │ ├── store_test.go │ │ ├── token.go │ │ ├── token_test.go │ │ ├── transaction.go │ │ └── transaction_test.go │ ├── inmemory │ │ ├── cert_test.go │ │ ├── doc.go │ │ ├── store.go │ │ ├── store_test.go │ │ └── transaction_test.go │ ├── location.go │ ├── ocpi.go │ ├── token.go │ └── transaction.go ├── sync │ ├── certificates.go │ ├── certificates_test.go │ ├── doc.go │ ├── settings.go │ ├── settings_test.go │ ├── sync.go │ └── triggers.go ├── templates │ ├── templates.go │ └── transactions.html ├── testutil │ └── tracing.go └── transport │ ├── doc.go │ ├── emitter.go │ ├── error.go │ ├── listener.go │ ├── messages.go │ ├── mqtt │ ├── broker.go │ ├── broker_test.go │ ├── doc.go │ ├── emitter.go │ ├── emitter_test.go │ ├── listener.go │ ├── listener_test.go │ └── options.go │ └── receiver.go ├── prometheus └── prometheus.yml └── scripts ├── README.md ├── get-ca-cert.sh ├── json-to-go.sh └── run.sh /.github/dco.yml: -------------------------------------------------------------------------------- 1 | require: 2 | members: false 3 | -------------------------------------------------------------------------------- /.github/workflows/check-links.yml: -------------------------------------------------------------------------------- 1 | name: Check Markdown links 2 | 3 | on: push 4 | 5 | jobs: 6 | markdown-link-check: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@master 10 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 11 | -------------------------------------------------------------------------------- /.github/workflows/delete-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Delete Environment (default settings) 2 | 3 | on: 4 | workflow_dispatch: {} 5 | 6 | jobs: 7 | delete: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: strumwolf/delete-deployment-environment@v2 11 | with: 12 | token: ${{ github.token }} 13 | environment: production 14 | ref: csmstest 15 | onlyRemoveDeployments: true 16 | -------------------------------------------------------------------------------- /.github/workflows/end-to-end-tests.yml: -------------------------------------------------------------------------------- 1 | name: End-to-End Tests 2 | on: 3 | push: 4 | branches: [ '*' ] 5 | 6 | jobs: 7 | build-and-test: 8 | name: Install docker and Run E2E Tests 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - name: Setup Go 13 | uses: actions/setup-go@v4 14 | with: 15 | go-version: '1.20' 16 | - name: Install Docker Compose 17 | run: | 18 | sudo apt-get update 19 | sudo apt-get install docker-compose 20 | docker-compose --version 21 | - name: Build docker and Run E2E Tests 22 | run: ./e2e_tests/run-e2e-tests.sh -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | push: 4 | 5 | jobs: 6 | main: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: actions/setup-go@v3 11 | with: 12 | go-version: "1.20" 13 | check-latest: true 14 | - name: Install gosec 15 | run: go install github.com/securego/gosec/v2/cmd/gosec@latest 16 | - name: Install static check 17 | run: go install honnef.co/go/tools/cmd/staticcheck@latest 18 | - uses: actions/setup-python@v4 19 | with: 20 | python-version: 3.x 21 | - uses: pre-commit/action@v3.0.0 22 | - uses: pre-commit-ci/lite-action@v1.0.1 23 | if: always() 24 | -------------------------------------------------------------------------------- /.hook/check-talisman-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | files=$(for f in $(yq '.fileignoreconfig.[].filename' .talismanrc); do if [ ! -f "$f" ]; then echo "$f"; fi; done) 4 | count=$(echo "$files" | sed '/^$/d' | wc -l) 5 | 6 | if [[ "$count" -gt 0 ]]; 7 | then 8 | echo "The following files in .talismanrc do not exist:" 9 | echo "$files" 10 | exit 1 11 | fi -------------------------------------------------------------------------------- /.hook/sort-talismanrc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | yq -i '.fileignoreconfig |= sort_by(.filename)' .talismanrc 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | The MaEVe project takes security seriously. 4 | We make every possible effort to ensure users can adequately secure the CSMS, from the business logic to its underlying infrastructure. 5 | To that end, we continuously review security vulnerabilities, as well as security hotspots in the code, and provide fixes in a timely manner. 6 | 7 | ## Reporting Security Vulnerabilities 8 | 9 | Please report security vulnerabilities in the Issues section of this github repository. 10 | By keeping security issues visible, we leverage our community in helping fix them promptly. Consequently, a patched version of MaEVe can be released to users. 11 | 12 | If you are concerned sharing a vulnerability with the rest of the community, you can also send your report to our private team mailing list: [maeve-team@thoughtworks.com](mailto:maeve-team@thoughtworks.com) 13 | 14 | Our team will then review your request, and work with the maintainers of the affected component(s) to get the issue resolved. 15 | -------------------------------------------------------------------------------- /config/certificates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/config/certificates/.gitkeep -------------------------------------------------------------------------------- /config/certificates/Makefile: -------------------------------------------------------------------------------- 1 | # Temporary file for process substitution 2 | temp_file := /tmp/temp.ext 3 | 4 | all: csms.pem cpo_sub_ca1.pem cpo_sub_ca2.pem root-V2G-cert.pem trust.pem 5 | 6 | csms.key: 7 | openssl ecparam -name prime256v1 -genkey -noout -out csms.key 8 | 9 | csms.csr: csms.key 10 | openssl req -new -nodes -key csms.key \ 11 | -subj "/CN=CSMS/O=Thoughtworks" \ 12 | -addext "subjectAltName = DNS:localhost, DNS:gateway, DNS:lb" \ 13 | -out csms.csr 14 | 15 | csms.pem: csms.csr 16 | echo "basicConstraints = critical, CA:false" > $(temp_file) 17 | echo "keyUsage = critical, digitalSignature, keyEncipherment" >> $(temp_file) 18 | echo "subjectAltName = DNS:localhost, DNS:gateway, DNS:lb" >> $(temp_file) 19 | openssl x509 -req -in csms.csr \ 20 | -out csms.pem \ 21 | -signkey csms.key \ 22 | -days 365 \ 23 | -extfile $(temp_file) 24 | rm -f $(temp_file) 25 | 26 | cpo_sub_ca1.pem cpo_sub_ca2.pem root-V2G-cert.pem trust.pem: 27 | ../../scripts/get-ca-cert.sh 28 | 29 | .PHONY: clean 30 | clean: 31 | rm -f *.pem csms.key csms.csr 32 | -------------------------------------------------------------------------------- /config/mosquitto/mosquitto.conf: -------------------------------------------------------------------------------- 1 | # Listeners 2 | listener 1883 3 | protocol mqtt 4 | 5 | listener 9000 6 | protocol websockets 7 | 8 | # Logging 9 | log_dest stdout 10 | log_type error 11 | log_type warning 12 | log_type notice 13 | log_type information 14 | log_timestamp true 15 | log_timestamp_format %Y/%m/%d %H:%M:%S 16 | connection_messages false 17 | 18 | # Security 19 | allow_anonymous true 20 | -------------------------------------------------------------------------------- /docs/assets/gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/docs/assets/gateway.png -------------------------------------------------------------------------------- /docs/assets/manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/docs/assets/manager.png -------------------------------------------------------------------------------- /docs/assets/scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/docs/assets/scaling.png -------------------------------------------------------------------------------- /e2e_tests/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: up 2 | up: register-cs setup-rfid setup-contract 3 | OCPP_VERSION=ocpp docker-compose --profile everest up -d 4 | 5 | .PHONY: test 6 | test: # password 123456 7 | websocat --client-pkcs12-der ./config/certificates/cs001.pem --client-pkcs12-passwd 123456 wss://localhost:443 8 | 9 | .PHONY: setup-rfid 10 | setup-rfid: 11 | curl -i http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{"countryCode": "GB","partyId": "TWK","type": "RFID","uid": "DEADBEEF","contractId": "GBTWK012345678V","issuer": "Thoughtworks","valid": true,"cacheMode": "ALWAYS"}' 12 | 13 | .PHONY: setup-contract 14 | setup-contract: 15 | curl -i http://localhost:9410/api/v0/token -H 'content-type: application/json' -d '{"countryCode": "GB","partyId": "TWK","type": "RFID","uid": "EMP77TWTW99999","contractId": "GBTWK012345678V","issuer": "Thoughtworks","valid": true,"cacheMode": "ALWAYS"}' 16 | 17 | .PHONY: register-cs 18 | register-cs: 19 | curl -i http://localhost:9410/api/v0/cs/cs001 -H 'content-type: application/json' -d '{"securityProfile":2}' 20 | -------------------------------------------------------------------------------- /e2e_tests/README.md: -------------------------------------------------------------------------------- 1 | # End-to-end tests 2 | 3 | ## Description 4 | 5 | Runs end-to-end tests against Everest (Charge station and EV simulator) along with CSMS. This performs the following tests: 6 | - Plug-in a connector 7 | - Authorise a charge (using RFID or ISO-15118) 8 | - Start a charge 9 | - Stop a charge 10 | - Unplug a connector 11 | 12 | 13 | ## Steps 14 | 15 | 1. Run the following bash script to start the docker containers for Everest and CSMS and execute the end-to-end tests 16 | ```shell 17 | ./run-e2e-tests.sh 18 | ``` 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/certificates/root-V2G-cert.pem: -------------------------------------------------------------------------------- 1 | subject=C=DE, O=Hubject GmbH, DC=V2G, CN=V2G Root CA QA G1 2 | issuer=C=DE, O=Hubject GmbH, DC=V2G, CN=V2G Root CA QA G1 3 | -----BEGIN CERTIFICATE----- 4 | MIICUzCCAfmgAwIBAgIQaasA0lm730LOgFKa0wzl7TAKBggqhkjOPQQDAjBVMQsw 5 | CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRMwEQYKCZImiZPyLGQB 6 | GRYDVjJHMRowGAYDVQQDExFWMkcgUm9vdCBDQSBRQSBHMTAgFw0xOTA0MjYwODM3 7 | MTVaGA8yMDU5MDQyNjA4MzcxNVowVTELMAkGA1UEBhMCREUxFTATBgNVBAoTDEh1 8 | YmplY3QgR21iSDETMBEGCgmSJomT8ixkARkWA1YyRzEaMBgGA1UEAxMRVjJHIFJv 9 | b3QgQ0EgUUEgRzEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAShT8kSNcC+74TN 10 | D82On2Y2TOf8mYfxw73lKZ7t9cmEXHpMdAgsWBQ4LI+pOMhe6NOHzJbzP38kQTg4 11 | zLfw3kU0o4GoMIGlMBMGA1UdJQQMMAoGCCsGAQUFBwMJMA8GA1UdEwEB/wQFMAMB 12 | Af8wEQYDVR0OBAoECEtF/4Il/BCWMEUGA1UdIAQ+MDwwOgYMKwYBBAGCxDUBAgEA 13 | MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3Lmh1YmplY3QuY29tL3BraS8wEwYD 14 | VR0jBAwwCoAIS0X/giX8EJYwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMCA0gA 15 | MEUCIQCq3Qx2BLYVFb7Lt5XXpSlUViYv4cIUOQE1Ce9o2Jyy1QIgZRmVzMVjHZA+ 16 | toiM000PCUrLppqbLpcRN4MP8kE0OhU= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/certificates/trust.pem: -------------------------------------------------------------------------------- 1 | subject=C=DE, O=Hubject GmbH, CN=CPO Sub1 CA QA G1.2 2 | issuer=C=DE, O=Hubject GmbH, DC=V2G, CN=V2G Root CA QA G1 3 | -----BEGIN CERTIFICATE----- 4 | MIICIjCCAcigAwIBAgIQcNHZPf7SMsnpLbJvOgtUYjAKBggqhkjOPQQDAjBVMQsw 5 | CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRMwEQYKCZImiZPyLGQB 6 | GRYDVjJHMRowGAYDVQQDExFWMkcgUm9vdCBDQSBRQSBHMTAeFw0yMjA0MDcxNDEx 7 | MjBaFw0yNjA0MDcxNDExMjBaMEIxCzAJBgNVBAYTAkRFMRUwEwYDVQQKEwxIdWJq 8 | ZWN0IEdtYkgxHDAaBgNVBAMTE0NQTyBTdWIxIENBIFFBIEcxLjIwWTATBgcqhkjO 9 | PQIBBggqhkjOPQMBBwNCAAQu+9a26mDSIAgSACu3WCOth7bcQnJhqmMa+OYlCnc8 10 | +QMhgl1wLS15agYgDptdD5kJK+jt/CYRFZ4alwrXCf2po4GMMIGJMBIGA1UdEwEB 11 | /wQIMAYBAf8CAQEwEQYDVR0OBAoECEAU+/DnqWOsMBMGA1UdIwQMMAqACEtF/4Il 12 | /BCWMDsGCCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29jc3AtcWEu 13 | aHViamVjdC5jb206ODA4MDAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwIDSAAw 14 | RQIhAL/4EvlWVR6+Z7+efMrttafXPoUfQWqqv1xIkGRo1wPQAiBbEmj7MeHZwV23 15 | XPHkCjWCfzHwYlvQ4c8Cwo8ndW6law== 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/ca/csms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/ca/csms/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/ca/cso/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/ca/cso/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/ca/oem/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/ca/oem/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/ca/v2g/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/ca/v2g/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/client/csms/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/client/csms/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/client/cso/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/client/cso/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/certs/client/oem/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/certs/client/oem/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/default_logging.cfg: -------------------------------------------------------------------------------- 1 | # for documentation on this file format see: 2 | # https://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/detailed/utilities.html#log.detailed.utilities.setup.filter_formatter 3 | 4 | [Core] 5 | DisableLogging=false 6 | Filter="%Severity% >= INFO" 7 | 8 | [Sinks.Console] 9 | Destination=Console 10 | # Filter="%Target% contains \"MySink1\"" 11 | Format="%TimeStamp% [%Severity%] \033[1;32m%Process%\033[0m \033[1;36m%function%\033[0m \033[1;30m%file%:\033[0m\033[1;32m%line%\033[0m: %Message%" 12 | Asynchronous=false 13 | AutoFlush=true 14 | SeverityStringColorDebug="\033[1;30m" 15 | SeverityStringColorInfo="\033[1;37m" 16 | SeverityStringColorWarning="\033[1;33m" 17 | SeverityStringColorError="\033[1;31m" 18 | SeverityStringColorCritical="\033[1;35m" 19 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP/logging.ini: -------------------------------------------------------------------------------- 1 | # for documentation on this file format see: 2 | # https://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/detailed/utilities.html#log.detailed.utilities.setup.filter_formatter 3 | 4 | [Core] 5 | DisableLogging=false 6 | Filter="%Severity% >= INFO" 7 | 8 | [Sinks.Console] 9 | Destination=Console 10 | # Filter="%Target% contains \"MySink1\"" 11 | Format="%TimeStamp% \033[1;32m%Process%\033[0m [\033[1;32m%ProcessID%\033[0m] [%Severity%] {\033[1;34m%ThreadID%\033[0m} \033[1;36m%function%\033[0m \033[1;30m%file%:\033[0m\033[1;32m%line%\033[0m: %Message%" 12 | Asynchronous=false 13 | AutoFlush=true 14 | SeverityStringColorDebug="\033[1;30m" 15 | SeverityStringColorInfo="\033[1;37m" 16 | SeverityStringColorWarning="\033[1;33m" 17 | SeverityStringColorError="\033[1;31m" 18 | SeverityStringColorCritical="\033[1;35m" 19 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP/profile_schemas/Custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "description": "Json schema for Custom configuration keys", 4 | "$comment": "This is just an example schema and can be modified according to custom requirements", 5 | "type": "object", 6 | "required": [], 7 | "properties": { 8 | "ExampleConfigurationKey": { 9 | "type": "string", 10 | "description": "Custom key", 11 | "readOnly": false 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP/profile_schemas/FirmwareManagement.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "description": "Json schema for Firmware Management Profile config", 4 | "type": "object", 5 | "required": [], 6 | "properties": { 7 | "SupportedFileTransferProtocols": { 8 | "type": "string", 9 | "readOnly": true 10 | } 11 | }, 12 | "additionalProperties": false 13 | } 14 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP/profile_schemas/LocalAuthListManagement.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "description": "Json schema for Local Auth List Management Profile config", 4 | "type": "object", 5 | "required": [ 6 | "LocalAuthListEnabled", 7 | "LocalAuthListMaxLength", 8 | "SendLocalListMaxLength" 9 | ], 10 | "properties": { 11 | "LocalAuthListEnabled": { 12 | "type": "boolean", 13 | "readOnly": false 14 | }, 15 | "LocalAuthListMaxLength": { 16 | "type": "integer", 17 | "readOnly": true, 18 | "minimum": 0 19 | }, 20 | "SendLocalListMaxLength": { 21 | "type": "integer", 22 | "readOnly": true, 23 | "minimum": 0 24 | } 25 | }, 26 | "additionalProperties": false 27 | } 28 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP/profile_schemas/Reservation.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "description": "Json schema for Reservation Profile config", 4 | "type": "object", 5 | "required": [], 6 | "properties": { 7 | "ReserveConnectorZeroSupported": { 8 | "type": "boolean", 9 | "readOnly": true 10 | } 11 | }, 12 | "additionalProperties": false 13 | } 14 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP/user_config.json: -------------------------------------------------------------------------------- 1 | {"Core":{"HeartbeatInterval":300}} 2 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP201/device_model_storage.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/ocpp/OCPP201/device_model_storage.db -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/ocpp/OCPP201/logging.ini: -------------------------------------------------------------------------------- 1 | # for documentation on this file format see: 2 | # https://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/detailed/utilities.html#log.detailed.utilities.setup.filter_formatter 3 | 4 | [Core] 5 | DisableLogging=false 6 | Filter="%Severity% >= INFO" 7 | 8 | [Sinks.Console] 9 | Destination=Console 10 | # Filter="%Target% contains \"MySink1\"" 11 | Format="%TimeStamp% \033[1;32m%Process%\033[0m [\033[1;32m%ProcessID%\033[0m] [%Severity%] {\033[1;34m%ThreadID%\033[0m} \033[1;36m%function%\033[0m \033[1;30m%file%:\033[0m\033[1;32m%line%\033[0m: %Message%" 12 | Asynchronous=false 13 | AutoFlush=true 14 | SeverityStringColorDebug="\033[1;30m" 15 | SeverityStringColorInfo="\033[1;37m" 16 | SeverityStringColorWarning="\033[1;33m" 17 | SeverityStringColorError="\033[1;31m" 18 | SeverityStringColorCritical="\033[1;35m" 19 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/rise_v2g/EVCCConfig.properties: -------------------------------------------------------------------------------- 1 | # 2 | #Fri Jun 30 19:17:39 UTC 2023 3 | network.interface=eth0 4 | exi.messages.showhex=true 5 | energy.transfermode.requested=AC_three_phase_core 6 | exi.messages.showxml=true 7 | signature.verification.showlog=true 8 | contract.certificate.update.timespan=14 9 | implementation.evcc.controller=com.v2gclarity.risev2g.evcc.evController.EverestEVController 10 | authentication.mode= 11 | voltage.accuracy=5 12 | tls=false 13 | session.id=00 14 | exi.codec=exificient 15 | -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/rise_v2g/log4j2.properties: -------------------------------------------------------------------------------- 1 | appender.file.type = File 2 | appender.file.name = FILE 3 | appender.file.fileName = /tmp/rise.log 4 | appender.file.layout.type = PatternLayout 5 | appender.file.layout.pattern = %m%n 6 | 7 | logger.evcc.level = debug 8 | logger.evcc.appenderRef.file.ref = FILE 9 | logger.evcc.name = StartEVCC 10 | logger.evcc.additivity = false 11 | 12 | logger.codec.level = debug 13 | logger.codec.appenderRef.file.ref = FILE 14 | logger.codec.name = EXIficientCodec 15 | logger.codec.additivity = false -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/user-config/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/e2e_tests/everest/config/everest/user-config/.gitkeep -------------------------------------------------------------------------------- /e2e_tests/everest/config/everest/user-config/ocpp/user_config.json: -------------------------------------------------------------------------------- 1 | {"Core":{"HeartbeatInterval":60}} 2 | -------------------------------------------------------------------------------- /e2e_tests/everest/scripts/copy-csms-cert.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 4 | default_csms_dir="${script_dir}"/../../.. 5 | csms_dir="${1:-$default_csms_dir}" 6 | 7 | cp "$csms_dir"/config/certificates/csms.pem "$script_dir"/../config/certificates 8 | cp "$csms_dir"/config/certificates/csms.pem "$script_dir"/../config/everest/certs/ca/csms 9 | -------------------------------------------------------------------------------- /e2e_tests/test_driver/README.md: -------------------------------------------------------------------------------- 1 | # End-to-End test 2 | 3 | To run the end-to-end tests separately on local, run the following command: 4 | ```shell 5 | $ go test --tags=e2e -v ./... -count=1 6 | ``` 7 | 8 | -------------------------------------------------------------------------------- /e2e_tests/test_driver/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package test_driver 4 | -------------------------------------------------------------------------------- /e2e_tests/test_driver/go.mod: -------------------------------------------------------------------------------- 1 | module mqttbrokertest 2 | 3 | go 1.20 4 | 5 | require github.com/eclipse/paho.mqtt.golang v1.4.3 6 | 7 | require ( 8 | github.com/gorilla/websocket v1.5.0 // indirect 9 | golang.org/x/net v0.23.0 // indirect 10 | golang.org/x/sync v0.2.0 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /e2e_tests/test_driver/go.sum: -------------------------------------------------------------------------------- 1 | github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= 2 | github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= 3 | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= 4 | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 5 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 6 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 7 | golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= 8 | golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 9 | -------------------------------------------------------------------------------- /gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.2 2 | 3 | # STAGE 1: build the executable 4 | FROM golang:1.20-alpine AS builder 5 | 6 | RUN apk add --no-cache git openssh ca-certificates 7 | 8 | ARG TARGETARCH 9 | 10 | # IF statement executed due to incosistent package names @ https://github.com/moparisthebest/static-curl/issues/8 11 | RUN if [ "$TARGETARCH" = "arm64" ]; then \ 12 | TARGETARCH=aarch64 ; \ 13 | fi; \ 14 | wget -O /usr/bin/curl https://github.com/moparisthebest/static-curl/releases/download/v8.0.1/curl-$TARGETARCH \ 15 | && chmod +x /usr/bin/curl 16 | 17 | WORKDIR /src 18 | 19 | COPY ./go.mod ./go.sum ./ 20 | 21 | RUN go mod download 22 | 23 | COPY ./ ./ 24 | 25 | RUN --mount=type=cache,target=/root/.cache/go-build/ CGO_ENABLED=0 go build -o /app main.go 26 | 27 | # STAGE 2: build the container 28 | FROM gcr.io/distroless/static:nonroot AS final 29 | 30 | COPY --from=builder /usr/bin/curl /usr/bin/curl 31 | 32 | USER 10000:10000 33 | 34 | COPY --from=builder --chown=nonroot:nonroot /app /app 35 | 36 | ENTRYPOINT ["/app"] 37 | -------------------------------------------------------------------------------- /gateway/cmd/root.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "os" 7 | 8 | "github.com/spf13/cobra" 9 | ) 10 | 11 | // rootCmd represents the base command when called without any subcommands 12 | var rootCmd = &cobra.Command{ 13 | Use: "csms", 14 | Short: "Charge Station Management System", 15 | Long: `Provides a Charge Station Management System that is horizontally 16 | scalable. There are two core components, the gateway accepts 17 | connections from charge stations and forwards messages to/from 18 | an MQTT broker. The manager reads messages from the MQTT broker, 19 | implements any logic and determines the appropriate response. 20 | The manager can also initiate a request to the charge station 21 | and receive the response.`, 22 | } 23 | 24 | // Execute adds all child commands to the root command and sets flags appropriately. 25 | // This is called by main.main(). It only needs to happen once to the rootCmd. 26 | func Execute() { 27 | err := rootCmd.Execute() 28 | if err != nil { 29 | os.Exit(1) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gateway/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package main 4 | 5 | import ( 6 | "github.com/thoughtworks/maeve-csms/gateway/cmd" 7 | ) 8 | 9 | func main() { 10 | cmd.Execute() 11 | } 12 | -------------------------------------------------------------------------------- /gateway/pipe/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package pipe provides the core functionality for transferring messages between 4 | // a charge station and a CSMS using OCPP/J. 5 | // A Pipe is a bidirectional connection where OCPP Call and CallResult (or CallError) 6 | // messages are brokered. A Pipe is agnostic to the actual communication channels. It 7 | // is up to the caller to ensure that the charge station and CSMS Rx and Tx channels 8 | // are hooked up to an appropriate source or sink. 9 | package pipe 10 | -------------------------------------------------------------------------------- /gateway/pipe/message.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package pipe 4 | 5 | import ( 6 | "context" 7 | "encoding/json" 8 | "github.com/thoughtworks/maeve-csms/gateway/ocpp" 9 | ) 10 | 11 | type GatewayMessage struct { 12 | Context context.Context `json:"-"` 13 | MessageType ocpp.MessageType `json:"type"` 14 | Action string `json:"action"` 15 | MessageId string `json:"id"` 16 | RequestPayload json.RawMessage `json:"request,omitempty"` 17 | ResponsePayload json.RawMessage `json:"response,omitempty"` 18 | ErrorCode ocpp.ErrorCode `json:"error_code,omitempty"` 19 | ErrorDescription string `json:"error_description,omitempty"` 20 | State json.RawMessage `json:"state,omitempty"` 21 | } 22 | -------------------------------------------------------------------------------- /gateway/registry/api.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package registry 4 | 5 | import "crypto/x509" 6 | 7 | type SecurityProfile int 8 | 9 | const ( 10 | UnsecuredTransportWithBasicAuth SecurityProfile = iota 11 | TLSWithBasicAuth 12 | TLSWithClientSideCertificates 13 | ) 14 | 15 | type ChargeStation struct { 16 | ClientId string 17 | SecurityProfile SecurityProfile 18 | Base64SHA256Password string 19 | InvalidUsernameAllowed bool 20 | } 21 | 22 | type DeviceRegistry interface { 23 | LookupChargeStation(clientId string) (*ChargeStation, error) 24 | LookupCertificate(certHash string) (*x509.Certificate, error) 25 | } 26 | -------------------------------------------------------------------------------- /gateway/registry/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package registry provides support for retrieving details of a charge station 4 | // from a registry. 5 | package registry 6 | -------------------------------------------------------------------------------- /gateway/registry/mock.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package registry 4 | 5 | import "crypto/x509" 6 | 7 | type MockRegistry struct { 8 | ChargeStations map[string]*ChargeStation 9 | Certificates map[string]*x509.Certificate 10 | } 11 | 12 | func NewMockRegistry() *MockRegistry { 13 | return &MockRegistry{ 14 | ChargeStations: make(map[string]*ChargeStation), 15 | Certificates: make(map[string]*x509.Certificate), 16 | } 17 | } 18 | 19 | func (m MockRegistry) LookupChargeStation(clientId string) (*ChargeStation, error) { 20 | return m.ChargeStations[clientId], nil 21 | } 22 | 23 | func (m MockRegistry) LookupCertificate(certHash string) (*x509.Certificate, error) { 24 | return m.Certificates[certHash], nil 25 | } 26 | -------------------------------------------------------------------------------- /gateway/server/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package server provides the implementation of the HTTP server 4 | // components used by the gateway. 5 | package server 6 | -------------------------------------------------------------------------------- /gateway/server/status.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package server 4 | 5 | import ( 6 | "github.com/go-chi/chi/v5" 7 | "github.com/go-chi/chi/v5/middleware" 8 | "github.com/prometheus/client_golang/prometheus/promhttp" 9 | "net/http" 10 | ) 11 | 12 | func NewStatusHandler() http.Handler { 13 | r := chi.NewRouter() 14 | r.Use(middleware.Recoverer) 15 | r.Get("/health", health) 16 | r.Handle("/metrics", promhttp.Handler()) 17 | return r 18 | } 19 | 20 | func health(w http.ResponseWriter, r *http.Request) { 21 | w.WriteHeader(http.StatusOK) 22 | _, _ = w.Write([]byte(`{"status":"OK"}`)) 23 | } 24 | -------------------------------------------------------------------------------- /gateway/server/status_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package server_test 4 | 5 | import ( 6 | "github.com/thoughtworks/maeve-csms/gateway/server" 7 | "net/http" 8 | "net/http/httptest" 9 | "testing" 10 | ) 11 | 12 | func TestHealthHandler(t *testing.T) { 13 | handler := server.NewStatusHandler() 14 | 15 | req := httptest.NewRequest(http.MethodGet, "/health", nil) 16 | w := httptest.NewRecorder() 17 | handler.ServeHTTP(w, req) 18 | res := w.Result() 19 | defer func() { 20 | err := res.Body.Close() 21 | if err != nil { 22 | t.Errorf("closing body: %v", err) 23 | } 24 | }() 25 | 26 | if res.StatusCode != http.StatusOK { 27 | t.Errorf("status code: want %d, got %d", http.StatusOK, res.StatusCode) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /loadtests/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thoughtworks/maeve-csms/55c65bba34fe89acbbd4830d6f65be914dc6d053/loadtests/.DS_Store -------------------------------------------------------------------------------- /manager/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.2 2 | 3 | # STAGE 1: build the executable 4 | FROM golang:1.20-alpine AS builder 5 | 6 | RUN apk add --no-cache git openssh ca-certificates 7 | WORKDIR /src 8 | 9 | ARG TARGETARCH 10 | 11 | # IF statement executed due to incosistent package names @ https://github.com/moparisthebest/static-curl/issues/8 12 | RUN if [ "$TARGETARCH" = "arm64" ]; then \ 13 | TARGETARCH=aarch64 ; \ 14 | fi; \ 15 | wget -O /usr/bin/curl https://github.com/moparisthebest/static-curl/releases/download/v8.0.1/curl-$TARGETARCH \ 16 | && chmod +x /usr/bin/curl 17 | 18 | COPY ./go.mod ./go.sum ./ 19 | 20 | RUN go mod download 21 | 22 | COPY ./ ./ 23 | 24 | RUN --mount=type=cache,target=/root/.cache/go-build/ CGO_ENABLED=0 go build -o /app main.go 25 | 26 | # STAGE 2: build the container 27 | FROM gcr.io/distroless/static:nonroot AS final 28 | 29 | COPY --from=builder /usr/bin/curl /usr/bin/curl 30 | 31 | USER 10000:10000 32 | 33 | COPY --from=builder --chown=nonroot:nonroot /app /app 34 | 35 | ENTRYPOINT ["/app"] 36 | -------------------------------------------------------------------------------- /manager/adminui/templates/error.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MaEVe Admin UI 5 | 6 | 7 | 8 | 9 | 10 |
11 |

An error occurred

12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /manager/adminui/templates/index.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MaEVe Admin UI 5 | 6 | 7 | 8 | 9 | 10 |
11 |

MaEVe Admin UI

12 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /manager/adminui/templates/post-token.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MaEVe Admin UI 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Token Details

12 |
13 | 14 | 15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /manager/adminui/templates/token.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MaEVe Admin UI 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Create a Token

12 |
13 |
14 | 15 | 16 |
17 | 18 |
19 |
20 | 21 | -------------------------------------------------------------------------------- /manager/api/README.md: -------------------------------------------------------------------------------- 1 | To regenerate code based on the OpenAPI spec: 2 | 3 | ```shell 4 | $ go generate api.go 5 | ``` 6 | 7 | To generate the OpenAPI markdown docs: 8 | 9 | ```shell 10 | $ npm install -g widdershins 11 | $ widdershins api-spec.yaml -o API.md -c true 12 | ``` -------------------------------------------------------------------------------- /manager/api/api.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package api 4 | 5 | //go:generate oapi-codegen -config cfg.yaml api-spec.yaml 6 | //go:generate widdershins api-spec.yaml -o API.md -c true 7 | -------------------------------------------------------------------------------- /manager/api/cfg.yaml: -------------------------------------------------------------------------------- 1 | package: api 2 | generate: 3 | chi-server: true 4 | models: true 5 | embedded-spec: true 6 | compatibility: 7 | apply-chi-middleware-first-to-last: true 8 | output: api.gen.go -------------------------------------------------------------------------------- /manager/api/req.json: -------------------------------------------------------------------------------- 1 | { 2 | "certificates": [ 3 | { 4 | "type": "CSMS", 5 | "certificate": "The certificate value" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /manager/cmd/auth.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | // authCmd represents the auth command 10 | var authCmd = &cobra.Command{ 11 | Use: "auth", 12 | Short: "Support configuring charge station authentication", 13 | } 14 | 15 | func init() { 16 | rootCmd.AddCommand(authCmd) 17 | } 18 | -------------------------------------------------------------------------------- /manager/cmd/auth_encode_password.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "crypto/sha256" 7 | "encoding/base64" 8 | "fmt" 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | // encodePasswordCmd represents the encodePassword command 13 | var encodePasswordCmd = &cobra.Command{ 14 | Use: "encode-password", 15 | Short: "Encode a password for storage in the database", 16 | Run: func(cmd *cobra.Command, args []string) { 17 | for _, pwd := range args { 18 | hash := sha256.Sum256([]byte(pwd)) 19 | b64 := base64.StdEncoding.EncodeToString(hash[:]) 20 | fmt.Printf("%s: %s\n", pwd, b64) 21 | } 22 | }, 23 | } 24 | 25 | func init() { 26 | authCmd.AddCommand(encodePasswordCmd) 27 | } 28 | -------------------------------------------------------------------------------- /manager/cmd/contract.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | // contractCmd represents the contract command 10 | var contractCmd = &cobra.Command{ 11 | Use: "contract", 12 | Short: "Support for contract certificates", 13 | } 14 | 15 | func init() { 16 | rootCmd.AddCommand(contractCmd) 17 | } 18 | -------------------------------------------------------------------------------- /manager/cmd/emaid.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | // emaidCmd represents the emaid command 10 | var emaidCmd = &cobra.Command{ 11 | Use: "emaid", 12 | Short: "Support for working with eMAIDs", 13 | } 14 | 15 | func init() { 16 | rootCmd.AddCommand(emaidCmd) 17 | } 18 | -------------------------------------------------------------------------------- /manager/cmd/emaid_normalize.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "github.com/spf13/cobra" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 9 | ) 10 | 11 | // normalizeCmd represents the checkdigit command 12 | var normalizeCmd = &cobra.Command{ 13 | Use: "normalize", 14 | Short: "Normalize an eMAID", 15 | Long: "Processes each argument and returns its normalized value", 16 | Run: func(cmd *cobra.Command, args []string) { 17 | for _, arg := range args { 18 | norm, err := ocpp.NormalizeEmaid(arg) 19 | if err != nil { 20 | fmt.Printf("%s: %v\n", arg, err) 21 | } else { 22 | fmt.Printf("%s: %s\n", arg, norm) 23 | } 24 | } 25 | }, 26 | } 27 | 28 | func init() { 29 | emaidCmd.AddCommand(normalizeCmd) 30 | } 31 | -------------------------------------------------------------------------------- /manager/cmd/root.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "os" 7 | 8 | "github.com/spf13/cobra" 9 | ) 10 | 11 | // rootCmd represents the base command when called without any subcommands 12 | var rootCmd = &cobra.Command{ 13 | Use: "manager", 14 | Short: "CSMS manager", 15 | Long: `The CSMS component that has responsibility for responding to 16 | OCPP protocol messages.`, 17 | } 18 | 19 | // Execute adds all child commands to the root command and sets flags appropriately. 20 | // This is called by main.main(). It only needs to happen once to the rootCmd. 21 | func Execute() { 22 | err := rootCmd.Execute() 23 | if err != nil { 24 | os.Exit(1) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /manager/cmd/transaction.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package cmd 4 | 5 | import ( 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | // transactionCmd represents the transaction command 10 | var transactionCmd = &cobra.Command{ 11 | Use: "transaction", 12 | Short: "Interact with the transaction store", 13 | Long: `Interact with the transaction store.`, 14 | } 15 | 16 | func init() { 17 | rootCmd.AddCommand(transactionCmd) 18 | } 19 | -------------------------------------------------------------------------------- /manager/config/contract_cert_provider_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package config 4 | 5 | type OpcpContractCertProviderConfig struct { 6 | Url string `mapstructure:"url" toml:"url" validate:"required"` 7 | HttpAuth HttpAuthConfig `mapstructure:"auth" toml:"auth" validate:"required"` 8 | } 9 | 10 | type ContractCertProviderConfig struct { 11 | Type string `mapstructure:"type" toml:"type" validate:"required,oneof=default opcp"` 12 | Opcp *OpcpContractCertProviderConfig `mapstructure:"opcp,omitempty" toml:"opcp,omitempty" validate:"required_if=Type opcp"` 13 | } 14 | -------------------------------------------------------------------------------- /manager/config/contract_cert_validator_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package config 4 | 5 | type OcspContractCertValidatorConfig struct { 6 | RootCertProvider RootCertProviderConfig `mapstructure:"root_certs" toml:"root_certs" validate:"required"` 7 | MaxAttempts int `mapstructure:"max_attempts" toml:"max_attempts" validate:"required"` 8 | } 9 | 10 | type ContractCertValidatorConfig struct { 11 | Type string `mapstructure:"type" toml:"type" validate:"required,oneof=ocsp"` 12 | Ocsp *OcspContractCertValidatorConfig `mapstructure:"ocsp,omitempty" toml:"ocsp,omitempty" validate:"required_if=Type ocsp"` 13 | } 14 | -------------------------------------------------------------------------------- /manager/config/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package config provides support for configuring the system. 4 | // 5 | // BaseConfig provides the data structures that represent the 6 | // configuration and can be used to load configuration from a 7 | // TOML file. 8 | // 9 | // Config consumes the BaseConfig and returns implementations 10 | // of the various interfaces used by the application (in a 11 | // dependency-injection style). 12 | package config 13 | -------------------------------------------------------------------------------- /manager/config/ocpi_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package config 4 | 5 | type OcpiConfig struct { 6 | Addr string `mapstructure:"addr" toml:"addr" validate:"required"` 7 | ExternalURL string `mapstructure:"external_url" toml:"external_url" validate:"required"` 8 | CountryCode string `mapstructure:"country_code" toml:"country_code" validate:"required"` 9 | PartyId string `mapstructure:"party_id" toml:"party_id" validate:"required"` 10 | } 11 | -------------------------------------------------------------------------------- /manager/config/storage_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package config 4 | 5 | type InMemoryStorageConfig struct{} 6 | 7 | type FirestoreStorageConfig struct { 8 | ProjectId string `mapstructure:"project_id" toml:"project_id" validate:"required"` 9 | } 10 | 11 | type StorageConfig struct { 12 | Type string `mapstructure:"type" toml:"type" validate:"required,oneof=firestore in_memory"` 13 | FirestoreStorage *FirestoreStorageConfig `mapstructure:"firestore,omitempty" toml:"firestore,omitempty" validate:"required_if=Type firestore"` 14 | InMemoryStorage *InMemoryStorageConfig `mapstructure:"in_memory,omitempty" toml:"in_memory,omitempty"` 15 | } 16 | -------------------------------------------------------------------------------- /manager/config/tariff_service_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package config 4 | 5 | type TariffServiceConfig struct { 6 | Type string `mapstructure:"type" toml:"type" validate:"required,oneof=kwh"` 7 | } 8 | -------------------------------------------------------------------------------- /manager/config/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PUBLIC KEY----- 2 | MIIBigKCAYEAlTBc4skxuJQNBK1p3CgbjEu3aYFw9fUBYd3+qajCSbIkSmtOLMXT 3 | O62X9/Jn3ZifomSKjx4VmRAtwbkwaPCHzI6pUQv2yjAsv+bXPzcm8YvXo1Emuv5T 4 | HgQopKohsMA9kxWV1VUeXeULGPp8c5QCMlnky4GpGp1GBaMNp9VgMBBIzkSR6xtE 5 | YslePu3gwbZ03HFZTPr/exoXd/4jyIix+p9eTHQZW54GT9KI70+TB7rRTMG65bXH 6 | 9GpFkzIgcxXcEsHabZ92YcJhn29ROo5uebiXxXDV3joFZ8QYOln7Zns599GjXEp7 7 | Ay7RxYmRPycvTJWxDd4f/fOlmM+ekiZAjIeO3L3ZtSFWpy8Dt/tXFsDJi4KHd5MT 8 | JbPTJHptJAWqSLGL5fg7+Jas3FiFAKZ7EWt4IUXM20dSk9nW1by/IoRcUnt+FeTu 9 | 3xknjF+gSBmCdJ6RkMfMJ5IHyY+4GeWYSqbCZZU5Te04djC2DfivJfiogw8k/TwP 10 | Z4qCVwSocu9vAgMBAAE= 11 | -----END RSA PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /manager/config/testdata/root_ca.pem: -------------------------------------------------------------------------------- 1 | subject=/C=DE/O=Hubject GmbH/DC=V2G/CN=V2G Root CA QA G1 2 | issuer=/C=DE/O=Hubject GmbH/DC=V2G/CN=V2G Root CA QA G1 3 | -----BEGIN CERTIFICATE----- 4 | MIICUzCCAfmgAwIBAgIQaasA0lm730LOgFKa0wzl7TAKBggqhkjOPQQDAjBVMQsw 5 | CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRMwEQYKCZImiZPyLGQB 6 | GRYDVjJHMRowGAYDVQQDExFWMkcgUm9vdCBDQSBRQSBHMTAgFw0xOTA0MjYwODM3 7 | MTVaGA8yMDU5MDQyNjA4MzcxNVowVTELMAkGA1UEBhMCREUxFTATBgNVBAoTDEh1 8 | YmplY3QgR21iSDETMBEGCgmSJomT8ixkARkWA1YyRzEaMBgGA1UEAxMRVjJHIFJv 9 | b3QgQ0EgUUEgRzEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAShT8kSNcC+74TN 10 | D82On2Y2TOf8mYfxw73lKZ7t9cmEXHpMdAgsWBQ4LI+pOMhe6NOHzJbzP38kQTg4 11 | zLfw3kU0o4GoMIGlMBMGA1UdJQQMMAoGCCsGAQUFBwMJMA8GA1UdEwEB/wQFMAMB 12 | Af8wEQYDVR0OBAoECEtF/4Il/BCWMEUGA1UdIAQ+MDwwOgYMKwYBBAGCxDUBAgEA 13 | MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3Lmh1YmplY3QuY29tL3BraS8wEwYD 14 | VR0jBAwwCoAIS0X/giX8EJYwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMCA0gA 15 | MEUCIQCq3Qx2BLYVFb7Lt5XXpSlUViYv4cIUOQE1Ce9o2Jyy1QIgZRmVzMVjHZA+ 16 | toiM000PCUrLppqbLpcRN4MP8kE0OhU= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /manager/config/transport_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package config 4 | 5 | type MqttSettingsConfig struct { 6 | Urls []string `mapstructure:"urls" toml:"urls" validate:"required,dive,required"` 7 | Prefix string `mapstructure:"prefix" toml:"prefix" validate:"required"` 8 | Group string `mapstructure:"group" toml:"group" validate:"required"` 9 | ConnectTimeout string `mapstructure:"connect_timeout" toml:"connect_timeout" validate:"required"` 10 | ConnectRetryDelay string `mapstructure:"connect_retry_delay" toml:"connect_retry_delay" validate:"required"` 11 | KeepAliveInterval string `mapstructure:"keep_alive_interval" toml:"keep_alive_interval" validate:"required"` 12 | } 13 | 14 | type TransportConfig struct { 15 | Type string `mapstructure:"type" toml:"type" validate:"required,oneof=mqtt"` 16 | Mqtt *MqttSettingsConfig `mapstructure:"mqtt,omitempty" toml:"mqtt,omitempty" validate:"required_if=Type mqtt"` 17 | } 18 | -------------------------------------------------------------------------------- /manager/handlers/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package handlers defines the interfaces implemented by handlers for OCPP 4 | // messages and the types used when routing those messages. 5 | package handlers 6 | -------------------------------------------------------------------------------- /manager/handlers/has2be/certificate_signed_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | import ( 6 | "context" 7 | "go.opentelemetry.io/otel/attribute" 8 | "go.opentelemetry.io/otel/trace" 9 | 10 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 11 | "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" 12 | ) 13 | 14 | type CertificateSignedResultHandler struct{} 15 | 16 | func (c CertificateSignedResultHandler) HandleCallResult(ctx context.Context, _ string, _ ocpp.Request, response ocpp.Response, _ any) error { 17 | span := trace.SpanFromContext(ctx) 18 | 19 | resp := response.(*has2be.CertificateSignedResponseJson) 20 | 21 | span.SetAttributes(attribute.String("response.status", string(resp.Status))) 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /manager/handlers/has2be/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package has2be defines handlers for processing Has2Be OCPP 1.6 extension messages. 4 | package has2be 5 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package ocpp16 defines handlers for processing OCPP 1.6 messages. 4 | package ocpp16 5 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/heartbeat.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | import ( 6 | "context" 7 | "time" 8 | 9 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 10 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 11 | "k8s.io/utils/clock" 12 | ) 13 | 14 | type HeartbeatHandler struct { 15 | Clock clock.PassiveClock 16 | } 17 | 18 | func (h HeartbeatHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { 19 | return &types.HeartbeatResponseJson{ 20 | CurrentTime: h.Clock.Now().Format(time.RFC3339), 21 | }, nil 22 | } 23 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/heartbeat_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16_test 4 | 5 | import ( 6 | "context" 7 | "github.com/stretchr/testify/assert" 8 | "github.com/stretchr/testify/require" 9 | handlers "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp16" 10 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 11 | clockTest "k8s.io/utils/clock/testing" 12 | "testing" 13 | "time" 14 | ) 15 | 16 | func TestHeartbeatHandler(t *testing.T) { 17 | now, err := time.Parse(time.RFC3339, "2023-06-15T15:05:00+01:00") 18 | require.NoError(t, err) 19 | clock := clockTest.NewFakePassiveClock(now) 20 | 21 | handler := handlers.HeartbeatHandler{ 22 | Clock: clock, 23 | } 24 | 25 | req := &types.HeartbeatJson{} 26 | 27 | got, err := handler.HandleCall(context.Background(), "cs001", req) 28 | assert.NoError(t, err) 29 | 30 | want := &types.HeartbeatResponseJson{ 31 | CurrentTime: "2023-06-15T15:05:00+01:00", 32 | } 33 | 34 | assert.Equal(t, want, got) 35 | } 36 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/meter_values.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | import ( 6 | "context" 7 | 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 9 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 10 | "github.com/thoughtworks/maeve-csms/manager/store" 11 | ) 12 | 13 | type MeterValuesHandler struct { 14 | TransactionStore store.TransactionStore 15 | } 16 | 17 | func (m MeterValuesHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 18 | // TODO: store in transaction store 19 | 20 | return &types.MeterValuesResponseJson{}, nil 21 | } 22 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/meter_values_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16_test 4 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/security_event_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type SecurityEventNotificationHandler struct{} 14 | 15 | func (s SecurityEventNotificationHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 16 | req := request.(*ocpp16.SecurityEventNotificationJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes(attribute.String("security_event.timestamp", req.Timestamp), attribute.String("security_event.type", req.Type)) 21 | if req.TechInfo != nil { 22 | span.SetAttributes(attribute.String("security_event.tech_info", *req.TechInfo)) 23 | } 24 | 25 | return &ocpp16.SecurityEventNotificationResponseJson{}, nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/status_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | import ( 6 | "context" 7 | "go.opentelemetry.io/otel/attribute" 8 | "go.opentelemetry.io/otel/trace" 9 | 10 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 11 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 12 | ) 13 | 14 | func StatusNotificationHandler(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { 15 | span := trace.SpanFromContext(ctx) 16 | 17 | req := request.(*types.StatusNotificationJson) 18 | 19 | span.SetAttributes( 20 | attribute.Int("status.connector_id", req.ConnectorId), 21 | attribute.String("status.connector_status", string(req.Status))) 22 | 23 | return &types.StatusNotificationResponseJson{}, nil 24 | } 25 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/status_notification_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16_test 4 | 5 | import ( 6 | "context" 7 | "github.com/stretchr/testify/assert" 8 | handlers "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp16" 9 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 10 | "testing" 11 | ) 12 | 13 | func TestStatusNotificationHandler(t *testing.T) { 14 | timestamp := "2023-05-01T01:00:00+01:00" 15 | req := &types.StatusNotificationJson{ 16 | Timestamp: ×tamp, 17 | ConnectorId: 2, 18 | ErrorCode: types.StatusNotificationJsonErrorCodeNoError, 19 | Status: types.StatusNotificationJsonStatusPreparing, 20 | } 21 | 22 | got, err := handlers.StatusNotificationHandler(context.Background(), "cs001", req) 23 | assert.NoError(t, err) 24 | 25 | want := &types.StatusNotificationResponseJson{} 26 | 27 | assert.Equal(t, want, got) 28 | } 29 | -------------------------------------------------------------------------------- /manager/handlers/ocpp16/trigger_message_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type TriggerMessageResultHandler struct{} 14 | 15 | func (c TriggerMessageResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*ocpp16.TriggerMessageJson) 17 | resp := response.(*ocpp16.TriggerMessageResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.String("trigger.requested_message", string(req.RequestedMessage)), 23 | attribute.String("trigger.status", string(resp.Status))) 24 | 25 | if req.ConnectorId != nil { 26 | span.SetAttributes(attribute.Int("trigger.connector_id", *req.ConnectorId)) 27 | } 28 | 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/certificate_id.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "crypto/sha256" 7 | "encoding/hex" 8 | "encoding/pem" 9 | "fmt" 10 | ) 11 | 12 | // GetCertificateId returns the SHA-256 thumbprint of the certificate 13 | func GetCertificateId(pemData string) (string, error) { 14 | block, _ := pem.Decode([]byte(pemData)) 15 | if block == nil { 16 | return "", fmt.Errorf("failed to decode certificate chain") 17 | } 18 | if block.Type != "CERTIFICATE" { 19 | return "", fmt.Errorf("expected certificate, got %s", block.Type) 20 | } 21 | hash := sha256.Sum256(block.Bytes) 22 | certificateId := hex.EncodeToString(hash[:]) 23 | 24 | return certificateId, nil 25 | } 26 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/clear_cache.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type ClearCacheResultHandler struct{} 14 | 15 | func (h ClearCacheResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | resp := response.(*types.ClearCacheResponseJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes( 21 | attribute.String("clear_cache.status", string(resp.Status))) 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/clear_cache_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201_test 4 | 5 | import ( 6 | "context" 7 | "github.com/stretchr/testify/require" 8 | "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" 9 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 10 | "github.com/thoughtworks/maeve-csms/manager/testutil" 11 | "testing" 12 | ) 13 | 14 | func TestClearCacheResultHandler(t *testing.T) { 15 | handler := ocpp201.ClearCacheResultHandler{} 16 | 17 | tracer, exporter := testutil.GetTracer() 18 | 19 | ctx := context.Background() 20 | 21 | func() { 22 | ctx, span := tracer.Start(ctx, `test`) 23 | defer span.End() 24 | 25 | req := &types.ClearCacheRequestJson{} 26 | resp := &types.ClearCacheResponseJson{ 27 | Status: types.ClearCacheStatusEnumTypeAccepted, 28 | } 29 | 30 | err := handler.HandleCallResult(ctx, "cs001", req, resp, nil) 31 | require.NoError(t, err) 32 | }() 33 | 34 | testutil.AssertSpan(t, &exporter.GetSpans()[0], "test", map[string]any{ 35 | "clear_cache.status": "Accepted", 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/delete_certificate_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type DeleteCertificateResultHandler struct{} 14 | 15 | func (h DeleteCertificateResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.DeleteCertificateRequestJson) 17 | resp := response.(*types.DeleteCertificateResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.String("delete_certificate.serial_number", req.CertificateHashData.SerialNumber), 23 | attribute.String("delete_certificate.status", string(resp.Status))) 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package ocpp201 defines handlers for processing OCPP 2.0.1 messages. 4 | package ocpp201 5 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/firmware_status_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type FirmwareStatusNotificationHandler struct{} 14 | 15 | func (h FirmwareStatusNotificationHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 16 | req := request.(*ocpp201.FirmwareStatusNotificationRequestJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes(attribute.String("firmware_status.status", string(req.Status))) 21 | if req.RequestId != nil { 22 | span.SetAttributes(attribute.Int("firmware_status.request_id", *req.RequestId)) 23 | } 24 | 25 | return &ocpp201.FirmwareStatusNotificationResponseJson{}, nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/get_base_report_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type GetBaseReportResultHandler struct{} 14 | 15 | func (h GetBaseReportResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.GetBaseReportRequestJson) 17 | resp := response.(*types.GetBaseReportResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.Int("get_base_report.request_id", req.RequestId), 23 | attribute.String("get_base_report.report_base", string(req.ReportBase)), 24 | attribute.String("get_base_report.status", string(resp.Status))) 25 | 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/get_local_list_version_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type GetLocalListVersionResultHandler struct{} 14 | 15 | func (h GetLocalListVersionResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | resp := response.(*types.GetLocalListVersionResponseJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes( 21 | attribute.Int("get_local_list_version.version_number", resp.VersionNumber)) 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/get_report_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type GetReportResultHandler struct{} 14 | 15 | func (h GetReportResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.GetReportRequestJson) 17 | resp := response.(*types.GetReportResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.Int("get_report.request_id", req.RequestId), 23 | attribute.String("get_report.status", string(resp.Status))) 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/heartbeat.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "time" 8 | 9 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 10 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 11 | "k8s.io/utils/clock" 12 | ) 13 | 14 | type HeartbeatHandler struct { 15 | Clock clock.PassiveClock 16 | } 17 | 18 | func (h HeartbeatHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { 19 | return &types.HeartbeatResponseJson{ 20 | CurrentTime: h.Clock.Now().Format(time.RFC3339), 21 | }, nil 22 | } 23 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/heartbeat_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201_test 4 | 5 | import ( 6 | "context" 7 | "github.com/stretchr/testify/assert" 8 | "github.com/stretchr/testify/require" 9 | handlers "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" 10 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 11 | clockTest "k8s.io/utils/clock/testing" 12 | "testing" 13 | "time" 14 | ) 15 | 16 | func TestHeartbeatHandler(t *testing.T) { 17 | now, err := time.Parse(time.RFC3339, "2023-06-15T15:05:00+01:00") 18 | require.NoError(t, err) 19 | clock := clockTest.NewFakePassiveClock(now) 20 | 21 | handler := handlers.HeartbeatHandler{ 22 | Clock: clock, 23 | } 24 | 25 | req := &types.HeartbeatRequestJson{} 26 | 27 | got, err := handler.HandleCall(context.Background(), "cs001", req) 28 | assert.NoError(t, err) 29 | 30 | want := &types.HeartbeatResponseJson{ 31 | CurrentTime: "2023-06-15T15:05:00+01:00", 32 | } 33 | 34 | assert.Equal(t, want, got) 35 | } 36 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/log_status_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type LogStatusNotificationHandler struct{} 14 | 15 | func (h LogStatusNotificationHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 16 | req := request.(*ocpp201.LogStatusNotificationRequestJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes(attribute.String("log_status.status", string(req.Status))) 21 | if req.RequestId != nil { 22 | span.SetAttributes(attribute.Int("log_status.request_id", *req.RequestId)) 23 | } 24 | 25 | return &ocpp201.LogStatusNotificationResponseJson{}, nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/meter_values.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type MeterValuesHandler struct{} 14 | 15 | func (h MeterValuesHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 16 | req := request.(*ocpp201.MeterValuesRequestJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes(attribute.Int("meter_values.evse_id", req.EvseId)) 21 | 22 | return &ocpp201.MeterValuesResponseJson{}, nil 23 | } 24 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/notify_report.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type NotifyReportHandler struct{} 14 | 15 | func (h NotifyReportHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 16 | req := request.(*ocpp201.NotifyReportRequestJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes( 21 | attribute.String("notify_report.generated_at", req.GeneratedAt), 22 | attribute.Int("notify_report.request_id", req.RequestId), 23 | attribute.Int("notify_report.seq_no", req.SeqNo), 24 | attribute.Bool("notify_report.tbc", req.Tbc)) 25 | 26 | return &ocpp201.NotifyReportResponseJson{}, nil 27 | } 28 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/request_stop_transaction_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type RequestStopTransactionResultHandler struct{} 14 | 15 | func (h RequestStopTransactionResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.RequestStopTransactionRequestJson) 17 | resp := response.(*types.RequestStopTransactionResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.String("request_stop.transaction_id", req.TransactionId), 23 | attribute.String("request_stop.status", string(resp.Status))) 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/reset_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type ResetResultHandler struct{} 14 | 15 | func (h ResetResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.ResetRequestJson) 17 | resp := response.(*types.ResetResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.String("reset.type", string(req.Type)), 23 | attribute.String("reset.status", string(resp.Status))) 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/security_event_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type SecurityEventNotificationHandler struct{} 14 | 15 | func (s SecurityEventNotificationHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (response ocpp.Response, err error) { 16 | req := request.(*ocpp201.SecurityEventNotificationRequestJson) 17 | 18 | span := trace.SpanFromContext(ctx) 19 | 20 | span.SetAttributes(attribute.String("security_event.timestamp", req.Timestamp), attribute.String("security_event.type", req.Type)) 21 | if req.TechInfo != nil { 22 | span.SetAttributes(attribute.String("security_event.tech_info", *req.TechInfo)) 23 | } 24 | 25 | return &ocpp201.SecurityEventNotificationResponseJson{}, nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/send_local_list_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type SendLocalListResultHandler struct{} 14 | 15 | func (h SendLocalListResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.SendLocalListRequestJson) 17 | resp := response.(*types.SendLocalListResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.String("send_local_list.update_type", string(req.UpdateType)), 23 | attribute.Int("send_local_list.version_number", req.VersionNumber), 24 | attribute.String("send_local_list.status", string(resp.Status))) 25 | 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/set_network_profile_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type SetNetworkProfileResultHandler struct{} 14 | 15 | func (h SetNetworkProfileResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*types.SetNetworkProfileRequestJson) 17 | resp := response.(*types.SetNetworkProfileResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | 21 | span.SetAttributes( 22 | attribute.Int("set_network_profile.config_slot", req.ConfigurationSlot), 23 | attribute.String("set_network_profile.status", string(resp.Status))) 24 | 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/status_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "go.opentelemetry.io/otel/attribute" 8 | "go.opentelemetry.io/otel/trace" 9 | 10 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 11 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 12 | ) 13 | 14 | func StatusNotificationHandler(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { 15 | span := trace.SpanFromContext(ctx) 16 | 17 | req := request.(*types.StatusNotificationRequestJson) 18 | 19 | span.SetAttributes( 20 | attribute.Int("status.evse_id", req.EvseId), 21 | attribute.Int("status.connector_id", req.ConnectorId), 22 | attribute.String("status.connector_status", string(req.ConnectorStatus))) 23 | 24 | return &types.StatusNotificationResponseJson{}, nil 25 | } 26 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/status_notification_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201_test 4 | 5 | import ( 6 | "context" 7 | "github.com/stretchr/testify/assert" 8 | handlers "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" 9 | types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 10 | "testing" 11 | ) 12 | 13 | func TestStatusNotificationHandler(t *testing.T) { 14 | req := &types.StatusNotificationRequestJson{ 15 | Timestamp: "2023-05-01T01:00:00+01:00", 16 | EvseId: 1, 17 | ConnectorId: 2, 18 | ConnectorStatus: types.ConnectorStatusEnumTypeOccupied, 19 | } 20 | 21 | got, err := handlers.StatusNotificationHandler(context.Background(), "cs001", req) 22 | assert.NoError(t, err) 23 | 24 | want := &types.StatusNotificationResponseJson{} 25 | 26 | assert.Equal(t, want, got) 27 | } 28 | -------------------------------------------------------------------------------- /manager/handlers/ocpp201/unlock_connector_result.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | import ( 6 | "context" 7 | "github.com/thoughtworks/maeve-csms/manager/ocpp" 8 | "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" 9 | "go.opentelemetry.io/otel/attribute" 10 | "go.opentelemetry.io/otel/trace" 11 | ) 12 | 13 | type UnlockConnectorResultHandler struct{} 14 | 15 | func (h UnlockConnectorResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { 16 | req := request.(*ocpp201.UnlockConnectorRequestJson) 17 | resp := response.(*ocpp201.UnlockConnectorResponseJson) 18 | 19 | span := trace.SpanFromContext(ctx) 20 | span.SetAttributes(attribute.Int("unlock_connector.evse_id", req.EvseId), 21 | attribute.Int("unlock_connector.connector_id", req.ConnectorId), 22 | attribute.String("unlock_connector.status", string(resp.Status))) 23 | 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /manager/handlers/testdata/schemas/EmptySchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "title": "EmptySchema", 4 | "type": "object", 5 | "properties": { 6 | }, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/handlers/testdata/schemas/RequiredFieldSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "title": "RequiredFieldSchema", 4 | "type": "object", 5 | "properties": { 6 | "data": { 7 | "type": "string" 8 | } 9 | }, 10 | "additionalProperties": false, 11 | "required": [ 12 | "data" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /manager/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package main 4 | 5 | import ( 6 | "github.com/thoughtworks/maeve-csms/manager/cmd" 7 | ) 8 | 9 | func main() { 10 | cmd.Execute() 11 | } 12 | -------------------------------------------------------------------------------- /manager/ocpi/cfg.yaml: -------------------------------------------------------------------------------- 1 | package: ocpi 2 | generate: 3 | chi-server: true 4 | models: true 5 | embedded-spec: true 6 | compatibility: 7 | apply-chi-middleware-first-to-last: true 8 | output: ocpi.gen.go -------------------------------------------------------------------------------- /manager/ocpi/correlation.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpi 4 | 5 | import ( 6 | "github.com/google/uuid" 7 | "golang.org/x/net/context" 8 | "net/http" 9 | ) 10 | 11 | type ContextKey string 12 | 13 | const ( 14 | ContextKeyCorrelationId ContextKey = "correlation_id" 15 | ) 16 | 17 | func CorrelationIDMiddleware(next http.Handler) http.Handler { 18 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 19 | ctx := r.Context() 20 | id := r.Header.Get("X-Correlation-Id") 21 | if id == "" { 22 | id = uuid.New().String() 23 | } 24 | ctx = context.WithValue(ctx, ContextKeyCorrelationId, id) 25 | r = r.WithContext(ctx) 26 | w.Header().Set("X-Correlation-Id", id) 27 | next.ServeHTTP(w, r) 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /manager/ocpi/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package ocpi implements the OCPI API for interacting with eMSPs (MOs) 4 | package ocpi 5 | -------------------------------------------------------------------------------- /manager/ocpi/render.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpi 4 | 5 | import "net/http" 6 | 7 | func (OcpiResponseCommandResponse) Render(http.ResponseWriter, *http.Request) error { 8 | return nil 9 | } 10 | 11 | func (OcpiResponseListVersion) Render(http.ResponseWriter, *http.Request) error { 12 | return nil 13 | } 14 | 15 | func (OcpiResponseVersionDetail) Render(http.ResponseWriter, *http.Request) error { 16 | return nil 17 | } 18 | 19 | func (OcpiResponseToken) Render(http.ResponseWriter, *http.Request) error { 20 | return nil 21 | } 22 | 23 | func (Credentials) Bind(r *http.Request) error { 24 | return nil 25 | } 26 | 27 | func (Token) Bind(r *http.Request) error { 28 | return nil 29 | } 30 | 31 | func (StartSession) Bind(r *http.Request) error { 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /manager/ocpp/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package ocpp provides marker interfaces for types that are intended 4 | // to be OCPP requests and responses. Types should always implement 5 | // these interfaces using a pointer receiver. 6 | package ocpp 7 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/certificate_signed_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type CertificateSignedRequestJson struct { 6 | // The signed X.509 certificate, first DER encoded into binary, and then hex 7 | // encoded into a case insensitive string. This can also contain the necessary sub 8 | // CA certificates. In that case, the order should follow the certificate chain, 9 | // starting from the leaf certificate. 10 | 11 | // TypeOfCertificate corresponds to the JSON schema field "typeOfCertificate". 12 | TypeOfCertificate CertificateSigningUseEnumType `json:"typeOfCertificate" yaml:"typeOfCertificate" mapstructure:"typeOfCertificate"` 13 | } 14 | 15 | func (*CertificateSignedRequestJson) IsRequest() {} 16 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/certificate_signed_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type CertificateSignedStatusEnumType string 6 | 7 | type CertificateSignedResponseJson struct { 8 | // Status corresponds to the JSON schema field "status". 9 | Status CertificateSignedStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 10 | } 11 | 12 | const CertificateSignedStatusEnumTypeAccepted CertificateSignedStatusEnumType = "Accepted" 13 | const CertificateSignedStatusEnumTypeRejected CertificateSignedStatusEnumType = "Rejected" 14 | 15 | func (*CertificateSignedResponseJson) IsResponse() {} 16 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/get_15118_ev_certificate_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type Get15118EVCertificateRequestJson struct { 6 | // Schema version currently used for the 15118 session between EV and Charging 7 | // Station. Needed for parsing of the EXI stream by the CSMS. 8 | A15118SchemaVersion *string `json:"15118SchemaVersion,omitempty" yaml:"15118SchemaVersion,omitempty" mapstructure:"15118SchemaVersion,omitempty"` 9 | 10 | // Raw CertificateInstallationReq request from EV, Base64 encoded. 11 | ExiRequest string `json:"exiRequest" yaml:"exiRequest" mapstructure:"exiRequest"` 12 | } 13 | 14 | func (*Get15118EVCertificateRequestJson) IsRequest() {} 15 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/get_certificate_status_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type GetCertificateStatusRequestJson struct { 6 | // OcspRequestData corresponds to the JSON schema field "ocspRequestData". 7 | OcspRequestData OCSPRequestDataType `json:"ocspRequestData" yaml:"ocspRequestData" mapstructure:"ocspRequestData"` 8 | } 9 | 10 | func (*GetCertificateStatusRequestJson) IsRequest() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/get_certificate_status_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type GetCertificateStatusEnumType string 6 | 7 | const GetCertificateStatusEnumTypeAccepted GetCertificateStatusEnumType = "Accepted" 8 | const GetCertificateStatusEnumTypeFailed GetCertificateStatusEnumType = "Failed" 9 | 10 | type GetCertificateStatusResponseJson struct { 11 | // OCSPResponse class as defined in <>. DER encoded (as defined in <>;), and then base64 encoded. MAY only be omitted when status is not 14 | // Accepted. 15 | OcspResult *string `json:"ocspResult,omitempty" yaml:"ocspResult,omitempty" mapstructure:"ocspResult,omitempty"` 16 | 17 | // Status corresponds to the JSON schema field "status". 18 | Status GetCertificateStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 19 | } 20 | 21 | func (*GetCertificateStatusResponseJson) IsResponse() {} 22 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/sign_certificate_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type SignCertificateRequestJson struct { 6 | // The Charging Station SHALL send the public key in form of a Certificate Signing 7 | // Request (CSR) as described in the X.509 standard. 8 | Csr string `json:"csr" yaml:"csr" mapstructure:"csr"` 9 | 10 | // TypeOfCertificate corresponds to the JSON schema field "typeOfCertificate". 11 | TypeOfCertificate *CertificateSigningUseEnumType `json:"typeOfCertificate,omitempty" yaml:"typeOfCertificate,omitempty" mapstructure:"typeOfCertificate,omitempty"` 12 | } 13 | 14 | func (*SignCertificateRequestJson) IsRequest() {} 15 | -------------------------------------------------------------------------------- /manager/ocpp/has2be/sign_certificate_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package has2be 4 | 5 | type GenericStatusEnumType string 6 | 7 | const GenericStatusEnumTypeAccepted GenericStatusEnumType = "Accepted" 8 | const GenericStatusEnumTypeRejected GenericStatusEnumType = "Rejected" 9 | 10 | type SignCertificateResponseJson struct { 11 | // Status corresponds to the JSON schema field "status". 12 | Status GenericStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 13 | } 14 | 15 | func (*SignCertificateResponseJson) IsResponse() {} 16 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/authorize.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type AuthorizeJson struct { 6 | // IdTag corresponds to the JSON schema field "idTag". 7 | IdTag string `json:"idTag" yaml:"idTag" mapstructure:"idTag"` 8 | } 9 | 10 | func (*AuthorizeJson) IsRequest() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/boot_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type BootNotificationResponseJsonStatus string 6 | 7 | type BootNotificationResponseJson struct { 8 | // CurrentTime corresponds to the JSON schema field "currentTime". 9 | CurrentTime string `json:"currentTime" yaml:"currentTime" mapstructure:"currentTime"` 10 | 11 | // Interval corresponds to the JSON schema field "interval". 12 | Interval int `json:"interval" yaml:"interval" mapstructure:"interval"` 13 | 14 | // Status corresponds to the JSON schema field "status". 15 | Status BootNotificationResponseJsonStatus `json:"status" yaml:"status" mapstructure:"status"` 16 | } 17 | 18 | const BootNotificationResponseJsonStatusAccepted BootNotificationResponseJsonStatus = "Accepted" 19 | const BootNotificationResponseJsonStatusPending BootNotificationResponseJsonStatus = "Pending" 20 | const BootNotificationResponseJsonStatusRejected BootNotificationResponseJsonStatus = "Rejected" 21 | 22 | func (*BootNotificationResponseJson) IsResponse() {} 23 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/change_configuration.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type ChangeConfigurationJson struct { 6 | // Key corresponds to the JSON schema field "key". 7 | Key string `json:"key" yaml:"key" mapstructure:"key"` 8 | 9 | // Value corresponds to the JSON schema field "value". 10 | Value string `json:"value" yaml:"value" mapstructure:"value"` 11 | } 12 | 13 | func (*ChangeConfigurationJson) IsRequest() {} 14 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/change_configuration_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type ChangeConfigurationResponseJsonStatus string 6 | 7 | type ChangeConfigurationResponseJson struct { 8 | // Status corresponds to the JSON schema field "status". 9 | Status ChangeConfigurationResponseJsonStatus `json:"status" yaml:"status" mapstructure:"status"` 10 | } 11 | 12 | const ChangeConfigurationResponseJsonStatusAccepted ChangeConfigurationResponseJsonStatus = "Accepted" 13 | const ChangeConfigurationResponseJsonStatusNotSupported ChangeConfigurationResponseJsonStatus = "NotSupported" 14 | const ChangeConfigurationResponseJsonStatusRebootRequired ChangeConfigurationResponseJsonStatus = "RebootRequired" 15 | const ChangeConfigurationResponseJsonStatusRejected ChangeConfigurationResponseJsonStatus = "Rejected" 16 | 17 | func (*ChangeConfigurationResponseJson) IsResponse() {} 18 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/data_transfer.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type DataTransferJson struct { 6 | // Data corresponds to the JSON schema field "data". 7 | Data *string `json:"data,omitempty" yaml:"data,omitempty" mapstructure:"data,omitempty"` 8 | 9 | // MessageId corresponds to the JSON schema field "messageId". 10 | MessageId *string `json:"messageId,omitempty" yaml:"messageId,omitempty" mapstructure:"messageId,omitempty"` 11 | 12 | // VendorId corresponds to the JSON schema field "vendorId". 13 | VendorId string `json:"vendorId" yaml:"vendorId" mapstructure:"vendorId"` 14 | } 15 | 16 | func (*DataTransferJson) IsRequest() {} 17 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/data_transfer_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type DataTransferResponseJsonStatus string 6 | 7 | type DataTransferResponseJson struct { 8 | // Data corresponds to the JSON schema field "data". 9 | Data *string `json:"data,omitempty" yaml:"data,omitempty" mapstructure:"data,omitempty"` 10 | 11 | // Status corresponds to the JSON schema field "status". 12 | Status DataTransferResponseJsonStatus `json:"status" yaml:"status" mapstructure:"status"` 13 | } 14 | 15 | const DataTransferResponseJsonStatusAccepted DataTransferResponseJsonStatus = "Accepted" 16 | const DataTransferResponseJsonStatusRejected DataTransferResponseJsonStatus = "Rejected" 17 | const DataTransferResponseJsonStatusUnknownMessageId DataTransferResponseJsonStatus = "UnknownMessageId" 18 | const DataTransferResponseJsonStatusUnknownVendorId DataTransferResponseJsonStatus = "UnknownVendorId" 19 | 20 | func (*DataTransferResponseJson) IsResponse() {} 21 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package ocpp16 contains types that represent each of the different OCPP 1.6 4 | // protocol messages. The files have been generated using gojsonschema with all 5 | // explicit Unmarshaller functions removed as validation is handled separately. 6 | package ocpp16 7 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/heartbeat.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type HeartbeatJson map[string]interface{} 6 | 7 | func (*HeartbeatJson) IsRequest() {} 8 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/heartbeat_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type HeartbeatResponseJson struct { 6 | // CurrentTime corresponds to the JSON schema field "currentTime". 7 | CurrentTime string `json:"currentTime" yaml:"currentTime" mapstructure:"currentTime"` 8 | } 9 | 10 | func (*HeartbeatResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/meter_values_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type MeterValuesResponseJson map[string]interface{} 6 | 7 | func (*MeterValuesResponseJson) IsResponse() {} 8 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/remote_start_transaction_response.go: -------------------------------------------------------------------------------- 1 | package ocpp16 2 | 3 | type RemoteStartTransactionResponseJsonStatus string 4 | 5 | type RemoteStartTransactionResponseJson struct { 6 | // Status corresponds to the JSON schema field "status". 7 | Status RemoteStartTransactionResponseJsonStatus `json:"status" yaml:"status" mapstructure:"status"` 8 | } 9 | 10 | const RemoteStartTransactionResponseJsonStatusAccepted RemoteStartTransactionResponseJsonStatus = "Accepted" 11 | const RemoteStartTransactionResponseJsonStatusRejected RemoteStartTransactionResponseJsonStatus = "Rejected" 12 | 13 | func (*RemoteStartTransactionResponseJson) IsResponse() {} 14 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/security_event_notification.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type SecurityEventNotificationJson struct { 6 | // TechInfo corresponds to the JSON schema field "techInfo". 7 | TechInfo *string `json:"techInfo,omitempty" yaml:"techInfo,omitempty" mapstructure:"techInfo,omitempty"` 8 | 9 | // Timestamp corresponds to the JSON schema field "timestamp". 10 | Timestamp string `json:"timestamp" yaml:"timestamp" mapstructure:"timestamp"` 11 | 12 | // Type corresponds to the JSON schema field "type". 13 | Type string `json:"type" yaml:"type" mapstructure:"type"` 14 | } 15 | 16 | func (*SecurityEventNotificationJson) IsRequest() {} 17 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/security_event_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type SecurityEventNotificationResponseJson map[string]interface{} 6 | 7 | func (*SecurityEventNotificationResponseJson) IsResponse() {} 8 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/start_transaction.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type StartTransactionJson struct { 6 | // ConnectorId corresponds to the JSON schema field "connectorId". 7 | ConnectorId int `json:"connectorId" yaml:"connectorId" mapstructure:"connectorId"` 8 | 9 | // IdTag corresponds to the JSON schema field "idTag". 10 | IdTag string `json:"idTag" yaml:"idTag" mapstructure:"idTag"` 11 | 12 | // MeterStart corresponds to the JSON schema field "meterStart". 13 | MeterStart int `json:"meterStart" yaml:"meterStart" mapstructure:"meterStart"` 14 | 15 | // ReservationId corresponds to the JSON schema field "reservationId". 16 | ReservationId *int `json:"reservationId,omitempty" yaml:"reservationId,omitempty" mapstructure:"reservationId,omitempty"` 17 | 18 | // Timestamp corresponds to the JSON schema field "timestamp". 19 | Timestamp string `json:"timestamp" yaml:"timestamp" mapstructure:"timestamp"` 20 | } 21 | 22 | func (*StartTransactionJson) IsRequest() {} 23 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/status_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type StatusNotificationResponseJson map[string]interface{} 6 | 7 | func (*StatusNotificationResponseJson) IsResponse() {} 8 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp16/trigger_message_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp16 4 | 5 | type TriggerMessageResponseJsonStatus string 6 | 7 | type TriggerMessageResponseJson struct { 8 | // Status corresponds to the JSON schema field "status". 9 | Status TriggerMessageResponseJsonStatus `json:"status" yaml:"status" mapstructure:"status"` 10 | } 11 | 12 | const TriggerMessageResponseJsonStatusAccepted TriggerMessageResponseJsonStatus = "Accepted" 13 | const TriggerMessageResponseJsonStatusNotImplemented TriggerMessageResponseJsonStatus = "NotImplemented" 14 | const TriggerMessageResponseJsonStatusRejected TriggerMessageResponseJsonStatus = "Rejected" 15 | 16 | func (*TriggerMessageResponseJson) IsResponse() {} 17 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/additional_info_type.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | // Contains a case insensitive identifier to use for the authorization and the type 6 | // of authorization to support multiple forms of identifiers. 7 | type AdditionalInfoType struct { 8 | // This field specifies the additional IdToken. 9 | // 10 | AdditionalIdToken string `json:"additionalIdToken" yaml:"additionalIdToken" mapstructure:"additionalIdToken"` 11 | 12 | // CustomData corresponds to the JSON schema field "customData". 13 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 14 | 15 | // This defines the type of the additionalIdToken. This is a custom type, so the 16 | // implementation needs to be agreed upon by all involved parties. 17 | // 18 | Type string `json:"type" yaml:"type" mapstructure:"type"` 19 | } 20 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/authorization_status_enum_type.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type AuthorizationStatusEnumType string 6 | 7 | const AuthorizationStatusEnumTypeAccepted AuthorizationStatusEnumType = "Accepted" 8 | const AuthorizationStatusEnumTypeBlocked AuthorizationStatusEnumType = "Blocked" 9 | const AuthorizationStatusEnumTypeConcurrentTx AuthorizationStatusEnumType = "ConcurrentTx" 10 | const AuthorizationStatusEnumTypeExpired AuthorizationStatusEnumType = "Expired" 11 | const AuthorizationStatusEnumTypeInvalid AuthorizationStatusEnumType = "Invalid" 12 | const AuthorizationStatusEnumTypeNoCredit AuthorizationStatusEnumType = "NoCredit" 13 | const AuthorizationStatusEnumTypeNotAllowedTypeEVSE AuthorizationStatusEnumType = "NotAllowedTypeEVSE" 14 | const AuthorizationStatusEnumTypeNotAtThisLocation AuthorizationStatusEnumType = "NotAtThisLocation" 15 | const AuthorizationStatusEnumTypeNotAtThisTime AuthorizationStatusEnumType = "NotAtThisTime" 16 | const AuthorizationStatusEnumTypeUnknown AuthorizationStatusEnumType = "Unknown" 17 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/certificate_signed_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type CertificateSignedStatusEnumType string 6 | 7 | const CertificateSignedStatusEnumTypeAccepted CertificateSignedStatusEnumType = "Accepted" 8 | const CertificateSignedStatusEnumTypeRejected CertificateSignedStatusEnumType = "Rejected" 9 | 10 | type CertificateSignedResponseJson struct { 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // Status corresponds to the JSON schema field "status". 15 | Status CertificateSignedStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 16 | 17 | // StatusInfo corresponds to the JSON schema field "statusInfo". 18 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 19 | } 20 | 21 | func (*CertificateSignedResponseJson) IsResponse() {} 22 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/change_availability_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type OperationalStatusEnumType string 6 | 7 | const OperationalStatusEnumTypeInoperative OperationalStatusEnumType = "Inoperative" 8 | const OperationalStatusEnumTypeOperative OperationalStatusEnumType = "Operative" 9 | 10 | type ChangeAvailabilityRequestJson struct { 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // Evse corresponds to the JSON schema field "evse". 15 | Evse *EVSEType `json:"evse,omitempty" yaml:"evse,omitempty" mapstructure:"evse,omitempty"` 16 | 17 | // OperationalStatus corresponds to the JSON schema field "operationalStatus". 18 | OperationalStatus OperationalStatusEnumType `json:"operationalStatus" yaml:"operationalStatus" mapstructure:"operationalStatus"` 19 | } 20 | 21 | func (*ChangeAvailabilityRequestJson) IsRequest() {} 22 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/clear_cache_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type ClearCacheRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*ClearCacheRequestJson) IsRequest() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/clear_cache_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type ClearCacheStatusEnumType string 6 | 7 | const ClearCacheStatusEnumTypeAccepted ClearCacheStatusEnumType = "Accepted" 8 | const ClearCacheStatusEnumTypeRejected ClearCacheStatusEnumType = "Rejected" 9 | 10 | type ClearCacheResponseJson struct { 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // Status corresponds to the JSON schema field "status". 15 | Status ClearCacheStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 16 | 17 | // StatusInfo corresponds to the JSON schema field "statusInfo". 18 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 19 | } 20 | 21 | func (*ClearCacheResponseJson) IsResponse() {} 22 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/custom_data.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | // This class does not get 'AdditionalProperties = false' in the schema generation, 6 | // so it can be extended with arbitrary JSON properties to allow adding custom 7 | // data. 8 | type CustomDataType struct { 9 | // VendorId corresponds to the JSON schema field "vendorId". 10 | VendorId string `json:"vendorId" yaml:"vendorId" mapstructure:"vendorId"` 11 | } 12 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/delete_certificate_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type DeleteCertificateRequestJson struct { 6 | // CertificateHashData corresponds to the JSON schema field "certificateHashData". 7 | CertificateHashData CertificateHashDataType `json:"certificateHashData" yaml:"certificateHashData" mapstructure:"certificateHashData"` 8 | 9 | // CustomData corresponds to the JSON schema field "customData". 10 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 11 | } 12 | 13 | func (*DeleteCertificateRequestJson) IsRequest() {} 14 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package ocpp201 contains types that represent each of the different OCPP 2.0.1 4 | // protocol messages. The files have been generated using gojsonschema with all 5 | // references to the CustomDataType removed (as this type is shared) and with all 6 | // explicit Unmarshaller functions removed as validation is handled separately. 7 | package ocpp201 8 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/firmware_status_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type FirmwareStatusNotificationResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*FirmwareStatusNotificationResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_15118_ev_certificate_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type CertificateActionEnumType string 6 | 7 | const CertificateActionEnumTypeInstall CertificateActionEnumType = "Install" 8 | const CertificateActionEnumTypeUpdate CertificateActionEnumType = "Update" 9 | 10 | type Get15118EVCertificateRequestJson struct { 11 | // Action corresponds to the JSON schema field "action". 12 | Action CertificateActionEnumType `json:"action" yaml:"action" mapstructure:"action"` 13 | 14 | // CustomData corresponds to the JSON schema field "customData". 15 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 16 | 17 | ExiRequest string `json:"exiRequest" yaml:"exiRequest" mapstructure:"exiRequest"` 18 | 19 | Iso15118SchemaVersion string `json:"iso15118SchemaVersion" yaml:"iso15118SchemaVersion" mapstructure:"iso15118SchemaVersion"` 20 | } 21 | 22 | func (*Get15118EVCertificateRequestJson) IsRequest() {} 23 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_base_report_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type ReportBaseEnumType string 6 | 7 | const ReportBaseEnumTypeConfigurationInventory ReportBaseEnumType = "ConfigurationInventory" 8 | const ReportBaseEnumTypeFullInventory ReportBaseEnumType = "FullInventory" 9 | const ReportBaseEnumTypeSummaryInventory ReportBaseEnumType = "SummaryInventory" 10 | 11 | type GetBaseReportRequestJson struct { 12 | // CustomData corresponds to the JSON schema field "customData". 13 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 14 | 15 | // ReportBase corresponds to the JSON schema field "reportBase". 16 | ReportBase ReportBaseEnumType `json:"reportBase" yaml:"reportBase" mapstructure:"reportBase"` 17 | 18 | // The Id of the request. 19 | // 20 | RequestId int `json:"requestId" yaml:"requestId" mapstructure:"requestId"` 21 | } 22 | 23 | func (*GetBaseReportRequestJson) IsRequest() {} 24 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_certificate_status_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetCertificateStatusRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // OcspRequestData corresponds to the JSON schema field "ocspRequestData". 10 | OcspRequestData OCSPRequestDataType `json:"ocspRequestData" yaml:"ocspRequestData" mapstructure:"ocspRequestData"` 11 | } 12 | 13 | func (*GetCertificateStatusRequestJson) IsRequest() {} 14 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_installed_certificate_ids_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetInstalledCertificateIdsRequestJson struct { 6 | // Indicates the type of certificates requested. When omitted, all certificate 7 | // types are requested. 8 | // 9 | CertificateType []GetCertificateIdUseEnumType `json:"certificateType,omitempty" yaml:"certificateType,omitempty" mapstructure:"certificateType,omitempty"` 10 | 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | } 14 | 15 | func (*GetInstalledCertificateIdsRequestJson) IsRequest() {} 16 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_local_list_version_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetLocalListVersionRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*GetLocalListVersionRequestJson) IsRequest() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_local_list_version_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetLocalListVersionResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // This contains the current version number of the local authorization list in the 10 | // Charging Station. 11 | // 12 | VersionNumber int `json:"versionNumber" yaml:"versionNumber" mapstructure:"versionNumber"` 13 | } 14 | 15 | func (*GetLocalListVersionResponseJson) IsResponse() {} 16 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_report_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetReportResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // Status corresponds to the JSON schema field "status". 10 | Status GenericDeviceModelStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 11 | 12 | // StatusInfo corresponds to the JSON schema field "statusInfo". 13 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 14 | } 15 | 16 | func (*GetReportResponseJson) IsResponse() {} 17 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_transaction_status_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetTransactionStatusRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // The Id of the transaction for which the status is requested. 10 | // 11 | TransactionId *string `json:"transactionId,omitempty" yaml:"transactionId,omitempty" mapstructure:"transactionId,omitempty"` 12 | } 13 | 14 | func (*GetTransactionStatusRequestJson) IsRequest() {} 15 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/get_transaction_status_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GetTransactionStatusResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // Whether there are still message to be delivered. 10 | // 11 | MessagesInQueue bool `json:"messagesInQueue" yaml:"messagesInQueue" mapstructure:"messagesInQueue"` 12 | 13 | // Whether the transaction is still ongoing. 14 | // 15 | OngoingIndicator *bool `json:"ongoingIndicator,omitempty" yaml:"ongoingIndicator,omitempty" mapstructure:"ongoingIndicator,omitempty"` 16 | } 17 | 18 | func (*GetTransactionStatusResponseJson) IsResponse() {} 19 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/heartbeat_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type HeartbeatRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*HeartbeatRequestJson) IsRequest() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/heartbeat_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type HeartbeatResponseJson struct { 6 | // Contains the current time of the CSMS. 7 | // 8 | CurrentTime string `json:"currentTime" yaml:"currentTime" mapstructure:"currentTime"` 9 | 10 | // CustomData corresponds to the JSON schema field "customData". 11 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 12 | } 13 | 14 | func (*HeartbeatResponseJson) IsResponse() {} 15 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/id_token_enum_type.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type IdTokenEnumType string 6 | 7 | const IdTokenEnumTypeCentral IdTokenEnumType = "Central" 8 | const IdTokenEnumTypeEMAID IdTokenEnumType = "eMAID" 9 | const IdTokenEnumTypeISO14443 IdTokenEnumType = "ISO14443" 10 | const IdTokenEnumTypeISO15693 IdTokenEnumType = "ISO15693" 11 | const IdTokenEnumTypeKeyCode IdTokenEnumType = "KeyCode" 12 | const IdTokenEnumTypeLocal IdTokenEnumType = "Local" 13 | const IdTokenEnumTypeMacAddress IdTokenEnumType = "MacAddress" 14 | const IdTokenEnumTypeNoAuthorization IdTokenEnumType = "NoAuthorization" 15 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/id_token_type.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | // Contains a case insensitive identifier to use for the authorization and the type 6 | // of authorization to support multiple forms of identifiers. 7 | type IdTokenType struct { 8 | // AdditionalInfo corresponds to the JSON schema field "additionalInfo". 9 | AdditionalInfo *[]AdditionalInfoType `json:"additionalInfo,omitempty" yaml:"additionalInfo,omitempty" mapstructure:"additionalInfo,omitempty"` 10 | 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // IdToken is case insensitive. Might hold the hidden id of an RFID tag, but can 15 | // for example also contain a UUID. 16 | // 17 | IdToken string `json:"idToken" yaml:"idToken" mapstructure:"idToken"` 18 | 19 | // Type corresponds to the JSON schema field "type". 20 | Type IdTokenEnumType `json:"type" yaml:"type" mapstructure:"type"` 21 | } 22 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/log_status_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type LogStatusNotificationResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*LogStatusNotificationResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/message_format_enum_type.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type MessageFormatEnumType string 6 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/meter_values_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | // Request_ Body 6 | // urn:x-enexis:ecdm:uid:2:234744 7 | type MeterValuesRequestJson struct { 8 | // CustomData corresponds to the JSON schema field "customData". 9 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 10 | 11 | // Request_ Body. EVSEID. Numeric_ Identifier 12 | // urn:x-enexis:ecdm:uid:1:571101 13 | // This contains a number (>0) designating an EVSE of the Charging Station. ‘0’ 14 | // (zero) is used to designate the main power meter. 15 | // 16 | EvseId int `json:"evseId" yaml:"evseId" mapstructure:"evseId"` 17 | 18 | // MeterValue corresponds to the JSON schema field "meterValue". 19 | MeterValue []MeterValueType `json:"meterValue" yaml:"meterValue" mapstructure:"meterValue"` 20 | } 21 | 22 | func (*MeterValuesRequestJson) IsRequest() {} 23 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/meter_values_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type MeterValuesResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*MeterValuesResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/notify_report_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type NotifyReportResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*NotifyReportResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/request_stop_transaction_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type RequestStopTransactionRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // The identifier of the transaction which the Charging Station is requested to 10 | // stop. 11 | // 12 | TransactionId string `json:"transactionId" yaml:"transactionId" mapstructure:"transactionId"` 13 | } 14 | 15 | func (*RequestStopTransactionRequestJson) IsRequest() {} 16 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/request_stop_transaction_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type RequestStartStopStatusEnumType string 6 | 7 | const RequestStartStopStatusEnumTypeAccepted RequestStartStopStatusEnumType = "Accepted" 8 | const RequestStartStopStatusEnumTypeRejected RequestStartStopStatusEnumType = "Rejected" 9 | 10 | type RequestStopTransactionResponseJson struct { 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // Status corresponds to the JSON schema field "status". 15 | Status RequestStartStopStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 16 | 17 | // StatusInfo corresponds to the JSON schema field "statusInfo". 18 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 19 | } 20 | 21 | func (*RequestStopTransactionResponseJson) IsResponse() {} 22 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/reset_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type ResetEnumType string 6 | 7 | const ResetEnumTypeImmediate ResetEnumType = "Immediate" 8 | const ResetEnumTypeOnIdle ResetEnumType = "OnIdle" 9 | 10 | type ResetRequestJson struct { 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // This contains the ID of a specific EVSE that needs to be reset, instead of the 15 | // entire Charging Station. 16 | // 17 | EvseId *int `json:"evseId,omitempty" yaml:"evseId,omitempty" mapstructure:"evseId,omitempty"` 18 | 19 | // Type corresponds to the JSON schema field "type". 20 | Type ResetEnumType `json:"type" yaml:"type" mapstructure:"type"` 21 | } 22 | 23 | func (*ResetRequestJson) IsRequest() {} 24 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/reset_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type ResetStatusEnumType string 6 | 7 | const ResetStatusEnumTypeAccepted ResetStatusEnumType = "Accepted" 8 | const ResetStatusEnumTypeRejected ResetStatusEnumType = "Rejected" 9 | const ResetStatusEnumTypeScheduled ResetStatusEnumType = "Scheduled" 10 | 11 | type ResetResponseJson struct { 12 | // CustomData corresponds to the JSON schema field "customData". 13 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 14 | 15 | // Status corresponds to the JSON schema field "status". 16 | Status ResetStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 17 | 18 | // StatusInfo corresponds to the JSON schema field "statusInfo". 19 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 20 | } 21 | 22 | func (*ResetResponseJson) IsResponse() {} 23 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/security_event_notification_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type SecurityEventNotificationRequestJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | 9 | // Additional information about the occurred security event. 10 | // 11 | TechInfo *string `json:"techInfo,omitempty" yaml:"techInfo,omitempty" mapstructure:"techInfo,omitempty"` 12 | 13 | // Date and time at which the event occurred. 14 | // 15 | Timestamp string `json:"timestamp" yaml:"timestamp" mapstructure:"timestamp"` 16 | 17 | // Type of the security event. This value should be taken from the Security events 18 | // list. 19 | // 20 | Type string `json:"type" yaml:"type" mapstructure:"type"` 21 | } 22 | 23 | func (*SecurityEventNotificationRequestJson) IsRequest() {} 24 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/security_event_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type SecurityEventNotificationResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*SecurityEventNotificationResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/send_local_list_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type SendLocalListStatusEnumType string 6 | 7 | const SendLocalListStatusEnumTypeAccepted SendLocalListStatusEnumType = "Accepted" 8 | const SendLocalListStatusEnumTypeFailed SendLocalListStatusEnumType = "Failed" 9 | const SendLocalListStatusEnumTypeVersionMismatch SendLocalListStatusEnumType = "VersionMismatch" 10 | 11 | type SendLocalListResponseJson struct { 12 | // CustomData corresponds to the JSON schema field "customData". 13 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 14 | 15 | // Status corresponds to the JSON schema field "status". 16 | Status SendLocalListStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 17 | 18 | // StatusInfo corresponds to the JSON schema field "statusInfo". 19 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 20 | } 21 | 22 | func (*SendLocalListResponseJson) IsResponse() {} 23 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/sign_certificate_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type GenericStatusEnumType string 6 | 7 | const GenericStatusEnumTypeAccepted GenericStatusEnumType = "Accepted" 8 | const GenericStatusEnumTypeRejected GenericStatusEnumType = "Rejected" 9 | 10 | type SignCertificateResponseJson struct { 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // Status corresponds to the JSON schema field "status". 15 | Status GenericStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` 16 | 17 | // StatusInfo corresponds to the JSON schema field "statusInfo". 18 | StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"` 19 | } 20 | 21 | func (*SignCertificateResponseJson) IsResponse() {} 22 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/status_info_type.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | // Element providing more information about the status. 6 | type StatusInfoType struct { 7 | // Additional text to provide detailed information. 8 | // 9 | AdditionalInfo *string `json:"additionalInfo,omitempty" yaml:"additionalInfo,omitempty" mapstructure:"additionalInfo,omitempty"` 10 | 11 | // CustomData corresponds to the JSON schema field "customData". 12 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 13 | 14 | // A predefined code for the reason why the status is returned in this response. 15 | // The string is case-insensitive. 16 | // 17 | ReasonCode string `json:"reasonCode" yaml:"reasonCode" mapstructure:"reasonCode"` 18 | } 19 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/status_notification_response.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type StatusNotificationResponseJson struct { 6 | // CustomData corresponds to the JSON schema field "customData". 7 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 8 | } 9 | 10 | func (*StatusNotificationResponseJson) IsResponse() {} 11 | -------------------------------------------------------------------------------- /manager/ocpp/ocpp201/unlock_connector_request.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp201 4 | 5 | type UnlockConnectorRequestJson struct { 6 | // This contains the identifier of the connector that needs to be unlocked. 7 | // 8 | ConnectorId int `json:"connectorId" yaml:"connectorId" mapstructure:"connectorId"` 9 | 10 | // CustomData corresponds to the JSON schema field "customData". 11 | CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"` 12 | 13 | // This contains the identifier of the EVSE for which a connector needs to be 14 | // unlocked. 15 | // 16 | EvseId int `json:"evseId" yaml:"evseId" mapstructure:"evseId"` 17 | } 18 | 19 | func (*UnlockConnectorRequestJson) IsRequest() {} 20 | -------------------------------------------------------------------------------- /manager/ocpp/types.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package ocpp 4 | 5 | type Request interface { 6 | IsRequest() 7 | } 8 | 9 | type Response interface { 10 | IsResponse() 11 | } 12 | -------------------------------------------------------------------------------- /manager/schemas/has2be/CertificateSignedResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:CertificateSignedResponse", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "definitions": { 6 | "CertificateSignedStatusEnumType": { 7 | "description": "Returns whether certificate signing has been accepted, otherwise rejected.\r\n", 8 | "javaType": "CertificateSignedStatusEnum", 9 | "type": "string", 10 | "additionalProperties": false, 11 | "enum": [ 12 | "Accepted", 13 | "Rejected" 14 | ] 15 | } 16 | }, 17 | "type": "object", 18 | "additionalProperties": false, 19 | "properties": { 20 | "status": { 21 | "$ref": "#/definitions/CertificateSignedStatusEnumType" 22 | } 23 | }, 24 | "required": [ 25 | "status" 26 | ] 27 | } -------------------------------------------------------------------------------- /manager/schemas/has2be/DeleteCertificateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:DeleteCertificateResponse", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "definitions": { 6 | "DeleteCertificateStatusEnumType": { 7 | "description": "Charging Station indicates if it can process the request.\r\n", 8 | "javaType": "DeleteCertificateStatusEnum", 9 | "type": "string", 10 | "additionalProperties": false, 11 | "enum": [ 12 | "Accepted", 13 | "Failed", 14 | "NotFound" 15 | ] 16 | } 17 | }, 18 | "type": "object", 19 | "additionalProperties": false, 20 | "properties": { 21 | "status": { 22 | "$ref": "#/definitions/DeleteCertificateStatusEnumType" 23 | } 24 | }, 25 | "required": [ 26 | "status" 27 | ] 28 | } -------------------------------------------------------------------------------- /manager/schemas/has2be/Get15118EVCertificateRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:Get15118EVCertificateRequest", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "type": "object", 6 | "additionalProperties": false, 7 | "properties": { 8 | "15118SchemaVersion": { 9 | "description": "Schema version currently used for the 15118 session between EV and Charging Station. Needed for parsing of the EXI stream by the CSMS.\r\n\r\n", 10 | "type": "string", 11 | "maxLength": 50 12 | }, 13 | "exiRequest": { 14 | "description": "Raw CertificateInstallationReq request from EV, Base64 encoded.\r\n", 15 | "type": "string", 16 | "maxLength": 5500 17 | } 18 | }, 19 | "required": [ 20 | "iso15118SchemaVersion", 21 | "exiRequest" 22 | ] 23 | } -------------------------------------------------------------------------------- /manager/schemas/has2be/InstallCertificateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:InstallCertificateResponse", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "definitions": { 6 | "InstallCertificateStatusEnumType": { 7 | "description": "Charging Station indicates if installation was successful.\r\n", 8 | "javaType": "InstallCertificateStatusEnum", 9 | "type": "string", 10 | "additionalProperties": false, 11 | "enum": [ 12 | "Accepted", 13 | "Rejected", 14 | "Failed" 15 | ] 16 | } 17 | }, 18 | "type": "object", 19 | "additionalProperties": false, 20 | "properties": { 21 | "status": { 22 | "$ref": "#/definitions/InstallCertificateStatusEnumType" 23 | } 24 | }, 25 | "required": [ 26 | "status" 27 | ] 28 | } -------------------------------------------------------------------------------- /manager/schemas/has2be/SignCertificateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:SignCertificateResponse", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "definitions": { 6 | "GenericStatusEnumType": { 7 | "description": "Specifies whether the CSMS can process the request.\r\n", 8 | "javaType": "GenericStatusEnum", 9 | "type": "string", 10 | "additionalProperties": false, 11 | "enum": [ 12 | "Accepted", 13 | "Rejected" 14 | ] 15 | } 16 | }, 17 | "type": "object", 18 | "additionalProperties": false, 19 | "properties": { 20 | "status": { 21 | "$ref": "#/definitions/GenericStatusEnumType" 22 | } 23 | }, 24 | "required": [ 25 | "status" 26 | ] 27 | } -------------------------------------------------------------------------------- /manager/schemas/has2be/TriggerMessageRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:TriggerMessageRequest", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "definitions": { 6 | "MessageTriggerEnumType": { 7 | "description": "Type of message to be triggered.\r\n", 8 | "javaType": "MessageTriggerEnum", 9 | "type": "string", 10 | "additionalProperties": false, 11 | "enum": [ 12 | "SignChargingStationCertificate", 13 | "SignV2GCertificate" 14 | ] 15 | } 16 | }, 17 | "type": "object", 18 | "additionalProperties": false, 19 | "properties": { 20 | "requestedMessage": { 21 | "$ref": "#/definitions/MessageTriggerEnumType" 22 | } 23 | }, 24 | "required": [ 25 | "requestedMessage" 26 | ] 27 | } -------------------------------------------------------------------------------- /manager/schemas/has2be/TriggerMessageResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:Has2Be:1.3:2019:10:TriggerMessageResponse", 4 | "comment": "https://has-to-be.com/wp-content/uploads/2019/11/OCPP-1.6_v1.3-ISO-15118-extension-1.pdf", 5 | "definitions": { 6 | "TriggerMessageStatusEnumType": { 7 | "description": "Indicates whether the Charging Station will send the requested notification or not.\r\n", 8 | "javaType": "TriggerMessageStatusEnum", 9 | "type": "string", 10 | "additionalProperties": false, 11 | "enum": [ 12 | "Accepted", 13 | "Rejected", 14 | "NotImplemented" 15 | ] 16 | } 17 | }, 18 | "type": "object", 19 | "additionalProperties": false, 20 | "properties": { 21 | "status": { 22 | "$ref": "#/definitions/TriggerMessageStatusEnumType" 23 | } 24 | }, 25 | "required": [ 26 | "status" 27 | ] 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/Authorize.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:AuthorizeRequest", 4 | "title": "AuthorizeRequest", 5 | "type": "object", 6 | "properties": { 7 | "idTag": { 8 | "type": "string", 9 | "maxLength": 20 10 | } 11 | }, 12 | "additionalProperties": false, 13 | "required": [ 14 | "idTag" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/BootNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:BootNotificationResponse", 4 | "title": "BootNotificationResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Pending", 13 | "Rejected" 14 | ] 15 | }, 16 | "currentTime": { 17 | "type": "string", 18 | "format": "date-time" 19 | }, 20 | "interval": { 21 | "type": "integer" 22 | } 23 | }, 24 | "additionalProperties": false, 25 | "required": [ 26 | "status", 27 | "currentTime", 28 | "interval" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/CancelReservation.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:CancelReservationRequest", 4 | "title": "CancelReservationRequest", 5 | "type": "object", 6 | "properties": { 7 | "reservationId": { 8 | "type": "integer" 9 | } 10 | }, 11 | "additionalProperties": false, 12 | "required": [ 13 | "reservationId" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/CancelReservationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:CancelReservationResponse", 4 | "title": "CancelReservationResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "status" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/CertificateSigned.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:CertificateSigned.req", 4 | "type": "object", 5 | "properties": { 6 | "certificateChain": { 7 | "type": "string", 8 | "maxLength": 10000 9 | } 10 | }, 11 | "additionalProperties": false, 12 | "required": [ 13 | "certificateChain" 14 | ] 15 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/CertificateSignedResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:CertificateSigned.conf", 4 | "definitions": { 5 | "CertificateSignedStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Rejected" 11 | ] 12 | } 13 | }, 14 | "type": "object", 15 | "additionalProperties": false, 16 | "properties": { 17 | "status": { 18 | "$ref": "#/definitions/CertificateSignedStatusEnumType" 19 | } 20 | }, 21 | "required": [ 22 | "status" 23 | ] 24 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ChangeAvailability.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ChangeAvailabilityRequest", 4 | "title": "ChangeAvailabilityRequest", 5 | "type": "object", 6 | "properties": { 7 | "connectorId": { 8 | "type": "integer" 9 | }, 10 | "type": { 11 | "type": "string", 12 | "additionalProperties": false, 13 | "enum": [ 14 | "Inoperative", 15 | "Operative" 16 | ] 17 | } 18 | }, 19 | "additionalProperties": false, 20 | "required": [ 21 | "connectorId", 22 | "type" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ChangeAvailabilityResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ChangeAvailabilityResponse", 4 | "title": "ChangeAvailabilityResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected", 13 | "Scheduled" 14 | ] 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "status" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ChangeConfiguration.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ChangeConfigurationRequest", 4 | "title": "ChangeConfigurationRequest", 5 | "type": "object", 6 | "properties": { 7 | "key": { 8 | "type": "string", 9 | "maxLength": 50 10 | }, 11 | "value": { 12 | "type": "string", 13 | "maxLength": 500 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "key", 19 | "value" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ChangeConfigurationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ChangeConfigurationResponse", 4 | "title": "ChangeConfigurationResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected", 13 | "RebootRequired", 14 | "NotSupported" 15 | ] 16 | } 17 | }, 18 | "additionalProperties": false, 19 | "required": [ 20 | "status" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ClearCache.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ClearCacheRequest", 4 | "title": "ClearCacheRequest", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ClearCacheResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ClearCacheResponse", 4 | "title": "ClearCacheResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "status" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ClearChargingProfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ClearChargingProfileRequest", 4 | "title": "ClearChargingProfileRequest", 5 | "type": "object", 6 | "properties": { 7 | "id": { 8 | "type": "integer" 9 | }, 10 | "connectorId": { 11 | "type": "integer" 12 | }, 13 | "chargingProfilePurpose": { 14 | "type": "string", 15 | "additionalProperties": false, 16 | "enum": [ 17 | "ChargePointMaxProfile", 18 | "TxDefaultProfile", 19 | "TxProfile" 20 | ] 21 | }, 22 | "stackLevel": { 23 | "type": "integer" 24 | } 25 | }, 26 | "additionalProperties": false 27 | } 28 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ClearChargingProfileResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ClearChargingProfileResponse", 4 | "title": "ClearChargingProfileResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Unknown" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "status" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/DataTransfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:DataTransferRequest", 4 | "title": "DataTransferRequest", 5 | "type": "object", 6 | "properties": { 7 | "vendorId": { 8 | "type": "string", 9 | "maxLength": 255 10 | }, 11 | "messageId": { 12 | "type": "string", 13 | "maxLength": 50 14 | }, 15 | "data": { 16 | "type": "string" 17 | } 18 | }, 19 | "additionalProperties": false, 20 | "required": [ 21 | "vendorId" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/DataTransferResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:DataTransferResponse", 4 | "title": "DataTransferResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected", 13 | "UnknownMessageId", 14 | "UnknownVendorId" 15 | ] 16 | }, 17 | "data": { 18 | "type": "string" 19 | } 20 | }, 21 | "additionalProperties": false, 22 | "required": [ 23 | "status" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/DeleteCertificateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:DeleteCertificate.conf", 4 | "definitions": { 5 | "DeleteCertificateStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Failed", 11 | "NotFound" 12 | ] 13 | } 14 | }, 15 | "type": "object", 16 | "additionalProperties": false, 17 | "properties": { 18 | "status": { 19 | "$ref": "#/definitions/DeleteCertificateStatusEnumType" 20 | } 21 | }, 22 | "required": [ 23 | "status" 24 | ] 25 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/DiagnosticsStatusNotification.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:DiagnosticsStatusNotificationRequest", 4 | "title": "DiagnosticsStatusNotificationRequest", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Idle", 12 | "Uploaded", 13 | "UploadFailed", 14 | "Uploading" 15 | ] 16 | } 17 | }, 18 | "additionalProperties": false, 19 | "required": [ 20 | "status" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/DiagnosticsStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:DiagnosticsStatusNotificationResponse", 4 | "title": "DiagnosticsStatusNotificationResponse", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ExtendedTriggerMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:ExtendedTriggerMessage.req", 4 | "definitions": { 5 | "MessageTriggerEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "BootNotification", 10 | "LogStatusNotification", 11 | "FirmwareStatusNotification", 12 | "Heartbeat", 13 | "MeterValues", 14 | "SignChargePointCertificate", 15 | "StatusNotification" 16 | ] 17 | } 18 | }, 19 | "type": "object", 20 | "additionalProperties": false, 21 | "properties": { 22 | "requestedMessage": { 23 | "$ref": "#/definitions/MessageTriggerEnumType" 24 | }, 25 | "connectorId": { 26 | "type": "integer" 27 | } 28 | }, 29 | "required": [ 30 | "requestedMessage" 31 | ] 32 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ExtendedTriggerMessageResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:ExtendedTriggerMessage.conf", 4 | "definitions": { 5 | "TriggerMessageStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Rejected", 11 | "NotImplemented" 12 | ] 13 | } 14 | }, 15 | "type": "object", 16 | "additionalProperties": false, 17 | "properties": { 18 | "status": { 19 | "$ref": "#/definitions/TriggerMessageStatusEnumType" 20 | } 21 | }, 22 | "required": [ 23 | "status" 24 | ] 25 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/FirmwareStatusNotification.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:FirmwareStatusNotificationRequest", 4 | "title": "FirmwareStatusNotificationRequest", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Downloaded", 12 | "DownloadFailed", 13 | "Downloading", 14 | "Idle", 15 | "InstallationFailed", 16 | "Installing", 17 | "Installed" 18 | ] 19 | } 20 | }, 21 | "additionalProperties": false, 22 | "required": [ 23 | "status" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/FirmwareStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:FirmwareStatusNotificationResponse", 4 | "title": "FirmwareStatusNotificationResponse", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetCompositeSchedule.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:GetCompositeScheduleRequest", 4 | "title": "GetCompositeScheduleRequest", 5 | "type": "object", 6 | "properties": { 7 | "connectorId": { 8 | "type": "integer" 9 | }, 10 | "duration": { 11 | "type": "integer" 12 | }, 13 | "chargingRateUnit": { 14 | "type": "string", 15 | "additionalProperties": false, 16 | "enum": [ 17 | "A", 18 | "W" 19 | ] 20 | } 21 | }, 22 | "additionalProperties": false, 23 | "required": [ 24 | "connectorId", 25 | "duration" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetConfiguration.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:GetConfigurationRequest", 4 | "title": "GetConfigurationRequest", 5 | "type": "object", 6 | "properties": { 7 | "key": { 8 | "type": "array", 9 | "items": { 10 | "type": "string", 11 | "maxLength": 50 12 | } 13 | } 14 | }, 15 | "additionalProperties": false 16 | } 17 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetDiagnostics.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:GetDiagnosticsRequest", 4 | "title": "GetDiagnosticsRequest", 5 | "type": "object", 6 | "properties": { 7 | "location": { 8 | "type": "string", 9 | "format": "uri" 10 | }, 11 | "retries": { 12 | "type": "integer" 13 | }, 14 | "retryInterval": { 15 | "type": "integer" 16 | }, 17 | "startTime": { 18 | "type": "string", 19 | "format": "date-time" 20 | }, 21 | "stopTime": { 22 | "type": "string", 23 | "format": "date-time" 24 | } 25 | }, 26 | "additionalProperties": false, 27 | "required": [ 28 | "location" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetDiagnosticsResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:GetDiagnosticsResponse", 4 | "title": "GetDiagnosticsResponse", 5 | "type": "object", 6 | "properties": { 7 | "fileName": { 8 | "type": "string", 9 | "maxLength": 255 10 | } 11 | }, 12 | "additionalProperties": false 13 | } 14 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetInstalledCertificateIds.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:GetInstalledCertificateIds.req", 4 | "definitions": { 5 | "CertificateUseEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "CentralSystemRootCertificate", 10 | "ManufacturerRootCertificate" 11 | ] 12 | } 13 | }, 14 | "type": "object", 15 | "additionalProperties": false, 16 | "properties": { 17 | "certificateType": { 18 | "$ref": "#/definitions/CertificateUseEnumType" 19 | } 20 | }, 21 | "required": [ 22 | "certificateType" 23 | ] 24 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetLocalListVersion.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:GetLocalListVersionRequest", 4 | "title": "GetLocalListVersionRequest", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetLocalListVersionResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:GetLocalListVersionResponse", 4 | "title": "GetLocalListVersionResponse", 5 | "type": "object", 6 | "properties": { 7 | "listVersion": { 8 | "type": "integer" 9 | } 10 | }, 11 | "additionalProperties": false, 12 | "required": [ 13 | "listVersion" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/GetLogResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:GetLog.conf", 4 | "definitions": { 5 | "LogStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Rejected", 11 | "AcceptedCanceled" 12 | ] 13 | } 14 | }, 15 | "type": "object", 16 | "additionalProperties": false, 17 | "properties": { 18 | "status": { 19 | "$ref": "#/definitions/LogStatusEnumType" 20 | }, 21 | "filename": { 22 | "type": "string", 23 | "maxLength": 255 24 | } 25 | }, 26 | "required": [ 27 | "status" 28 | ] 29 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/Heartbeat.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:HeartbeatRequest", 4 | "title": "HeartbeatRequest", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/HeartbeatResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:HeartbeatResponse", 4 | "title": "HeartbeatResponse", 5 | "type": "object", 6 | "properties": { 7 | "currentTime": { 8 | "type": "string", 9 | "format": "date-time" 10 | } 11 | }, 12 | "additionalProperties": false, 13 | "required": [ 14 | "currentTime" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/InstallCertificate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:InstallCertificate.req", 4 | "definitions": { 5 | "CertificateUseEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "CentralSystemRootCertificate", 10 | "ManufacturerRootCertificate" 11 | ] 12 | } 13 | }, 14 | "type": "object", 15 | "additionalProperties": false, 16 | "properties": { 17 | "certificateType": { 18 | "$ref": "#/definitions/CertificateUseEnumType" 19 | }, 20 | "certificate": { 21 | "type": "string", 22 | "maxLength": 5500 23 | } 24 | }, 25 | "required": [ 26 | "certificateType", 27 | "certificate" 28 | ] 29 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/InstallCertificateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:InstallCertificate.conf", 4 | "definitions": { 5 | "InstallCertificateStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Failed", 11 | "Rejected" 12 | ] 13 | } 14 | }, 15 | "type": "object", 16 | "additionalProperties": false, 17 | "properties": { 18 | "status": { 19 | "$ref": "#/definitions/InstallCertificateStatusEnumType" 20 | } 21 | }, 22 | "required": [ 23 | "status" 24 | ] 25 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/LogStatusNotification.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:LogStatusNotification.req", 4 | "definitions": { 5 | "UploadLogStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "BadMessage", 10 | "Idle", 11 | "NotSupportedOperation", 12 | "PermissionDenied", 13 | "Uploaded", 14 | "UploadFailure", 15 | "Uploading" 16 | ] 17 | } 18 | }, 19 | "type": "object", 20 | "additionalProperties": false, 21 | "properties": { 22 | "status": { 23 | "$ref": "#/definitions/UploadLogStatusEnumType" 24 | }, 25 | "requestId": { 26 | "type": "integer" 27 | } 28 | }, 29 | "required": [ 30 | "status" 31 | ] 32 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/LogStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:LogStatusNotification.conf", 4 | "type": "object", 5 | "additionalProperties": false 6 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/MeterValuesResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:MeterValuesResponse", 4 | "title": "MeterValuesResponse", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/RemoteStartTransactionResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:RemoteStartTransactionResponse", 4 | "title": "RemoteStartTransactionResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "status" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/RemoteStopTransaction.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:RemoteStopTransactionRequest", 4 | "title": "RemoteStopTransactionRequest", 5 | "type": "object", 6 | "properties": { 7 | "transactionId": { 8 | "type": "integer" 9 | } 10 | }, 11 | "additionalProperties": false, 12 | "required": [ 13 | "transactionId" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/RemoteStopTransactionResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:RemoteStopTransactionResponse", 4 | "title": "RemoteStopTransactionResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "status" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ReserveNow.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ReserveNowRequest", 4 | "title": "ReserveNowRequest", 5 | "type": "object", 6 | "properties": { 7 | "connectorId": { 8 | "type": "integer" 9 | }, 10 | "expiryDate": { 11 | "type": "string", 12 | "format": "date-time" 13 | }, 14 | "idTag": { 15 | "type": "string", 16 | "maxLength": 20 17 | }, 18 | "parentIdTag": { 19 | "type": "string", 20 | "maxLength": 20 21 | }, 22 | "reservationId": { 23 | "type": "integer" 24 | } 25 | }, 26 | "additionalProperties": false, 27 | "required": [ 28 | "connectorId", 29 | "expiryDate", 30 | "idTag", 31 | "reservationId" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ReserveNowResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ReserveNowResponse", 4 | "title": "ReserveNowResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Faulted", 13 | "Occupied", 14 | "Rejected", 15 | "Unavailable" 16 | ] 17 | } 18 | }, 19 | "additionalProperties": false, 20 | "required": [ 21 | "status" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/Reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ResetRequest", 4 | "title": "ResetRequest", 5 | "type": "object", 6 | "properties": { 7 | "type": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Hard", 12 | "Soft" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "type" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/ResetResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:ResetResponse", 4 | "title": "ResetResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected" 13 | ] 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "status" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SecurityEventNotification.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SecurityEventNotification.req", 4 | "type": "object", 5 | "additionalProperties": false, 6 | "properties": { 7 | "type": { 8 | "type": "string", 9 | "maxLength": 50 10 | }, 11 | "timestamp": { 12 | "type": "string", 13 | "format": "date-time" 14 | }, 15 | "techInfo": { 16 | "type": "string", 17 | "maxLength": 255 18 | } 19 | }, 20 | "required": [ 21 | "type", 22 | "timestamp" 23 | ] 24 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SecurityEventNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SecurityEventNotification.conf", 4 | "type": "object", 5 | "additionalProperties": false 6 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SendLocalListResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:SendLocalListResponse", 4 | "title": "SendLocalListResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Failed", 13 | "NotSupported", 14 | "VersionMismatch" 15 | ] 16 | } 17 | }, 18 | "additionalProperties": false, 19 | "required": [ 20 | "status" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SetChargingProfileResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:SetChargingProfileResponse", 4 | "title": "SetChargingProfileResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected", 13 | "NotSupported" 14 | ] 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "status" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SignCertificate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SignCertificate.req", 4 | "type": "object", 5 | "additionalProperties": false, 6 | "properties": { 7 | "csr": { 8 | "type": "string", 9 | "maxLength": 5500 10 | } 11 | }, 12 | "required": [ 13 | "csr" 14 | ] 15 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SignCertificateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SignCertificate.conf", 4 | "definitions": { 5 | "GenericStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Rejected" 11 | ] 12 | } 13 | }, 14 | "type": "object", 15 | "additionalProperties": false, 16 | "properties": { 17 | "status": { 18 | "$ref": "#/definitions/GenericStatusEnumType" 19 | } 20 | }, 21 | "required": [ 22 | "status" 23 | ] 24 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SignedFirmwareStatusNotification.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SignedFirmwareStatusNotification.req", 4 | "definitions": { 5 | "FirmwareStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Downloaded", 10 | "DownloadFailed", 11 | "Downloading", 12 | "DownloadScheduled", 13 | "DownloadPaused", 14 | "Idle", 15 | "InstallationFailed", 16 | "Installing", 17 | "Installed", 18 | "InstallRebooting", 19 | "InstallScheduled", 20 | "InstallVerificationFailed", 21 | "InvalidSignature", 22 | "SignatureVerified" 23 | ] 24 | } 25 | }, 26 | "type": "object", 27 | "additionalProperties": false, 28 | "properties": { 29 | "status": { 30 | "$ref": "#/definitions/FirmwareStatusEnumType" 31 | }, 32 | "requestId": { 33 | "type": "integer" 34 | } 35 | }, 36 | "required": [ 37 | "status" 38 | ] 39 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SignedFirmwareStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SignedFirmwareStatusNotification.conf", 4 | "type": "object", 5 | "additionalProperties": false 6 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/SignedUpdateFirmwareResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:1.6:2020:3:SignedUpdateFirmware.conf", 4 | "definitions": { 5 | "UpdateFirmwareStatusEnumType": { 6 | "type": "string", 7 | "additionalProperties": false, 8 | "enum": [ 9 | "Accepted", 10 | "Rejected", 11 | "AcceptedCanceled", 12 | "InvalidCertificate", 13 | "RevokedCertificate" 14 | ] 15 | } 16 | }, 17 | "type": "object", 18 | "additionalProperties": false, 19 | "properties": { 20 | "status": { 21 | "$ref": "#/definitions/UpdateFirmwareStatusEnumType" 22 | } 23 | }, 24 | "required": [ 25 | "status" 26 | ] 27 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp16/StartTransaction.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:StartTransactionRequest", 4 | "title": "StartTransactionRequest", 5 | "type": "object", 6 | "properties": { 7 | "connectorId": { 8 | "type": "integer" 9 | }, 10 | "idTag": { 11 | "type": "string", 12 | "maxLength": 20 13 | }, 14 | "meterStart": { 15 | "type": "integer" 16 | }, 17 | "reservationId": { 18 | "type": "integer" 19 | }, 20 | "timestamp": { 21 | "type": "string", 22 | "format": "date-time" 23 | } 24 | }, 25 | "additionalProperties": false, 26 | "required": [ 27 | "connectorId", 28 | "idTag", 29 | "meterStart", 30 | "timestamp" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/StatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:StatusNotificationResponse", 4 | "title": "StatusNotificationResponse", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/TriggerMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:TriggerMessageRequest", 4 | "title": "TriggerMessageRequest", 5 | "type": "object", 6 | "properties": { 7 | "requestedMessage": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "BootNotification", 12 | "DiagnosticsStatusNotification", 13 | "FirmwareStatusNotification", 14 | "Heartbeat", 15 | "MeterValues", 16 | "StatusNotification" 17 | ] 18 | }, 19 | "connectorId": { 20 | "type": "integer" 21 | } 22 | }, 23 | "additionalProperties": false, 24 | "required": [ 25 | "requestedMessage" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/TriggerMessageResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:TriggerMessageResponse", 4 | "title": "TriggerMessageResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Accepted", 12 | "Rejected", 13 | "NotImplemented" 14 | ] 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "status" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/UnlockConnector.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:UnlockConnectorRequest", 4 | "title": "UnlockConnectorRequest", 5 | "type": "object", 6 | "properties": { 7 | "connectorId": { 8 | "type": "integer" 9 | } 10 | }, 11 | "additionalProperties": false, 12 | "required": [ 13 | "connectorId" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/UnlockConnectorResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:UnlockConnectorResponse", 4 | "title": "UnlockConnectorResponse", 5 | "type": "object", 6 | "properties": { 7 | "status": { 8 | "type": "string", 9 | "additionalProperties": false, 10 | "enum": [ 11 | "Unlocked", 12 | "UnlockFailed", 13 | "NotSupported" 14 | ] 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "status" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/UpdateFirmware.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:UpdateFirmwareRequest", 4 | "title": "UpdateFirmwareRequest", 5 | "type": "object", 6 | "properties": { 7 | "location": { 8 | "type": "string", 9 | "format": "uri" 10 | }, 11 | "retries": { 12 | "type": "integer" 13 | }, 14 | "retrieveDate": { 15 | "type": "string", 16 | "format": "date-time" 17 | }, 18 | "retryInterval": { 19 | "type": "integer" 20 | } 21 | }, 22 | "additionalProperties": false, 23 | "required": [ 24 | "location", 25 | "retrieveDate" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /manager/schemas/ocpp16/UpdateFirmwareResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "id": "urn:OCPP:1.6:2019:12:UpdateFirmwareResponse", 4 | "title": "UpdateFirmwareResponse", 5 | "type": "object", 6 | "properties": {}, 7 | "additionalProperties": false 8 | } 9 | -------------------------------------------------------------------------------- /manager/schemas/ocpp201/CancelReservationRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:CancelReservationRequest", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | }, 27 | "reservationId": { 28 | "description": "Id of the reservation to cancel.\r\n", 29 | "type": "integer" 30 | } 31 | }, 32 | "required": [ 33 | "reservationId" 34 | ] 35 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/ClearCacheRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:ClearCacheRequest", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/ClearedChargingLimitResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:ClearedChargingLimitResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/CostUpdatedResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:CostUpdatedResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/FirmwareStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:FirmwareStatusNotificationResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/GetLocalListVersionRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:GetLocalListVersionRequest", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/GetTransactionStatusRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:GetTransactionStatusRequest", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | }, 27 | "transactionId": { 28 | "description": "The Id of the transaction for which the status is requested.\r\n", 29 | "type": "string", 30 | "maxLength": 36 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/HeartbeatRequest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:HeartbeatRequest", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/LogStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:LogStatusNotificationResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/MeterValuesResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:MeterValuesResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/NotifyChargingLimitResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:NotifyChargingLimitResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/NotifyCustomerInformationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:NotifyCustomerInformationResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/NotifyDisplayMessagesResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:NotifyDisplayMessagesResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/NotifyEventResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:NotifyEventResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/NotifyMonitoringReportResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:NotifyMonitoringReportResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/NotifyReportResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:NotifyReportResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/PublishFirmwareStatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:PublishFirmwareStatusNotificationResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/ReportChargingProfilesResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:ReportChargingProfilesResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/ReservationStatusUpdateResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:ReservationStatusUpdateResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/SecurityEventNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:SecurityEventNotificationResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/ocpp201/StatusNotificationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "urn:OCPP:Cp:2:2020:3:StatusNotificationResponse", 4 | "comment": "OCPP 2.0.1 FINAL", 5 | "definitions": { 6 | "CustomDataType": { 7 | "description": "This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.", 8 | "javaType": "CustomData", 9 | "type": "object", 10 | "properties": { 11 | "vendorId": { 12 | "type": "string", 13 | "maxLength": 255 14 | } 15 | }, 16 | "required": [ 17 | "vendorId" 18 | ] 19 | } 20 | }, 21 | "type": "object", 22 | "additionalProperties": false, 23 | "properties": { 24 | "customData": { 25 | "$ref": "#/definitions/CustomDataType" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /manager/schemas/schemas.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package schemas 4 | 5 | import "embed" 6 | 7 | //go:embed */*.json 8 | var OcppSchemas embed.FS 9 | -------------------------------------------------------------------------------- /manager/schemas/validator.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package schemas 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "fmt" 9 | "github.com/santhosh-tekuri/jsonschema" 10 | "github.com/santhosh-tekuri/jsonschema/loader" 11 | "io" 12 | "io/fs" 13 | "net/url" 14 | ) 15 | 16 | type FSLoader struct { 17 | FS fs.FS 18 | } 19 | 20 | func (f FSLoader) Load(u string) (io.ReadCloser, error) { 21 | parsedUrl, err := url.Parse(u) 22 | if err != nil { 23 | return nil, err 24 | } 25 | if parsedUrl.Scheme == "fs" { 26 | return f.FS.Open(parsedUrl.Path[1:]) 27 | } 28 | return nil, nil 29 | } 30 | 31 | func Validate(data json.RawMessage, schemaFs fs.FS, schemaFile string) error { 32 | compiler := jsonschema.NewCompiler() 33 | compiler.Draft = jsonschema.Draft6 34 | loader.Register("fs", FSLoader{ 35 | FS: schemaFs, 36 | }) 37 | schema, err := compiler.Compile(fmt.Sprintf("fs:///%s", schemaFile)) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | return schema.Validate(bytes.NewReader(data)) 43 | } 44 | -------------------------------------------------------------------------------- /manager/server/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package server provides the implementation of the HTTP server 4 | // components used by the manager. 5 | package server 6 | -------------------------------------------------------------------------------- /manager/server/log.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chi/chi/v5/middleware" 6 | "golang.org/x/exp/slog" 7 | "net/http" 8 | "time" 9 | ) 10 | 11 | type logEntry struct { 12 | method string 13 | path string 14 | remoteAddr string 15 | } 16 | 17 | func (l logEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) { 18 | slog.Info(fmt.Sprintf("%s %s", l.method, l.path), slog.String("remote_addr", l.remoteAddr), slog.Int("status", status), slog.Int("bytes", bytes), slog.Duration("duration", elapsed)) 19 | } 20 | 21 | func (l logEntry) Panic(v interface{}, stack []byte) { 22 | slog.Info(fmt.Sprintf("%s %s", l.method, l.path), slog.String("remote_addr", l.remoteAddr), slog.Any("panic", v), slog.String("stack", string(stack))) 23 | } 24 | 25 | type logFormatter struct{} 26 | 27 | func (l logFormatter) NewLogEntry(r *http.Request) middleware.LogEntry { 28 | return logEntry{ 29 | method: r.Method, 30 | path: r.URL.Path, 31 | remoteAddr: r.RemoteAddr, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /manager/services/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package services defines pluggable services that are used to customize 4 | // the processing of OCPP messages by the core handlers. 5 | package services 6 | -------------------------------------------------------------------------------- /manager/services/http_token_hubject_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //go:build integration 4 | 5 | package services_test 6 | 7 | import ( 8 | "context" 9 | "github.com/lestrrat-go/jwx/jwt" 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | "github.com/thoughtworks/maeve-csms/manager/services" 13 | "net/http" 14 | "testing" 15 | ) 16 | 17 | func TestHubjectTestHttpTokenService(t *testing.T) { 18 | svc := services.NewHubjectTestHttpTokenService( 19 | "https://hubject.stoplight.io/api/v1/projects/cHJqOjk0NTg5/nodes/6bb8b3bc79c2e-authorization-token", 20 | http.DefaultClient) 21 | token, err := svc.GetToken(context.Background(), false) 22 | require.NoError(t, err) 23 | jwtToken, err := jwt.Parse([]byte(token)) 24 | require.NoError(t, err) 25 | 26 | assert.Equal(t, "https://auth.eu.plugncharge.hubject.com/", jwtToken.Issuer()) 27 | } 28 | -------------------------------------------------------------------------------- /manager/services/testdata/root_ca.pem: -------------------------------------------------------------------------------- 1 | subject=/C=DE/O=Hubject GmbH/DC=V2G/CN=V2G Root CA QA G1 2 | issuer=/C=DE/O=Hubject GmbH/DC=V2G/CN=V2G Root CA QA G1 3 | -----BEGIN CERTIFICATE----- 4 | MIICUzCCAfmgAwIBAgIQaasA0lm730LOgFKa0wzl7TAKBggqhkjOPQQDAjBVMQsw 5 | CQYDVQQGEwJERTEVMBMGA1UEChMMSHViamVjdCBHbWJIMRMwEQYKCZImiZPyLGQB 6 | GRYDVjJHMRowGAYDVQQDExFWMkcgUm9vdCBDQSBRQSBHMTAgFw0xOTA0MjYwODM3 7 | MTVaGA8yMDU5MDQyNjA4MzcxNVowVTELMAkGA1UEBhMCREUxFTATBgNVBAoTDEh1 8 | YmplY3QgR21iSDETMBEGCgmSJomT8ixkARkWA1YyRzEaMBgGA1UEAxMRVjJHIFJv 9 | b3QgQ0EgUUEgRzEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAShT8kSNcC+74TN 10 | D82On2Y2TOf8mYfxw73lKZ7t9cmEXHpMdAgsWBQ4LI+pOMhe6NOHzJbzP38kQTg4 11 | zLfw3kU0o4GoMIGlMBMGA1UdJQQMMAoGCCsGAQUFBwMJMA8GA1UdEwEB/wQFMAMB 12 | Af8wEQYDVR0OBAoECEtF/4Il/BCWMEUGA1UdIAQ+MDwwOgYMKwYBBAGCxDUBAgEA 13 | MCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3Lmh1YmplY3QuY29tL3BraS8wEwYD 14 | VR0jBAwwCoAIS0X/giX8EJYwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMCA0gA 15 | MEUCIQCq3Qx2BLYVFb7Lt5XXpSlUViYv4cIUOQE1Ce9o2Jyy1QIgZRmVzMVjHZA+ 16 | toiM000PCUrLppqbLpcRN4MP8kE0OhU= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /manager/store/cert.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package store 4 | 5 | import "context" 6 | 7 | type CertificateStore interface { 8 | SetCertificate(ctx context.Context, pemCertificate string) error 9 | LookupCertificate(ctx context.Context, certificateHash string) (string, error) 10 | DeleteCertificate(ctx context.Context, certificateHash string) error 11 | } 12 | -------------------------------------------------------------------------------- /manager/store/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package store defines the interfaces to the persistent store. 4 | package store 5 | -------------------------------------------------------------------------------- /manager/store/engine.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package store 4 | 5 | type Engine interface { 6 | ChargeStationAuthStore 7 | ChargeStationSettingsStore 8 | ChargeStationRuntimeDetailsStore 9 | ChargeStationInstallCertificatesStore 10 | ChargeStationTriggerMessageStore 11 | TokenStore 12 | TransactionStore 13 | CertificateStore 14 | OcpiStore 15 | LocationStore 16 | } 17 | -------------------------------------------------------------------------------- /manager/store/firestore/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package firestore provides an implementation of store.Engine using Google Firestore. 4 | package firestore 5 | -------------------------------------------------------------------------------- /manager/store/firestore/store.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package firestore 4 | 5 | import ( 6 | "cloud.google.com/go/firestore" 7 | "context" 8 | "fmt" 9 | "github.com/thoughtworks/maeve-csms/manager/store" 10 | "k8s.io/utils/clock" 11 | ) 12 | 13 | type Store struct { 14 | client *firestore.Client 15 | clock clock.PassiveClock 16 | } 17 | 18 | func NewStore(ctx context.Context, gcloudProject string, clock clock.PassiveClock) (store.Engine, error) { 19 | client, err := firestore.NewClient(ctx, gcloudProject) 20 | if err != nil { 21 | return nil, fmt.Errorf("create new firestore client in %s: %w", gcloudProject, err) 22 | } 23 | 24 | return &Store{ 25 | client: client, 26 | clock: clock, 27 | }, nil 28 | } 29 | -------------------------------------------------------------------------------- /manager/store/firestore/store_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | //go:build integration 4 | 5 | package firestore_test 6 | 7 | import ( 8 | "context" 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | "github.com/thoughtworks/maeve-csms/manager/store/firestore" 12 | "k8s.io/utils/clock" 13 | "testing" 14 | ) 15 | 16 | func TestNewStore(t *testing.T) { 17 | store, err := firestore.NewStore(context.Background(), "myproject", clock.RealClock{}) 18 | require.NoError(t, err) 19 | assert.NotNil(t, store) 20 | } 21 | -------------------------------------------------------------------------------- /manager/store/inmemory/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package inmemory provides an in-memory implementation of store.Engine. 4 | package inmemory 5 | -------------------------------------------------------------------------------- /manager/store/location.go: -------------------------------------------------------------------------------- 1 | package store 2 | 3 | import "golang.org/x/net/context" 4 | 5 | type GeoLocation struct { 6 | Latitude string 7 | Longitude string 8 | } 9 | 10 | type Connector struct { 11 | Format string 12 | Id string 13 | MaxAmperage int32 14 | MaxVoltage int32 15 | PowerType string 16 | Standard string 17 | LastUpdated string 18 | } 19 | 20 | type Evse struct { 21 | Connectors []Connector 22 | EvseId *string 23 | Status string 24 | Uid string 25 | LastUpdated string 26 | } 27 | 28 | type Location struct { 29 | Address string 30 | City string 31 | Coordinates GeoLocation 32 | Country string 33 | Evses *[]Evse 34 | Id string 35 | LastUpdated string 36 | Name string 37 | ParkingType string 38 | PostalCode string 39 | } 40 | 41 | type LocationStore interface { 42 | SetLocation(ctx context.Context, location *Location) error 43 | LookupLocation(ctx context.Context, locationId string) (*Location, error) 44 | ListLocations(context context.Context, offset int, limit int) ([]*Location, error) 45 | } 46 | -------------------------------------------------------------------------------- /manager/store/token.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package store 4 | 5 | import "context" 6 | 7 | const ( 8 | CacheModeAlways = "ALWAYS" 9 | CacheModeAllowed = "ALLOWED" 10 | CacheModeAllowedOffline = "ALLOWED_OFFLINE" 11 | CacheModeNever = "NEVER" 12 | ) 13 | 14 | type Token struct { 15 | CountryCode string 16 | PartyId string 17 | Type string 18 | Uid string 19 | ContractId string 20 | VisualNumber *string 21 | Issuer string 22 | GroupId *string 23 | Valid bool 24 | LanguageCode *string 25 | CacheMode string 26 | LastUpdated string 27 | } 28 | 29 | type TokenStore interface { 30 | SetToken(ctx context.Context, token *Token) error 31 | LookupToken(ctx context.Context, tokenUid string) (*Token, error) 32 | ListTokens(context context.Context, offset int, limit int) ([]*Token, error) 33 | } 34 | -------------------------------------------------------------------------------- /manager/sync/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package sync provides support for synchronizing configuration 4 | // changes to the charge stations. It is expected that this package 5 | // will change significantly. 6 | package sync 7 | -------------------------------------------------------------------------------- /manager/templates/templates.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package templates 4 | 5 | import _ "embed" 6 | 7 | //go:embed transactions.html 8 | var Transactions string 9 | -------------------------------------------------------------------------------- /manager/transport/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package transport provides the interfaces that are used 4 | // to communicate between the manager and the gateway and 5 | // subsequently to the charge station. 6 | package transport 7 | -------------------------------------------------------------------------------- /manager/transport/mqtt/doc.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | // Package mqtt provides support for handling messages from the 4 | // gateway and emitting messages to the gateway using MQTT 5 | package mqtt 6 | -------------------------------------------------------------------------------- /manager/transport/receiver.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | package transport 4 | 5 | // Receiver is the interface implemented in order to receive messages 6 | // from the gateway (and thus from the charge station). The Receiver 7 | // must establish a connection to the gateway and then use a Router 8 | // to process any messages that are received. 9 | type Receiver interface { 10 | Connect(errCh chan error) 11 | } 12 | -------------------------------------------------------------------------------- /prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | 4 | scrape_configs: 5 | - job_name: 'prometheus' 6 | static_configs: 7 | - targets: [ 'host.docker.internal:9090' ] 8 | - job_name: 'endpoints' 9 | static_configs: 10 | - targets: ['gateway:9312', 'manager:9410'] 11 | 12 | -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | # Scripts 2 | 3 | ## Get CA Certificates 4 | 5 | The [get-ca-cert.sh](get-ca-cert.sh) script retrieves the root V2G CA certificate and the CPO intermediate CA 6 | certificates and writes them to the [config/certificates](../config/certificates) directory. 7 | 8 | The files will be called: 9 | * `cpo_sub_ca1.pem` 10 | * `cpo_sub_ca2.pem` 11 | * `root-V2G-cert.pem` 12 | 13 | Requires: 14 | * curl 15 | * openssl 16 | 17 | ## JSON to go 18 | 19 | The [json-to-go.sh](json-to-go.sh) script generates go types from the specified JSON schema. 20 | 21 | It takes two arguments: 22 | 1. The OCPP version: either `ocpp16` or `ocpp201` 23 | 2. The name of the schema file from manager/schemas/ 24 | 25 | Requires: 26 | * [gojsonschema](https://github.com/xeipuuv/gojsonschema) -------------------------------------------------------------------------------- /scripts/json-to-go.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function usage() { 4 | echo "Wrapper to extract Go code from JSON schema" 5 | echo 6 | echo "Usage: json-to-go.sh " 7 | echo " where " is either ocpp16 or ocpp201 8 | echo " where is the name of the type you want to extract from the json schema" 9 | echo 10 | echo "NOTE: this requires gojsonschema to be installed:" 11 | echo "go install github.com/atombender/go-jsonschema/cmd/gojsonschema@latest" 12 | } 13 | 14 | function snake_case() { 15 | echo "$1" \ 16 | | sed 's/\([^A-Z]\)\([A-Z0-9]\)/\1_\2/g' \ 17 | | sed 's/\([A-Z0-9]\)\([A-Z0-9]\)\([^A-Z]\)/\1_\2\3/g' \ 18 | | tr '[:upper:]' '[:lower:]' 19 | } 20 | 21 | if [[ -z "$1" || -z "$2" ]] 22 | then 23 | usage 24 | exit 1 25 | fi 26 | 27 | file=$(snake_case "$2") 28 | 29 | $(go env GOPATH)/bin/gojsonschema -p "$1" manager/schemas/"$1"/"$2".json > manager/ocpp/"$1"/"$file".go 30 | 31 | -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | command_exists() { 4 | command -v "$1" >/dev/null 2>&1 5 | } 6 | 7 | # Check if 'docker compose' is available (with space) 8 | if command_exists "docker compose"; then 9 | DOCKER_COMPOSE_CMD="docker compose" 10 | else 11 | # Check if 'docker-compose' is available 12 | if command_exists docker-compose; then 13 | DOCKER_COMPOSE_CMD="docker-compose" 14 | else 15 | echo "Error: Neither 'docker-compose' nor 'docker compose' is available. Please install Docker Compose." 16 | exit 1 17 | fi 18 | fi 19 | 20 | $DOCKER_COMPOSE_CMD up "${@:1}" 21 | --------------------------------------------------------------------------------