From 57b16d09167948467789e7bf85acdf9915cac376 Mon Sep 17 00:00:00 2001 From: Auke Oosterhoff Date: Thu, 20 Jul 2023 16:23:16 +0200 Subject: [PATCH 1/2] Allow to provide JSON schemas manually The OCA doesn't allow to share the JSON schemas for OCPP 2.1 outside it's members. Thus this library can't include these schemas. This commit introduces the `SchemaValidator`: a structure that loads schemas located at inprovide folder and validates payload against those schemas. The file names of the schema must follow the format 'Request' or 'Response'. E.g.: "HeartbeatRequest" or "BootNotificationResponse". The file names for the schemas of OCPP 1.6 and OCPP 2.0 have been adjusted to follow this pattern. Users relying on `ocpp.v16`, `ocpp.v20` or `ocpp.v201` shouldn't be affected by introduction of `SchemaValidator`. These modules create a default instance of `Validator` to include the right set of schemas. Users of `ocpp.v21` can create a custom validator and pass it to the construct of `ocpp.v21.ChargePoint`. See also the two examples in `examples/v21/`. Fixes: #453 --- Makefile | 9 + examples/v21/central_system.py | 58 ++ examples/v21/charge_point.py | 54 ++ .../v21/schemas/BootNotificationRequest.json | 105 +++ .../v21/schemas/BootNotificationResponse.json | 79 ++ ocpp/charge_point.py | 24 +- ocpp/exceptions.py | 14 + ocpp/messages.py | 114 ++- ocpp/v16/__init__.py | 41 + .../{Authorize.json => AuthorizeRequest.json} | 0 ...tion.json => BootNotificationRequest.json} | 0 ...ion.json => CancelReservationRequest.json} | 0 ...ned.json => CertificateSignedRequest.json} | 0 ...ty.json => ChangeAvailabilityRequest.json} | 0 ...n.json => ChangeConfigurationRequest.json} | 0 ...ClearCache.json => ClearCacheRequest.json} | 0 ....json => ClearChargingProfileRequest.json} | 0 ...Transfer.json => DataTransferRequest.json} | 0 ...ate.json => DeleteCertificateRequest.json} | 0 ...DiagnosticsStatusNotificationRequest.json} | 0 ...son => ExtendedTriggerMessageRequest.json} | 0 ...=> FirmwareStatusNotificationRequest.json} | 0 ....json => GetCompositeScheduleRequest.json} | 0 ...tion.json => GetConfigurationRequest.json} | 0 ...ostics.json => GetDiagnosticsRequest.json} | 0 ...=> GetInstalledCertificateIdsRequest.json} | 0 ...n.json => GetLocalListVersionRequest.json} | 0 .../{GetLog.json => GetLogRequest.json} | 0 .../{Heartbeat.json => HeartbeatRequest.json} | 0 ...te.json => InstallCertificateRequest.json} | 0 ...json => LogStatusNotificationRequest.json} | 0 ...terValues.json => MeterValuesRequest.json} | 0 ...son => RemoteStartTransactionRequest.json} | 0 ...json => RemoteStopTransactionRequest.json} | 0 ...ReserveNow.json => ReserveNowRequest.json} | 0 .../schemas/{Reset.json => ResetRequest.json} | 0 ... => SecurityEventNotificationRequest.json} | 0 ...calList.json => SendLocalListRequest.json} | 0 ...le.json => SetChargingProfileRequest.json} | 0 ...icate.json => SignCertificateRequest.json} | 0 ...nedFirmwareStatusNotificationRequest.json} | 0 ....json => SignedUpdateFirmwareRequest.json} | 0 ...tion.json => StartTransactionRequest.json} | 0 ...on.json => StatusNotificationRequest.json} | 0 ...ction.json => StopTransactionRequest.json} | 0 ...essage.json => TriggerMessageRequest.json} | 0 ...ector.json => UnlockConnectorRequest.json} | 0 ...rmware.json => UpdateFirmwareRequest.json} | 0 ocpp/v20/__init__.py | 9 + ...equest_v1p0.json => AuthorizeRequest.json} | 0 ...ponse_v1p0.json => AuthorizeResponse.json} | 0 ...v1p0.json => BootNotificationRequest.json} | 0 ...1p0.json => BootNotificationResponse.json} | 0 ...1p0.json => CancelReservationRequest.json} | 0 ...p0.json => CancelReservationResponse.json} | 0 ...1p0.json => CertificateSignedRequest.json} | 0 ...p0.json => CertificateSignedResponse.json} | 0 ...p0.json => ChangeAvailabilityRequest.json} | 0 ...0.json => ChangeAvailabilityResponse.json} | 0 ...quest_v1p0.json => ClearCacheRequest.json} | 0 ...onse_v1p0.json => ClearCacheResponse.json} | 0 ....json => ClearChargingProfileRequest.json} | 0 ...json => ClearChargingProfileResponse.json} | 0 ...0.json => ClearDisplayMessageRequest.json} | 0 ....json => ClearDisplayMessageResponse.json} | 0 ...on => ClearVariableMonitoringRequest.json} | 0 ...n => ClearVariableMonitoringResponse.json} | 0 ....json => ClearedChargingLimitRequest.json} | 0 ...json => ClearedChargingLimitResponse.json} | 0 ...uest_v1p0.json => CostUpdatedRequest.json} | 0 ...nse_v1p0.json => CostUpdatedResponse.json} | 0 ...0.json => CustomerInformationRequest.json} | 0 ....json => CustomerInformationResponse.json} | 0 ...est_v1p0.json => DataTransferRequest.json} | 0 ...se_v1p0.json => DataTransferResponse.json} | 0 ...1p0.json => DeleteCertificateRequest.json} | 0 ...p0.json => DeleteCertificateResponse.json} | 0 ...=> FirmwareStatusNotificationRequest.json} | 0 ...> FirmwareStatusNotificationResponse.json} | 0 ...json => Get15118EVCertificateRequest.json} | 0 ...son => Get15118EVCertificateResponse.json} | 0 ...st_v1p0.json => GetBaseReportRequest.json} | 0 ...e_v1p0.json => GetBaseReportResponse.json} | 0 ....json => GetCertificateStatusRequest.json} | 0 ...json => GetCertificateStatusResponse.json} | 0 ...0.json => GetChargingProfilesRequest.json} | 0 ....json => GetChargingProfilesResponse.json} | 0 ....json => GetCompositeScheduleRequest.json} | 0 ...json => GetCompositeScheduleResponse.json} | 0 ...p0.json => GetDisplayMessagesRequest.json} | 0 ...0.json => GetDisplayMessagesResponse.json} | 0 ...=> GetInstalledCertificateIdsRequest.json} | 0 ...> GetInstalledCertificateIdsResponse.json} | 0 ...0.json => GetLocalListVersionRequest.json} | 0 ....json => GetLocalListVersionResponse.json} | 0 ...ogRequest_v1p0.json => GetLogRequest.json} | 0 ...Response_v1p0.json => GetLogResponse.json} | 0 ...0.json => GetMonitoringReportRequest.json} | 0 ....json => GetMonitoringReportResponse.json} | 0 ...equest_v1p0.json => GetReportRequest.json} | 0 ...ponse_v1p0.json => GetReportResponse.json} | 0 ....json => GetTransactionStatusRequest.json} | 0 ...json => GetTransactionStatusResponse.json} | 0 ...est_v1p0.json => GetVariablesRequest.json} | 0 ...se_v1p0.json => GetVariablesResponse.json} | 0 ...equest_v1p0.json => HeartbeatRequest.json} | 0 ...ponse_v1p0.json => HeartbeatResponse.json} | 0 ...p0.json => InstallCertificateRequest.json} | 0 ...0.json => InstallCertificateResponse.json} | 0 ...json => LogStatusNotificationRequest.json} | 0 ...son => LogStatusNotificationResponse.json} | 0 ...uest_v1p0.json => MeterValuesRequest.json} | 0 ...nse_v1p0.json => MeterValuesResponse.json} | 0 ...=> NotifyCentralChargingNeedsRequest.json} | 0 ...> NotifyCentralChargingNeedsResponse.json} | 0 ...0.json => NotifyChargingLimitRequest.json} | 0 ....json => NotifyChargingLimitResponse.json} | 0 ... => NotifyCustomerInformationRequest.json} | 0 ...=> NotifyCustomerInformationResponse.json} | 0 ...json => NotifyDisplayMessagesRequest.json} | 0 ...son => NotifyDisplayMessagesResponse.json} | 0 ...json => NotifyEVChargingNeedsRequest.json} | 0 ...son => NotifyEVChargingNeedsResponse.json} | 0 ...n => NotifyEVChargingScheduleRequest.json} | 0 ... => NotifyEVChargingScheduleResponse.json} | 0 ...uest_v1p0.json => NotifyEventRequest.json} | 0 ...nse_v1p0.json => NotifyEventResponse.json} | 0 ...son => NotifyMonitoringReportRequest.json} | 0 ...on => NotifyMonitoringReportResponse.json} | 0 ...est_v1p0.json => NotifyReportRequest.json} | 0 ...se_v1p0.json => NotifyReportResponse.json} | 0 ..._v1p0.json => PublishFirmwareRequest.json} | 0 ...v1p0.json => PublishFirmwareResponse.json} | 0 ...ishFirmwareStatusNotificationRequest.json} | 0 ...shFirmwareStatusNotificationResponse.json} | 0 ...n => Renegotiate15118ScheduleRequest.json} | 0 ... => Renegotiate15118ScheduleResponse.json} | 0 ...son => ReportChargingProfilesRequest.json} | 0 ...on => ReportChargingProfilesResponse.json} | 0 ...on => RequestStartTransactionRequest.json} | 0 ...n => RequestStartTransactionResponse.json} | 0 ...son => RequestStopTransactionRequest.json} | 0 ...on => RequestStopTransactionResponse.json} | 0 ...on => ReservationStatusUpdateRequest.json} | 0 ...n => ReservationStatusUpdateResponse.json} | 0 ...quest_v1p0.json => ReserveNowRequest.json} | 0 ...onse_v1p0.json => ReserveNowResponse.json} | 0 ...setRequest_v1p0.json => ResetRequest.json} | 0 ...tResponse_v1p0.json => ResetResponse.json} | 0 ... => SecurityEventNotificationRequest.json} | 0 ...=> SecurityEventNotificationResponse.json} | 0 ...st_v1p0.json => SendLocalListRequest.json} | 0 ...e_v1p0.json => SendLocalListResponse.json} | 0 ...p0.json => SetChargingProfileRequest.json} | 0 ...0.json => SetChargingProfileResponse.json} | 0 ...1p0.json => SetDisplayMessageRequest.json} | 0 ...p0.json => SetDisplayMessageResponse.json} | 0 ...1p0.json => SetMonitoringBaseRequest.json} | 0 ...p0.json => SetMonitoringBaseResponse.json} | 0 ...p0.json => SetMonitoringLevelRequest.json} | 0 ...0.json => SetMonitoringLevelResponse.json} | 0 ...1p0.json => SetNetworkProfileRequest.json} | 0 ...p0.json => SetNetworkProfileResponse.json} | 0 ...json => SetVariableMonitoringRequest.json} | 0 ...son => SetVariableMonitoringResponse.json} | 0 ...est_v1p0.json => SetVariablesRequest.json} | 0 ...se_v1p0.json => SetVariablesResponse.json} | 0 ..._v1p0.json => SignCertificateRequest.json} | 0 ...v1p0.json => SignCertificateResponse.json} | 0 ...p0.json => StatusNotificationRequest.json} | 0 ...0.json => StatusNotificationResponse.json} | 0 ...v1p0.json => TransactionEventRequest.json} | 0 ...1p0.json => TransactionEventResponse.json} | 0 ...t_v1p0.json => TriggerMessageRequest.json} | 0 ..._v1p0.json => TriggerMessageResponse.json} | 0 ..._v1p0.json => UnlockConnectorRequest.json} | 0 ...v1p0.json => UnlockConnectorResponse.json} | 0 ...1p0.json => UnpublishFirmwareRequest.json} | 0 ...p0.json => UnpublishFirmwareResponse.json} | 0 ...n => Update15118EVCertificateRequest.json} | 0 ... => Update15118EVCertificateResponse.json} | 0 ...t_v1p0.json => UpdateFirmwareRequest.json} | 0 ..._v1p0.json => UpdateFirmwareResponse.json} | 0 ocpp/v201/__init__.py | 9 + ocpp/v21/__init__.py | 27 + ocpp/v21/call.py | 620 ++++++++++++++ ocpp/v21/call_result.py | 536 ++++++++++++ ocpp/v21/datatypes.py | 773 +++++++++++++++++ ocpp/v21/enums.py | 790 ++++++++++++++++++ poetry.lock | 682 ++++++++++----- pyproject.toml | 3 + tests/test_charge_point.py | 7 +- tests/test_exceptions.py | 5 +- tests/test_messages.py | 40 +- 194 files changed, 3719 insertions(+), 280 deletions(-) create mode 100644 examples/v21/central_system.py create mode 100644 examples/v21/charge_point.py create mode 100644 examples/v21/schemas/BootNotificationRequest.json create mode 100644 examples/v21/schemas/BootNotificationResponse.json rename ocpp/v16/schemas/{Authorize.json => AuthorizeRequest.json} (100%) rename ocpp/v16/schemas/{BootNotification.json => BootNotificationRequest.json} (100%) rename ocpp/v16/schemas/{CancelReservation.json => CancelReservationRequest.json} (100%) rename ocpp/v16/schemas/{CertificateSigned.json => CertificateSignedRequest.json} (100%) rename ocpp/v16/schemas/{ChangeAvailability.json => ChangeAvailabilityRequest.json} (100%) rename ocpp/v16/schemas/{ChangeConfiguration.json => ChangeConfigurationRequest.json} (100%) rename ocpp/v16/schemas/{ClearCache.json => ClearCacheRequest.json} (100%) rename ocpp/v16/schemas/{ClearChargingProfile.json => ClearChargingProfileRequest.json} (100%) rename ocpp/v16/schemas/{DataTransfer.json => DataTransferRequest.json} (100%) rename ocpp/v16/schemas/{DeleteCertificate.json => DeleteCertificateRequest.json} (100%) rename ocpp/v16/schemas/{DiagnosticsStatusNotification.json => DiagnosticsStatusNotificationRequest.json} (100%) rename ocpp/v16/schemas/{ExtendedTriggerMessage.json => ExtendedTriggerMessageRequest.json} (100%) rename ocpp/v16/schemas/{FirmwareStatusNotification.json => FirmwareStatusNotificationRequest.json} (100%) rename ocpp/v16/schemas/{GetCompositeSchedule.json => GetCompositeScheduleRequest.json} (100%) rename ocpp/v16/schemas/{GetConfiguration.json => GetConfigurationRequest.json} (100%) rename ocpp/v16/schemas/{GetDiagnostics.json => GetDiagnosticsRequest.json} (100%) rename ocpp/v16/schemas/{GetInstalledCertificateIds.json => GetInstalledCertificateIdsRequest.json} (100%) rename ocpp/v16/schemas/{GetLocalListVersion.json => GetLocalListVersionRequest.json} (100%) rename ocpp/v16/schemas/{GetLog.json => GetLogRequest.json} (100%) rename ocpp/v16/schemas/{Heartbeat.json => HeartbeatRequest.json} (100%) rename ocpp/v16/schemas/{InstallCertificate.json => InstallCertificateRequest.json} (100%) rename ocpp/v16/schemas/{LogStatusNotification.json => LogStatusNotificationRequest.json} (100%) rename ocpp/v16/schemas/{MeterValues.json => MeterValuesRequest.json} (100%) rename ocpp/v16/schemas/{RemoteStartTransaction.json => RemoteStartTransactionRequest.json} (100%) rename ocpp/v16/schemas/{RemoteStopTransaction.json => RemoteStopTransactionRequest.json} (100%) rename ocpp/v16/schemas/{ReserveNow.json => ReserveNowRequest.json} (100%) rename ocpp/v16/schemas/{Reset.json => ResetRequest.json} (100%) rename ocpp/v16/schemas/{SecurityEventNotification.json => SecurityEventNotificationRequest.json} (100%) rename ocpp/v16/schemas/{SendLocalList.json => SendLocalListRequest.json} (100%) rename ocpp/v16/schemas/{SetChargingProfile.json => SetChargingProfileRequest.json} (100%) rename ocpp/v16/schemas/{SignCertificate.json => SignCertificateRequest.json} (100%) rename ocpp/v16/schemas/{SignedFirmwareStatusNotification.json => SignedFirmwareStatusNotificationRequest.json} (100%) rename ocpp/v16/schemas/{SignedUpdateFirmware.json => SignedUpdateFirmwareRequest.json} (100%) rename ocpp/v16/schemas/{StartTransaction.json => StartTransactionRequest.json} (100%) rename ocpp/v16/schemas/{StatusNotification.json => StatusNotificationRequest.json} (100%) rename ocpp/v16/schemas/{StopTransaction.json => StopTransactionRequest.json} (100%) rename ocpp/v16/schemas/{TriggerMessage.json => TriggerMessageRequest.json} (100%) rename ocpp/v16/schemas/{UnlockConnector.json => UnlockConnectorRequest.json} (100%) rename ocpp/v16/schemas/{UpdateFirmware.json => UpdateFirmwareRequest.json} (100%) rename ocpp/v20/schemas/{AuthorizeRequest_v1p0.json => AuthorizeRequest.json} (100%) rename ocpp/v20/schemas/{AuthorizeResponse_v1p0.json => AuthorizeResponse.json} (100%) rename ocpp/v20/schemas/{BootNotificationRequest_v1p0.json => BootNotificationRequest.json} (100%) rename ocpp/v20/schemas/{BootNotificationResponse_v1p0.json => BootNotificationResponse.json} (100%) rename ocpp/v20/schemas/{CancelReservationRequest_v1p0.json => CancelReservationRequest.json} (100%) rename ocpp/v20/schemas/{CancelReservationResponse_v1p0.json => CancelReservationResponse.json} (100%) rename ocpp/v20/schemas/{CertificateSignedRequest_v1p0.json => CertificateSignedRequest.json} (100%) rename ocpp/v20/schemas/{CertificateSignedResponse_v1p0.json => CertificateSignedResponse.json} (100%) rename ocpp/v20/schemas/{ChangeAvailabilityRequest_v1p0.json => ChangeAvailabilityRequest.json} (100%) rename ocpp/v20/schemas/{ChangeAvailabilityResponse_v1p0.json => ChangeAvailabilityResponse.json} (100%) rename ocpp/v20/schemas/{ClearCacheRequest_v1p0.json => ClearCacheRequest.json} (100%) rename ocpp/v20/schemas/{ClearCacheResponse_v1p0.json => ClearCacheResponse.json} (100%) rename ocpp/v20/schemas/{ClearChargingProfileRequest_v1p0.json => ClearChargingProfileRequest.json} (100%) rename ocpp/v20/schemas/{ClearChargingProfileResponse_v1p0.json => ClearChargingProfileResponse.json} (100%) rename ocpp/v20/schemas/{ClearDisplayMessageRequest_v1p0.json => ClearDisplayMessageRequest.json} (100%) rename ocpp/v20/schemas/{ClearDisplayMessageResponse_v1p0.json => ClearDisplayMessageResponse.json} (100%) rename ocpp/v20/schemas/{ClearVariableMonitoringRequest_v1p0.json => ClearVariableMonitoringRequest.json} (100%) rename ocpp/v20/schemas/{ClearVariableMonitoringResponse_v1p0.json => ClearVariableMonitoringResponse.json} (100%) rename ocpp/v20/schemas/{ClearedChargingLimitRequest_v1p0.json => ClearedChargingLimitRequest.json} (100%) rename ocpp/v20/schemas/{ClearedChargingLimitResponse_v1p0.json => ClearedChargingLimitResponse.json} (100%) rename ocpp/v20/schemas/{CostUpdatedRequest_v1p0.json => CostUpdatedRequest.json} (100%) rename ocpp/v20/schemas/{CostUpdatedResponse_v1p0.json => CostUpdatedResponse.json} (100%) rename ocpp/v20/schemas/{CustomerInformationRequest_v1p0.json => CustomerInformationRequest.json} (100%) rename ocpp/v20/schemas/{CustomerInformationResponse_v1p0.json => CustomerInformationResponse.json} (100%) rename ocpp/v20/schemas/{DataTransferRequest_v1p0.json => DataTransferRequest.json} (100%) rename ocpp/v20/schemas/{DataTransferResponse_v1p0.json => DataTransferResponse.json} (100%) rename ocpp/v20/schemas/{DeleteCertificateRequest_v1p0.json => DeleteCertificateRequest.json} (100%) rename ocpp/v20/schemas/{DeleteCertificateResponse_v1p0.json => DeleteCertificateResponse.json} (100%) rename ocpp/v20/schemas/{FirmwareStatusNotificationRequest_v1p0.json => FirmwareStatusNotificationRequest.json} (100%) rename ocpp/v20/schemas/{FirmwareStatusNotificationResponse_v1p0.json => FirmwareStatusNotificationResponse.json} (100%) rename ocpp/v20/schemas/{Get15118EVCertificateRequest_v1p0.json => Get15118EVCertificateRequest.json} (100%) rename ocpp/v20/schemas/{Get15118EVCertificateResponse_v1p0.json => Get15118EVCertificateResponse.json} (100%) rename ocpp/v20/schemas/{GetBaseReportRequest_v1p0.json => GetBaseReportRequest.json} (100%) rename ocpp/v20/schemas/{GetBaseReportResponse_v1p0.json => GetBaseReportResponse.json} (100%) rename ocpp/v20/schemas/{GetCertificateStatusRequest_v1p0.json => GetCertificateStatusRequest.json} (100%) rename ocpp/v20/schemas/{GetCertificateStatusResponse_v1p0.json => GetCertificateStatusResponse.json} (100%) rename ocpp/v20/schemas/{GetChargingProfilesRequest_v1p0.json => GetChargingProfilesRequest.json} (100%) rename ocpp/v20/schemas/{GetChargingProfilesResponse_v1p0.json => GetChargingProfilesResponse.json} (100%) rename ocpp/v20/schemas/{GetCompositeScheduleRequest_v1p0.json => GetCompositeScheduleRequest.json} (100%) rename ocpp/v20/schemas/{GetCompositeScheduleResponse_v1p0.json => GetCompositeScheduleResponse.json} (100%) rename ocpp/v20/schemas/{GetDisplayMessagesRequest_v1p0.json => GetDisplayMessagesRequest.json} (100%) rename ocpp/v20/schemas/{GetDisplayMessagesResponse_v1p0.json => GetDisplayMessagesResponse.json} (100%) rename ocpp/v20/schemas/{GetInstalledCertificateIdsRequest_v1p0.json => GetInstalledCertificateIdsRequest.json} (100%) rename ocpp/v20/schemas/{GetInstalledCertificateIdsResponse_v1p0.json => GetInstalledCertificateIdsResponse.json} (100%) rename ocpp/v20/schemas/{GetLocalListVersionRequest_v1p0.json => GetLocalListVersionRequest.json} (100%) rename ocpp/v20/schemas/{GetLocalListVersionResponse_v1p0.json => GetLocalListVersionResponse.json} (100%) rename ocpp/v20/schemas/{GetLogRequest_v1p0.json => GetLogRequest.json} (100%) rename ocpp/v20/schemas/{GetLogResponse_v1p0.json => GetLogResponse.json} (100%) rename ocpp/v20/schemas/{GetMonitoringReportRequest_v1p0.json => GetMonitoringReportRequest.json} (100%) rename ocpp/v20/schemas/{GetMonitoringReportResponse_v1p0.json => GetMonitoringReportResponse.json} (100%) rename ocpp/v20/schemas/{GetReportRequest_v1p0.json => GetReportRequest.json} (100%) rename ocpp/v20/schemas/{GetReportResponse_v1p0.json => GetReportResponse.json} (100%) rename ocpp/v20/schemas/{GetTransactionStatusRequest_v1p0.json => GetTransactionStatusRequest.json} (100%) rename ocpp/v20/schemas/{GetTransactionStatusResponse_v1p0.json => GetTransactionStatusResponse.json} (100%) rename ocpp/v20/schemas/{GetVariablesRequest_v1p0.json => GetVariablesRequest.json} (100%) rename ocpp/v20/schemas/{GetVariablesResponse_v1p0.json => GetVariablesResponse.json} (100%) rename ocpp/v20/schemas/{HeartbeatRequest_v1p0.json => HeartbeatRequest.json} (100%) rename ocpp/v20/schemas/{HeartbeatResponse_v1p0.json => HeartbeatResponse.json} (100%) rename ocpp/v20/schemas/{InstallCertificateRequest_v1p0.json => InstallCertificateRequest.json} (100%) rename ocpp/v20/schemas/{InstallCertificateResponse_v1p0.json => InstallCertificateResponse.json} (100%) rename ocpp/v20/schemas/{LogStatusNotificationRequest_v1p0.json => LogStatusNotificationRequest.json} (100%) rename ocpp/v20/schemas/{LogStatusNotificationResponse_v1p0.json => LogStatusNotificationResponse.json} (100%) rename ocpp/v20/schemas/{MeterValuesRequest_v1p0.json => MeterValuesRequest.json} (100%) rename ocpp/v20/schemas/{MeterValuesResponse_v1p0.json => MeterValuesResponse.json} (100%) rename ocpp/v20/schemas/{NotifyCentralChargingNeedsRequest_v1p0.json => NotifyCentralChargingNeedsRequest.json} (100%) rename ocpp/v20/schemas/{NotifyCentralChargingNeedsResponse_v1p0.json => NotifyCentralChargingNeedsResponse.json} (100%) rename ocpp/v20/schemas/{NotifyChargingLimitRequest_v1p0.json => NotifyChargingLimitRequest.json} (100%) rename ocpp/v20/schemas/{NotifyChargingLimitResponse_v1p0.json => NotifyChargingLimitResponse.json} (100%) rename ocpp/v20/schemas/{NotifyCustomerInformationRequest_v1p0.json => NotifyCustomerInformationRequest.json} (100%) rename ocpp/v20/schemas/{NotifyCustomerInformationResponse_v1p0.json => NotifyCustomerInformationResponse.json} (100%) rename ocpp/v20/schemas/{NotifyDisplayMessagesRequest_v1p0.json => NotifyDisplayMessagesRequest.json} (100%) rename ocpp/v20/schemas/{NotifyDisplayMessagesResponse_v1p0.json => NotifyDisplayMessagesResponse.json} (100%) rename ocpp/v20/schemas/{NotifyEVChargingNeedsRequest_v1p0.json => NotifyEVChargingNeedsRequest.json} (100%) rename ocpp/v20/schemas/{NotifyEVChargingNeedsResponse_v1p0.json => NotifyEVChargingNeedsResponse.json} (100%) rename ocpp/v20/schemas/{NotifyEVChargingScheduleRequest_v1p0.json => NotifyEVChargingScheduleRequest.json} (100%) rename ocpp/v20/schemas/{NotifyEVChargingScheduleResponse_v1p0.json => NotifyEVChargingScheduleResponse.json} (100%) rename ocpp/v20/schemas/{NotifyEventRequest_v1p0.json => NotifyEventRequest.json} (100%) rename ocpp/v20/schemas/{NotifyEventResponse_v1p0.json => NotifyEventResponse.json} (100%) rename ocpp/v20/schemas/{NotifyMonitoringReportRequest_v1p0.json => NotifyMonitoringReportRequest.json} (100%) rename ocpp/v20/schemas/{NotifyMonitoringReportResponse_v1p0.json => NotifyMonitoringReportResponse.json} (100%) rename ocpp/v20/schemas/{NotifyReportRequest_v1p0.json => NotifyReportRequest.json} (100%) rename ocpp/v20/schemas/{NotifyReportResponse_v1p0.json => NotifyReportResponse.json} (100%) rename ocpp/v20/schemas/{PublishFirmwareRequest_v1p0.json => PublishFirmwareRequest.json} (100%) rename ocpp/v20/schemas/{PublishFirmwareResponse_v1p0.json => PublishFirmwareResponse.json} (100%) rename ocpp/v20/schemas/{PublishFirmwareStatusNotificationRequest_v1p0.json => PublishFirmwareStatusNotificationRequest.json} (100%) rename ocpp/v20/schemas/{PublishFirmwareStatusNotificationResponse_v1p0.json => PublishFirmwareStatusNotificationResponse.json} (100%) rename ocpp/v20/schemas/{Renegotiate15118ScheduleRequest_v1p0.json => Renegotiate15118ScheduleRequest.json} (100%) rename ocpp/v20/schemas/{Renegotiate15118ScheduleResponse_v1p0.json => Renegotiate15118ScheduleResponse.json} (100%) rename ocpp/v20/schemas/{ReportChargingProfilesRequest_v1p0.json => ReportChargingProfilesRequest.json} (100%) rename ocpp/v20/schemas/{ReportChargingProfilesResponse_v1p0.json => ReportChargingProfilesResponse.json} (100%) rename ocpp/v20/schemas/{RequestStartTransactionRequest_v1p0.json => RequestStartTransactionRequest.json} (100%) rename ocpp/v20/schemas/{RequestStartTransactionResponse_v1p0.json => RequestStartTransactionResponse.json} (100%) rename ocpp/v20/schemas/{RequestStopTransactionRequest_v1p0.json => RequestStopTransactionRequest.json} (100%) rename ocpp/v20/schemas/{RequestStopTransactionResponse_v1p0.json => RequestStopTransactionResponse.json} (100%) rename ocpp/v20/schemas/{ReservationStatusUpdateRequest_v1p0.json => ReservationStatusUpdateRequest.json} (100%) rename ocpp/v20/schemas/{ReservationStatusUpdateResponse_v1p0.json => ReservationStatusUpdateResponse.json} (100%) rename ocpp/v20/schemas/{ReserveNowRequest_v1p0.json => ReserveNowRequest.json} (100%) rename ocpp/v20/schemas/{ReserveNowResponse_v1p0.json => ReserveNowResponse.json} (100%) rename ocpp/v20/schemas/{ResetRequest_v1p0.json => ResetRequest.json} (100%) rename ocpp/v20/schemas/{ResetResponse_v1p0.json => ResetResponse.json} (100%) rename ocpp/v20/schemas/{SecurityEventNotificationRequest_v1p0.json => SecurityEventNotificationRequest.json} (100%) rename ocpp/v20/schemas/{SecurityEventNotificationResponse_v1p0.json => SecurityEventNotificationResponse.json} (100%) rename ocpp/v20/schemas/{SendLocalListRequest_v1p0.json => SendLocalListRequest.json} (100%) rename ocpp/v20/schemas/{SendLocalListResponse_v1p0.json => SendLocalListResponse.json} (100%) rename ocpp/v20/schemas/{SetChargingProfileRequest_v1p0.json => SetChargingProfileRequest.json} (100%) rename ocpp/v20/schemas/{SetChargingProfileResponse_v1p0.json => SetChargingProfileResponse.json} (100%) rename ocpp/v20/schemas/{SetDisplayMessageRequest_v1p0.json => SetDisplayMessageRequest.json} (100%) rename ocpp/v20/schemas/{SetDisplayMessageResponse_v1p0.json => SetDisplayMessageResponse.json} (100%) rename ocpp/v20/schemas/{SetMonitoringBaseRequest_v1p0.json => SetMonitoringBaseRequest.json} (100%) rename ocpp/v20/schemas/{SetMonitoringBaseResponse_v1p0.json => SetMonitoringBaseResponse.json} (100%) rename ocpp/v20/schemas/{SetMonitoringLevelRequest_v1p0.json => SetMonitoringLevelRequest.json} (100%) rename ocpp/v20/schemas/{SetMonitoringLevelResponse_v1p0.json => SetMonitoringLevelResponse.json} (100%) rename ocpp/v20/schemas/{SetNetworkProfileRequest_v1p0.json => SetNetworkProfileRequest.json} (100%) rename ocpp/v20/schemas/{SetNetworkProfileResponse_v1p0.json => SetNetworkProfileResponse.json} (100%) rename ocpp/v20/schemas/{SetVariableMonitoringRequest_v1p0.json => SetVariableMonitoringRequest.json} (100%) rename ocpp/v20/schemas/{SetVariableMonitoringResponse_v1p0.json => SetVariableMonitoringResponse.json} (100%) rename ocpp/v20/schemas/{SetVariablesRequest_v1p0.json => SetVariablesRequest.json} (100%) rename ocpp/v20/schemas/{SetVariablesResponse_v1p0.json => SetVariablesResponse.json} (100%) rename ocpp/v20/schemas/{SignCertificateRequest_v1p0.json => SignCertificateRequest.json} (100%) rename ocpp/v20/schemas/{SignCertificateResponse_v1p0.json => SignCertificateResponse.json} (100%) rename ocpp/v20/schemas/{StatusNotificationRequest_v1p0.json => StatusNotificationRequest.json} (100%) rename ocpp/v20/schemas/{StatusNotificationResponse_v1p0.json => StatusNotificationResponse.json} (100%) rename ocpp/v20/schemas/{TransactionEventRequest_v1p0.json => TransactionEventRequest.json} (100%) rename ocpp/v20/schemas/{TransactionEventResponse_v1p0.json => TransactionEventResponse.json} (100%) rename ocpp/v20/schemas/{TriggerMessageRequest_v1p0.json => TriggerMessageRequest.json} (100%) rename ocpp/v20/schemas/{TriggerMessageResponse_v1p0.json => TriggerMessageResponse.json} (100%) rename ocpp/v20/schemas/{UnlockConnectorRequest_v1p0.json => UnlockConnectorRequest.json} (100%) rename ocpp/v20/schemas/{UnlockConnectorResponse_v1p0.json => UnlockConnectorResponse.json} (100%) rename ocpp/v20/schemas/{UnpublishFirmwareRequest_v1p0.json => UnpublishFirmwareRequest.json} (100%) rename ocpp/v20/schemas/{UnpublishFirmwareResponse_v1p0.json => UnpublishFirmwareResponse.json} (100%) rename ocpp/v20/schemas/{Update15118EVCertificateRequest_v1p0.json => Update15118EVCertificateRequest.json} (100%) rename ocpp/v20/schemas/{Update15118EVCertificateResponse_v1p0.json => Update15118EVCertificateResponse.json} (100%) rename ocpp/v20/schemas/{UpdateFirmwareRequest_v1p0.json => UpdateFirmwareRequest.json} (100%) rename ocpp/v20/schemas/{UpdateFirmwareResponse_v1p0.json => UpdateFirmwareResponse.json} (100%) create mode 100644 ocpp/v21/__init__.py create mode 100644 ocpp/v21/call.py create mode 100644 ocpp/v21/call_result.py create mode 100644 ocpp/v21/datatypes.py create mode 100644 ocpp/v21/enums.py diff --git a/Makefile b/Makefile index d41951ec8..4ee3dc830 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,9 @@ help: @echo " If no version is provided, poetry outputs the current project version" @echo " test run all the tests and linting" @echo " update updates the dependencies in poetry.lock" + @echo " v21-central-system-example Run the example implementing an OCPP 2.1 central system. + @echo " v21-charge-point-example Run the example implementing an OCPP 2.1 charger. + @echo " update updates the dependencies in poetry.lock" @echo "" @echo "Check the Makefile to know exactly what each target is doing." @@ -55,3 +58,9 @@ release: .install-poetry deploy: update tests poetry publish --build + +v21-central-system-example: + PYTHONPATH=ocpp:$$PYTHONPATH poetry run python examples/v21/central_system.py + +v21-charge-point-example: + PYTHONPATH=ocpp:$$PYTHONPATH poetry run python examples/v21/charge_point.py diff --git a/examples/v21/central_system.py b/examples/v21/central_system.py new file mode 100644 index 000000000..64cbf55c0 --- /dev/null +++ b/examples/v21/central_system.py @@ -0,0 +1,58 @@ +import asyncio +import logging +import pathlib +from datetime import datetime, timezone + +try: + import websockets +except ModuleNotFoundError: + print("This example relies on the 'websockets' package.") + print("Please install it by running: ") + print() + print(" $ pip install websockets") + import sys + + sys.exit(1) + +from ocpp.messages import SchemaValidator +from ocpp.routing import on +from ocpp.v21 import ChargePoint as cp +from ocpp.v21 import call_result +from ocpp.v21.enums import RegistrationStatus + +logging.basicConfig(level=logging.INFO) + +# The ocpp package doesn't come with the JSON schemas for OCPP 2.1. +# See https://github.com/mobilityhouse/ocpp/issues/458 for more details. +schemas_dir = str(pathlib.Path(__file__).parent.joinpath("schemas").resolve()) +validator = SchemaValidator(schemas_dir) + + +class ChargePoint(cp): + @on("BootNotification") + def on_boot_notification(self, reason: str, charging_station: str, **kwargs): + return call_result.BootNotification( + current_time=datetime.now(timezone.utc).isoformat(), + interval=10, + status=RegistrationStatus.accepted, + ) + + +async def on_connect(websocket, path): + charge_point_id = path.strip("/") + cp = ChargePoint(charge_point_id, websocket, validator) + + await cp.start() + + +async def main(): + server = await websockets.serve( + on_connect, "0.0.0.0", 9000, subprotocols=["ocpp2.1"] + ) + + logging.info("Server Started listening to new connections...") + await server.wait_closed() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/v21/charge_point.py b/examples/v21/charge_point.py new file mode 100644 index 000000000..e3dcfff99 --- /dev/null +++ b/examples/v21/charge_point.py @@ -0,0 +1,54 @@ +import asyncio +import logging +import pathlib + +try: + import websockets +except ModuleNotFoundError: + print("This example relies on the 'websockets' package.") + print("Please install it by running: ") + print() + print(" $ pip install websockets") + import sys + + sys.exit(1) + +from ocpp.messages import SchemaValidator +from ocpp.v21 import ChargePoint as cp +from ocpp.v21 import call, call_result +from ocpp.v21.datatypes import ChargingStation +from ocpp.v21.enums import BootReason, RegistrationStatus + +logging.basicConfig(level=logging.INFO) + +schemas_dir = pathlib.Path(__file__).parent.joinpath("schemas").resolve() +validator = SchemaValidator(str(schemas_dir)) + + +class ChargePoint(cp): + async def send_boot_notification(self): + request = call.BootNotification( + reason=BootReason.power_up, + charging_station=ChargingStation( + model="Virtual Charge Point", + vendor_name="y", + ), + ) + + response: call_result.BootNotification = await self.call(request) + + if response.status == RegistrationStatus.accepted: + print("Connected to central system.") + + +async def main(): + async with websockets.connect( + "ws://localhost:9000/CP_1", subprotocols=["ocpp2.1"] + ) as ws: + cp = ChargePoint("CP_1", ws, validator) + + await asyncio.gather(cp.start(), cp.send_boot_notification()) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/v21/schemas/BootNotificationRequest.json b/examples/v21/schemas/BootNotificationRequest.json new file mode 100644 index 000000000..8fa121afb --- /dev/null +++ b/examples/v21/schemas/BootNotificationRequest.json @@ -0,0 +1,105 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$id": "urn:OCPP:Cp:2:2023:5:BootNotificationRequest", + "comment": "OCPP 2.1 Draft 1, Copyright Open Charge Alliance", + "definitions": { + "CustomDataType": { + "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.", + "javaType": "CustomData", + "type": "object", + "properties": { + "vendorId": { + "type": "string", + "maxLength": 255 + } + }, + "required": [ + "vendorId" + ] + }, + "BootReasonEnumType": { + "javaType": "BootReasonEnum", + "type": "string", + "additionalProperties": false, + "enum": [ + "ApplicationReset", + "FirmwareUpdate", + "LocalReset", + "PowerUp", + "RemoteReset", + "ScheduledReset", + "Triggered", + "Unknown", + "Watchdog" + ] + }, + "ChargingStationType": { + "javaType": "ChargingStation", + "type": "object", + "additionalProperties": false, + "properties": { + "customData": { + "$ref": "#/definitions/CustomDataType" + }, + "serialNumber": { + "type": "string", + "maxLength": 25 + }, + "model": { + "type": "string", + "maxLength": 20 + }, + "modem": { + "$ref": "#/definitions/ModemType" + }, + "vendorName": { + "type": "string", + "maxLength": 50 + }, + "firmwareVersion": { + "type": "string", + "maxLength": 50 + } + }, + "required": [ + "model", + "vendorName" + ] + }, + "ModemType": { + "javaType": "Modem", + "type": "object", + "additionalProperties": false, + "properties": { + "customData": { + "$ref": "#/definitions/CustomDataType" + }, + "iccid": { + "type": "string", + "maxLength": 20 + }, + "imsi": { + "type": "string", + "maxLength": 20 + } + } + } + }, + "type": "object", + "additionalProperties": false, + "properties": { + "customData": { + "$ref": "#/definitions/CustomDataType" + }, + "chargingStation": { + "$ref": "#/definitions/ChargingStationType" + }, + "reason": { + "$ref": "#/definitions/BootReasonEnumType" + } + }, + "required": [ + "reason", + "chargingStation" + ] +} \ No newline at end of file diff --git a/examples/v21/schemas/BootNotificationResponse.json b/examples/v21/schemas/BootNotificationResponse.json new file mode 100644 index 000000000..223df2663 --- /dev/null +++ b/examples/v21/schemas/BootNotificationResponse.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$id": "urn:OCPP:Cp:2:2023:5:BootNotificationResponse", + "comment": "OCPP 2.1 Draft 1, Copyright Open Charge Alliance", + "definitions": { + "CustomDataType": { + "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.", + "javaType": "CustomData", + "type": "object", + "properties": { + "vendorId": { + "type": "string", + "maxLength": 255 + } + }, + "required": [ + "vendorId" + ] + }, + "RegistrationStatusEnumType": { + "javaType": "RegistrationStatusEnum", + "type": "string", + "additionalProperties": false, + "enum": [ + "Accepted", + "Pending", + "Rejected" + ] + }, + "StatusInfoType": { + "javaType": "StatusInfo", + "type": "object", + "additionalProperties": false, + "properties": { + "customData": { + "$ref": "#/definitions/CustomDataType" + }, + "reasonCode": { + "type": "string", + "maxLength": 20 + }, + "additionalInfo": { + "type": "string", + "maxLength": 512 + } + }, + "required": [ + "reasonCode" + ] + } + }, + "type": "object", + "additionalProperties": false, + "properties": { + "customData": { + "$ref": "#/definitions/CustomDataType" + }, + "currentTime": { + "type": "string", + "format": "date-time" + }, + "interval": { + "type": "integer", + "minimum": -2147483648.0, + "maximum": 2147483647.0 + }, + "status": { + "$ref": "#/definitions/RegistrationStatusEnumType" + }, + "statusInfo": { + "$ref": "#/definitions/StatusInfoType" + } + }, + "required": [ + "currentTime", + "interval", + "status" + ] +} \ No newline at end of file diff --git a/ocpp/charge_point.py b/ocpp/charge_point.py index bdd75ae6e..02e867664 100644 --- a/ocpp/charge_point.py +++ b/ocpp/charge_point.py @@ -8,7 +8,7 @@ from typing import Dict, List, Union from ocpp.exceptions import NotSupportedError, OCPPError -from ocpp.messages import Call, MessageType, unpack, validate_payload +from ocpp.messages import Call, MessageType, SchemaValidator, unpack, validate_payload from ocpp.routing import create_route_map LOGGER = logging.getLogger("ocpp") @@ -85,7 +85,7 @@ class ChargePoint: initiated and received by the Central System """ - def __init__(self, id, connection, response_timeout=30): + def __init__(self, id, connection, validator: SchemaValidator, response_timeout=30): """ Args: @@ -98,6 +98,8 @@ def __init__(self, id, connection, response_timeout=30): """ self.id = id + self._validator = validator + # The maximum time in seconds it may take for a CP to respond to a # CALL. An asyncio.TimeoutError will be raised if this limit has been # exceeded. @@ -178,7 +180,7 @@ async def _handle_call(self, msg): ) if not handlers.get("_skip_schema_validation", False): - validate_payload(msg, self._ocpp_version) + validate_payload(msg, self._validator) # OCPP uses camelCase for the keys in the payload. It's more pythonic # to use snake_case for keyword arguments. Therefore the keys must be # 'translated'. Some examples: @@ -221,7 +223,7 @@ async def _handle_call(self, msg): response = msg.create_call_result(camel_case_payload) if not handlers.get("_skip_schema_validation", False): - validate_payload(response, self._ocpp_version) + validate_payload(msg, self._validator) await self._send(response.to_json()) @@ -265,13 +267,21 @@ async def call(self, payload, suppress=True, unique_id=None): unique_id if unique_id is not None else str(self._unique_id_generator()) ) + action = payload.__class__.__name__ + + # The call and call_result classes of OCPP 1.6, 2.0 and 2.0.1 are suffixed with 'Payload'. + # E.g. call_result.BootNotificationPayload. The suffixed doesn't make much sense and is removed + # as of OCPP 2.1. + if payload.__class__.__name__.endswith("Payload"): + action = payload.__class__.__name__[:-7] + call = Call( unique_id=unique_id, - action=payload.__class__.__name__[:-7], + action=action, payload=remove_nones(camel_case_payload), ) - validate_payload(call, self._ocpp_version) + validate_payload(call, self._validator) # Use a lock to prevent make sure that only 1 message can be send at a # a time. @@ -294,7 +304,7 @@ async def call(self, payload, suppress=True, unique_id=None): raise response.to_exception() else: response.action = call.action - validate_payload(response, self._ocpp_version) + validate_payload(response, self._validator) snake_case_payload = camel_to_snake_case(response.payload) # Create the correct Payload instance based on the received payload. If diff --git a/ocpp/exceptions.py b/ocpp/exceptions.py index 6c570425f..181c88ee3 100644 --- a/ocpp/exceptions.py +++ b/ocpp/exceptions.py @@ -114,6 +114,20 @@ class ValidationError(Exception): pass +class SchemaNotFoundError(Exception): + path: str + + def __init__(self, path: str): + self.path = path + super().__init__() + + def __str__(self): + return f"{self.__class__.__name__}: no schema found at {self.path}" + + def __repr__(self): + return f"<{self.__class__.__name__} - path={self.path}" + + class UnknownCallErrorCodeError(Exception): """Raised when a CALLERROR is received with unknown error code.""" diff --git a/ocpp/messages.py b/ocpp/messages.py index c9ee1c73c..20b8533d2 100644 --- a/ocpp/messages.py +++ b/ocpp/messages.py @@ -2,15 +2,16 @@ also contain some helper functions for packing and unpacking messages. """ from __future__ import annotations +import pathlib import decimal import json import os from dataclasses import asdict, is_dataclass from typing import Callable, Dict, Union +import jsonschema from jsonschema import Draft4Validator from jsonschema import _validators as SchemaValidators -from jsonschema.exceptions import ValidationError as SchemaValidationError from ocpp.exceptions import ( FormatViolationError, @@ -21,6 +22,7 @@ TypeConstraintViolationError, UnknownCallErrorCodeError, ValidationError, + SchemaNotFoundError, ) _validators: Dict[str, Draft4Validator] = {} @@ -63,6 +65,63 @@ def default(self, obj): raise e +class SchemaValidator: + """ " `SchemaValidator` validates the payload of a Call or Callresult against the JSON + schema. + + >>> validator = Validator("ocpp/v201/schemas") + >>> validator.validate_call(action="Heartbeat", payload={}) + + `Validator` lazily loads the schemas. That means, only when one calls + `Validator.validate_call()` or `Validator.validate_call_result()` a schema is + loaded from disc. Because schemas are cached, every schema is only loaded once at maximum. + + """ + + def __init__(self, schemas_dir: str): + dir = pathlib.Path(schemas_dir).absolute() + if not dir.exists(): + raise ValidationError( + f"Failed to init `SchemaValidator`: the folder '{dir}' doesn't exists. Make sure to provide a path to the folder containing JSON schemas." + ) + if not dir.is_dir(): + raise ValidationError( + f"Failed to init `SchemaValidator`: '{dir}' is not a folder. Make sure to provide a path to a folder containing JSON schemas." + ) + + self.schemas_dir: pathlib.Path = dir + + def validate_call(self, action: str, payload): + """Validate the payload against a schema with filename '`action` + "Request"'.""" + validator = self._get_validator(f"{action}Request") + validator.validate(payload) + + def validate_call_result(self, action: str, payload): + """Validate the payload against a schema with filename '`action` + "Response"'.""" + validator = self._get_validator(f"{action}Response") + validator.validate(payload) + + def _get_validator(self, schema_name: str): + path = self.schemas_dir / f"{schema_name}.json" + + if str(path) in _validators: + return _validators[str(path)] + + if not path.exists(): + raise SchemaNotFoundError(str(path)) + + # The JSON schemas for OCPP 2.0 start with a byte order mark (BOM) + # character. If no encoding is given, reading the schema would fail with: + # + # Unexpected UTF-8 BOM (decode using utf-8-sig): + with path.open("r", encoding="utf-8-sig") as f: + data = f.read() + validator = Draft4Validator(json.loads(data, parse_float=decimal.Decimal)) + _validators[str(path)] = validator + + return _validators[str(path)] + + class MessageType: """Number identifying the different types of OCPP messages.""" @@ -170,7 +229,9 @@ def get_validator( return _validators[cache_key] -def validate_payload(message: Union[Call, CallResult], ocpp_version: str) -> None: +def validate_payload( + message: Union[Call, CallResult], schema_validator: SchemaValidator +): """Validate the payload of the message using JSON schemas.""" if type(message) not in [Call, CallResult]: raise ValidationError( @@ -178,54 +239,19 @@ def validate_payload(message: Union[Call, CallResult], ocpp_version: str) -> Non f"type. It's '{type(message)}', but it should " "be either 'Call' or 'CallResult'." ) - try: - # 3 OCPP 1.6 schedules have fields of type floats. The JSON schema - # defines a certain precision for these fields of 1 decimal. A value of - # 21.4 is valid, whereas a value if 4.11 is not. - # - # The problem is that Python's internal representation of 21.4 might - # have more than 1 decimal. It might be 21.399999999999995. This would - # make the validation fail, although the payload is correct. This is a - # known issue with jsonschemas, see: - # https://github.com/Julian/jsonschema/issues/247 - # - # This issue can be fixed by using a different parser for floats than - # the default one that is used. - # - # Both the schema and the payload must be parsed using the different - # parser for floats. - if ocpp_version == "1.6" and ( - ( - type(message) == Call - and message.action in ["SetChargingProfile", "RemoteStartTransaction"] - ) # noqa - or ( - type(message) == CallResult and message.action == "GetCompositeSchedule" - ) - ): - validator = get_validator( - message.message_type_id, - message.action, - ocpp_version, - parse_float=decimal.Decimal, - ) - - message.payload = json.loads( - json.dumps(message.payload), parse_float=decimal.Decimal - ) - else: - validator = get_validator( - message.message_type_id, message.action, ocpp_version - ) + if message.message_type_id == MessageType.Call: + schema_validator.validate_call(message.action, message.payload) + elif message.message_type_id == MessageType.CallResult: + schema_validator.validate_call_result(message.action, message.payload) except (OSError, json.JSONDecodeError): raise NotImplementedError( details={"cause": f"Failed to validate action: {message.action}"} ) + except SchemaNotFoundError as e: + raise NotImplementedError() - try: - validator.validate(message.payload) - except SchemaValidationError as e: + except jsonschema.exceptions.ValidationError as e: if e.validator == SchemaValidators.type.__name__: raise TypeConstraintViolationError( details={"cause": e.message, "ocpp_message": message} diff --git a/ocpp/v16/__init__.py b/ocpp/v16/__init__.py index 17cb36158..24bdf8e40 100644 --- a/ocpp/v16/__init__.py +++ b/ocpp/v16/__init__.py @@ -1,8 +1,49 @@ +import decimal +import json +import pathlib + from ocpp.charge_point import ChargePoint as cp +from ocpp.messages import SchemaValidator as sv from ocpp.v16 import call, call_result +class SchemaValidator(sv): + # Three OCPP 1.6 schedules have fields of type floats. The JSON schema + # defines a precision of 1 decimal for these fields. A value of + # 21.4 is valid, whereas a value if 4.11 is not. + # + # The problem is that Python's internal representation of 21.4 might + # have more than 1 decimal. It might be 21.399999999999995. This would + # make the validation fail, although the payload is correct. This is a + # known issue with jsonschemas, see: + # https://github.com/Julian/jsonschema/issues/247 + # + # This issue can be fixed by using a different parser for floats than + # the default one that is used. + # + # Both the schema and the payload must be parsed using the different + # parser for floats. + def validate_call(self, action: str, payload): + if action in ["SetChargingProfile", "RemoteStartTransaction"]: + payload = json.loads(json.dumps(payload), parse_float=decimal.Decimal) + + super().validate_call(action, payload) + + def validate_call_result(self, action: str, payload): + if action == "GetCompositeSchedule": + payload = json.loads(json.dumps(payload), parse_float=decimal.Decimal) + + super().validate_call_result(action, payload) + + +_schemas_dir = pathlib.Path(__file__).parent.joinpath("schemas").resolve() +validator = SchemaValidator(str(_schemas_dir)) + + class ChargePoint(cp): _call = call _call_result = call_result _ocpp_version = "1.6" + + def __init__(self, validator: SchemaValidator = validator, *args, **kwargs): + super().__init__(validator=validator, *args, **kwargs) diff --git a/ocpp/v16/schemas/Authorize.json b/ocpp/v16/schemas/AuthorizeRequest.json similarity index 100% rename from ocpp/v16/schemas/Authorize.json rename to ocpp/v16/schemas/AuthorizeRequest.json diff --git a/ocpp/v16/schemas/BootNotification.json b/ocpp/v16/schemas/BootNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/BootNotification.json rename to ocpp/v16/schemas/BootNotificationRequest.json diff --git a/ocpp/v16/schemas/CancelReservation.json b/ocpp/v16/schemas/CancelReservationRequest.json similarity index 100% rename from ocpp/v16/schemas/CancelReservation.json rename to ocpp/v16/schemas/CancelReservationRequest.json diff --git a/ocpp/v16/schemas/CertificateSigned.json b/ocpp/v16/schemas/CertificateSignedRequest.json similarity index 100% rename from ocpp/v16/schemas/CertificateSigned.json rename to ocpp/v16/schemas/CertificateSignedRequest.json diff --git a/ocpp/v16/schemas/ChangeAvailability.json b/ocpp/v16/schemas/ChangeAvailabilityRequest.json similarity index 100% rename from ocpp/v16/schemas/ChangeAvailability.json rename to ocpp/v16/schemas/ChangeAvailabilityRequest.json diff --git a/ocpp/v16/schemas/ChangeConfiguration.json b/ocpp/v16/schemas/ChangeConfigurationRequest.json similarity index 100% rename from ocpp/v16/schemas/ChangeConfiguration.json rename to ocpp/v16/schemas/ChangeConfigurationRequest.json diff --git a/ocpp/v16/schemas/ClearCache.json b/ocpp/v16/schemas/ClearCacheRequest.json similarity index 100% rename from ocpp/v16/schemas/ClearCache.json rename to ocpp/v16/schemas/ClearCacheRequest.json diff --git a/ocpp/v16/schemas/ClearChargingProfile.json b/ocpp/v16/schemas/ClearChargingProfileRequest.json similarity index 100% rename from ocpp/v16/schemas/ClearChargingProfile.json rename to ocpp/v16/schemas/ClearChargingProfileRequest.json diff --git a/ocpp/v16/schemas/DataTransfer.json b/ocpp/v16/schemas/DataTransferRequest.json similarity index 100% rename from ocpp/v16/schemas/DataTransfer.json rename to ocpp/v16/schemas/DataTransferRequest.json diff --git a/ocpp/v16/schemas/DeleteCertificate.json b/ocpp/v16/schemas/DeleteCertificateRequest.json similarity index 100% rename from ocpp/v16/schemas/DeleteCertificate.json rename to ocpp/v16/schemas/DeleteCertificateRequest.json diff --git a/ocpp/v16/schemas/DiagnosticsStatusNotification.json b/ocpp/v16/schemas/DiagnosticsStatusNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/DiagnosticsStatusNotification.json rename to ocpp/v16/schemas/DiagnosticsStatusNotificationRequest.json diff --git a/ocpp/v16/schemas/ExtendedTriggerMessage.json b/ocpp/v16/schemas/ExtendedTriggerMessageRequest.json similarity index 100% rename from ocpp/v16/schemas/ExtendedTriggerMessage.json rename to ocpp/v16/schemas/ExtendedTriggerMessageRequest.json diff --git a/ocpp/v16/schemas/FirmwareStatusNotification.json b/ocpp/v16/schemas/FirmwareStatusNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/FirmwareStatusNotification.json rename to ocpp/v16/schemas/FirmwareStatusNotificationRequest.json diff --git a/ocpp/v16/schemas/GetCompositeSchedule.json b/ocpp/v16/schemas/GetCompositeScheduleRequest.json similarity index 100% rename from ocpp/v16/schemas/GetCompositeSchedule.json rename to ocpp/v16/schemas/GetCompositeScheduleRequest.json diff --git a/ocpp/v16/schemas/GetConfiguration.json b/ocpp/v16/schemas/GetConfigurationRequest.json similarity index 100% rename from ocpp/v16/schemas/GetConfiguration.json rename to ocpp/v16/schemas/GetConfigurationRequest.json diff --git a/ocpp/v16/schemas/GetDiagnostics.json b/ocpp/v16/schemas/GetDiagnosticsRequest.json similarity index 100% rename from ocpp/v16/schemas/GetDiagnostics.json rename to ocpp/v16/schemas/GetDiagnosticsRequest.json diff --git a/ocpp/v16/schemas/GetInstalledCertificateIds.json b/ocpp/v16/schemas/GetInstalledCertificateIdsRequest.json similarity index 100% rename from ocpp/v16/schemas/GetInstalledCertificateIds.json rename to ocpp/v16/schemas/GetInstalledCertificateIdsRequest.json diff --git a/ocpp/v16/schemas/GetLocalListVersion.json b/ocpp/v16/schemas/GetLocalListVersionRequest.json similarity index 100% rename from ocpp/v16/schemas/GetLocalListVersion.json rename to ocpp/v16/schemas/GetLocalListVersionRequest.json diff --git a/ocpp/v16/schemas/GetLog.json b/ocpp/v16/schemas/GetLogRequest.json similarity index 100% rename from ocpp/v16/schemas/GetLog.json rename to ocpp/v16/schemas/GetLogRequest.json diff --git a/ocpp/v16/schemas/Heartbeat.json b/ocpp/v16/schemas/HeartbeatRequest.json similarity index 100% rename from ocpp/v16/schemas/Heartbeat.json rename to ocpp/v16/schemas/HeartbeatRequest.json diff --git a/ocpp/v16/schemas/InstallCertificate.json b/ocpp/v16/schemas/InstallCertificateRequest.json similarity index 100% rename from ocpp/v16/schemas/InstallCertificate.json rename to ocpp/v16/schemas/InstallCertificateRequest.json diff --git a/ocpp/v16/schemas/LogStatusNotification.json b/ocpp/v16/schemas/LogStatusNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/LogStatusNotification.json rename to ocpp/v16/schemas/LogStatusNotificationRequest.json diff --git a/ocpp/v16/schemas/MeterValues.json b/ocpp/v16/schemas/MeterValuesRequest.json similarity index 100% rename from ocpp/v16/schemas/MeterValues.json rename to ocpp/v16/schemas/MeterValuesRequest.json diff --git a/ocpp/v16/schemas/RemoteStartTransaction.json b/ocpp/v16/schemas/RemoteStartTransactionRequest.json similarity index 100% rename from ocpp/v16/schemas/RemoteStartTransaction.json rename to ocpp/v16/schemas/RemoteStartTransactionRequest.json diff --git a/ocpp/v16/schemas/RemoteStopTransaction.json b/ocpp/v16/schemas/RemoteStopTransactionRequest.json similarity index 100% rename from ocpp/v16/schemas/RemoteStopTransaction.json rename to ocpp/v16/schemas/RemoteStopTransactionRequest.json diff --git a/ocpp/v16/schemas/ReserveNow.json b/ocpp/v16/schemas/ReserveNowRequest.json similarity index 100% rename from ocpp/v16/schemas/ReserveNow.json rename to ocpp/v16/schemas/ReserveNowRequest.json diff --git a/ocpp/v16/schemas/Reset.json b/ocpp/v16/schemas/ResetRequest.json similarity index 100% rename from ocpp/v16/schemas/Reset.json rename to ocpp/v16/schemas/ResetRequest.json diff --git a/ocpp/v16/schemas/SecurityEventNotification.json b/ocpp/v16/schemas/SecurityEventNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/SecurityEventNotification.json rename to ocpp/v16/schemas/SecurityEventNotificationRequest.json diff --git a/ocpp/v16/schemas/SendLocalList.json b/ocpp/v16/schemas/SendLocalListRequest.json similarity index 100% rename from ocpp/v16/schemas/SendLocalList.json rename to ocpp/v16/schemas/SendLocalListRequest.json diff --git a/ocpp/v16/schemas/SetChargingProfile.json b/ocpp/v16/schemas/SetChargingProfileRequest.json similarity index 100% rename from ocpp/v16/schemas/SetChargingProfile.json rename to ocpp/v16/schemas/SetChargingProfileRequest.json diff --git a/ocpp/v16/schemas/SignCertificate.json b/ocpp/v16/schemas/SignCertificateRequest.json similarity index 100% rename from ocpp/v16/schemas/SignCertificate.json rename to ocpp/v16/schemas/SignCertificateRequest.json diff --git a/ocpp/v16/schemas/SignedFirmwareStatusNotification.json b/ocpp/v16/schemas/SignedFirmwareStatusNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/SignedFirmwareStatusNotification.json rename to ocpp/v16/schemas/SignedFirmwareStatusNotificationRequest.json diff --git a/ocpp/v16/schemas/SignedUpdateFirmware.json b/ocpp/v16/schemas/SignedUpdateFirmwareRequest.json similarity index 100% rename from ocpp/v16/schemas/SignedUpdateFirmware.json rename to ocpp/v16/schemas/SignedUpdateFirmwareRequest.json diff --git a/ocpp/v16/schemas/StartTransaction.json b/ocpp/v16/schemas/StartTransactionRequest.json similarity index 100% rename from ocpp/v16/schemas/StartTransaction.json rename to ocpp/v16/schemas/StartTransactionRequest.json diff --git a/ocpp/v16/schemas/StatusNotification.json b/ocpp/v16/schemas/StatusNotificationRequest.json similarity index 100% rename from ocpp/v16/schemas/StatusNotification.json rename to ocpp/v16/schemas/StatusNotificationRequest.json diff --git a/ocpp/v16/schemas/StopTransaction.json b/ocpp/v16/schemas/StopTransactionRequest.json similarity index 100% rename from ocpp/v16/schemas/StopTransaction.json rename to ocpp/v16/schemas/StopTransactionRequest.json diff --git a/ocpp/v16/schemas/TriggerMessage.json b/ocpp/v16/schemas/TriggerMessageRequest.json similarity index 100% rename from ocpp/v16/schemas/TriggerMessage.json rename to ocpp/v16/schemas/TriggerMessageRequest.json diff --git a/ocpp/v16/schemas/UnlockConnector.json b/ocpp/v16/schemas/UnlockConnectorRequest.json similarity index 100% rename from ocpp/v16/schemas/UnlockConnector.json rename to ocpp/v16/schemas/UnlockConnectorRequest.json diff --git a/ocpp/v16/schemas/UpdateFirmware.json b/ocpp/v16/schemas/UpdateFirmwareRequest.json similarity index 100% rename from ocpp/v16/schemas/UpdateFirmware.json rename to ocpp/v16/schemas/UpdateFirmwareRequest.json diff --git a/ocpp/v20/__init__.py b/ocpp/v20/__init__.py index f054fc49f..6c243bbed 100644 --- a/ocpp/v20/__init__.py +++ b/ocpp/v20/__init__.py @@ -1,8 +1,17 @@ +import pathlib + from ocpp.charge_point import ChargePoint as cp +from ocpp.messages import SchemaValidator from ocpp.v20 import call, call_result +_schemas_dir = pathlib.Path(__file__).parent.joinpath("schemas").resolve() +validator = SchemaValidator(str(_schemas_dir)) + class ChargePoint(cp): _call = call _call_result = call_result _ocpp_version = "2.0" + + def __init__(self, validator: SchemaValidator = validator, *args, **kwargs): + super().__init__(validator=validator, *args, **kwargs) diff --git a/ocpp/v20/schemas/AuthorizeRequest_v1p0.json b/ocpp/v20/schemas/AuthorizeRequest.json similarity index 100% rename from ocpp/v20/schemas/AuthorizeRequest_v1p0.json rename to ocpp/v20/schemas/AuthorizeRequest.json diff --git a/ocpp/v20/schemas/AuthorizeResponse_v1p0.json b/ocpp/v20/schemas/AuthorizeResponse.json similarity index 100% rename from ocpp/v20/schemas/AuthorizeResponse_v1p0.json rename to ocpp/v20/schemas/AuthorizeResponse.json diff --git a/ocpp/v20/schemas/BootNotificationRequest_v1p0.json b/ocpp/v20/schemas/BootNotificationRequest.json similarity index 100% rename from ocpp/v20/schemas/BootNotificationRequest_v1p0.json rename to ocpp/v20/schemas/BootNotificationRequest.json diff --git a/ocpp/v20/schemas/BootNotificationResponse_v1p0.json b/ocpp/v20/schemas/BootNotificationResponse.json similarity index 100% rename from ocpp/v20/schemas/BootNotificationResponse_v1p0.json rename to ocpp/v20/schemas/BootNotificationResponse.json diff --git a/ocpp/v20/schemas/CancelReservationRequest_v1p0.json b/ocpp/v20/schemas/CancelReservationRequest.json similarity index 100% rename from ocpp/v20/schemas/CancelReservationRequest_v1p0.json rename to ocpp/v20/schemas/CancelReservationRequest.json diff --git a/ocpp/v20/schemas/CancelReservationResponse_v1p0.json b/ocpp/v20/schemas/CancelReservationResponse.json similarity index 100% rename from ocpp/v20/schemas/CancelReservationResponse_v1p0.json rename to ocpp/v20/schemas/CancelReservationResponse.json diff --git a/ocpp/v20/schemas/CertificateSignedRequest_v1p0.json b/ocpp/v20/schemas/CertificateSignedRequest.json similarity index 100% rename from ocpp/v20/schemas/CertificateSignedRequest_v1p0.json rename to ocpp/v20/schemas/CertificateSignedRequest.json diff --git a/ocpp/v20/schemas/CertificateSignedResponse_v1p0.json b/ocpp/v20/schemas/CertificateSignedResponse.json similarity index 100% rename from ocpp/v20/schemas/CertificateSignedResponse_v1p0.json rename to ocpp/v20/schemas/CertificateSignedResponse.json diff --git a/ocpp/v20/schemas/ChangeAvailabilityRequest_v1p0.json b/ocpp/v20/schemas/ChangeAvailabilityRequest.json similarity index 100% rename from ocpp/v20/schemas/ChangeAvailabilityRequest_v1p0.json rename to ocpp/v20/schemas/ChangeAvailabilityRequest.json diff --git a/ocpp/v20/schemas/ChangeAvailabilityResponse_v1p0.json b/ocpp/v20/schemas/ChangeAvailabilityResponse.json similarity index 100% rename from ocpp/v20/schemas/ChangeAvailabilityResponse_v1p0.json rename to ocpp/v20/schemas/ChangeAvailabilityResponse.json diff --git a/ocpp/v20/schemas/ClearCacheRequest_v1p0.json b/ocpp/v20/schemas/ClearCacheRequest.json similarity index 100% rename from ocpp/v20/schemas/ClearCacheRequest_v1p0.json rename to ocpp/v20/schemas/ClearCacheRequest.json diff --git a/ocpp/v20/schemas/ClearCacheResponse_v1p0.json b/ocpp/v20/schemas/ClearCacheResponse.json similarity index 100% rename from ocpp/v20/schemas/ClearCacheResponse_v1p0.json rename to ocpp/v20/schemas/ClearCacheResponse.json diff --git a/ocpp/v20/schemas/ClearChargingProfileRequest_v1p0.json b/ocpp/v20/schemas/ClearChargingProfileRequest.json similarity index 100% rename from ocpp/v20/schemas/ClearChargingProfileRequest_v1p0.json rename to ocpp/v20/schemas/ClearChargingProfileRequest.json diff --git a/ocpp/v20/schemas/ClearChargingProfileResponse_v1p0.json b/ocpp/v20/schemas/ClearChargingProfileResponse.json similarity index 100% rename from ocpp/v20/schemas/ClearChargingProfileResponse_v1p0.json rename to ocpp/v20/schemas/ClearChargingProfileResponse.json diff --git a/ocpp/v20/schemas/ClearDisplayMessageRequest_v1p0.json b/ocpp/v20/schemas/ClearDisplayMessageRequest.json similarity index 100% rename from ocpp/v20/schemas/ClearDisplayMessageRequest_v1p0.json rename to ocpp/v20/schemas/ClearDisplayMessageRequest.json diff --git a/ocpp/v20/schemas/ClearDisplayMessageResponse_v1p0.json b/ocpp/v20/schemas/ClearDisplayMessageResponse.json similarity index 100% rename from ocpp/v20/schemas/ClearDisplayMessageResponse_v1p0.json rename to ocpp/v20/schemas/ClearDisplayMessageResponse.json diff --git a/ocpp/v20/schemas/ClearVariableMonitoringRequest_v1p0.json b/ocpp/v20/schemas/ClearVariableMonitoringRequest.json similarity index 100% rename from ocpp/v20/schemas/ClearVariableMonitoringRequest_v1p0.json rename to ocpp/v20/schemas/ClearVariableMonitoringRequest.json diff --git a/ocpp/v20/schemas/ClearVariableMonitoringResponse_v1p0.json b/ocpp/v20/schemas/ClearVariableMonitoringResponse.json similarity index 100% rename from ocpp/v20/schemas/ClearVariableMonitoringResponse_v1p0.json rename to ocpp/v20/schemas/ClearVariableMonitoringResponse.json diff --git a/ocpp/v20/schemas/ClearedChargingLimitRequest_v1p0.json b/ocpp/v20/schemas/ClearedChargingLimitRequest.json similarity index 100% rename from ocpp/v20/schemas/ClearedChargingLimitRequest_v1p0.json rename to ocpp/v20/schemas/ClearedChargingLimitRequest.json diff --git a/ocpp/v20/schemas/ClearedChargingLimitResponse_v1p0.json b/ocpp/v20/schemas/ClearedChargingLimitResponse.json similarity index 100% rename from ocpp/v20/schemas/ClearedChargingLimitResponse_v1p0.json rename to ocpp/v20/schemas/ClearedChargingLimitResponse.json diff --git a/ocpp/v20/schemas/CostUpdatedRequest_v1p0.json b/ocpp/v20/schemas/CostUpdatedRequest.json similarity index 100% rename from ocpp/v20/schemas/CostUpdatedRequest_v1p0.json rename to ocpp/v20/schemas/CostUpdatedRequest.json diff --git a/ocpp/v20/schemas/CostUpdatedResponse_v1p0.json b/ocpp/v20/schemas/CostUpdatedResponse.json similarity index 100% rename from ocpp/v20/schemas/CostUpdatedResponse_v1p0.json rename to ocpp/v20/schemas/CostUpdatedResponse.json diff --git a/ocpp/v20/schemas/CustomerInformationRequest_v1p0.json b/ocpp/v20/schemas/CustomerInformationRequest.json similarity index 100% rename from ocpp/v20/schemas/CustomerInformationRequest_v1p0.json rename to ocpp/v20/schemas/CustomerInformationRequest.json diff --git a/ocpp/v20/schemas/CustomerInformationResponse_v1p0.json b/ocpp/v20/schemas/CustomerInformationResponse.json similarity index 100% rename from ocpp/v20/schemas/CustomerInformationResponse_v1p0.json rename to ocpp/v20/schemas/CustomerInformationResponse.json diff --git a/ocpp/v20/schemas/DataTransferRequest_v1p0.json b/ocpp/v20/schemas/DataTransferRequest.json similarity index 100% rename from ocpp/v20/schemas/DataTransferRequest_v1p0.json rename to ocpp/v20/schemas/DataTransferRequest.json diff --git a/ocpp/v20/schemas/DataTransferResponse_v1p0.json b/ocpp/v20/schemas/DataTransferResponse.json similarity index 100% rename from ocpp/v20/schemas/DataTransferResponse_v1p0.json rename to ocpp/v20/schemas/DataTransferResponse.json diff --git a/ocpp/v20/schemas/DeleteCertificateRequest_v1p0.json b/ocpp/v20/schemas/DeleteCertificateRequest.json similarity index 100% rename from ocpp/v20/schemas/DeleteCertificateRequest_v1p0.json rename to ocpp/v20/schemas/DeleteCertificateRequest.json diff --git a/ocpp/v20/schemas/DeleteCertificateResponse_v1p0.json b/ocpp/v20/schemas/DeleteCertificateResponse.json similarity index 100% rename from ocpp/v20/schemas/DeleteCertificateResponse_v1p0.json rename to ocpp/v20/schemas/DeleteCertificateResponse.json diff --git a/ocpp/v20/schemas/FirmwareStatusNotificationRequest_v1p0.json b/ocpp/v20/schemas/FirmwareStatusNotificationRequest.json similarity index 100% rename from ocpp/v20/schemas/FirmwareStatusNotificationRequest_v1p0.json rename to ocpp/v20/schemas/FirmwareStatusNotificationRequest.json diff --git a/ocpp/v20/schemas/FirmwareStatusNotificationResponse_v1p0.json b/ocpp/v20/schemas/FirmwareStatusNotificationResponse.json similarity index 100% rename from ocpp/v20/schemas/FirmwareStatusNotificationResponse_v1p0.json rename to ocpp/v20/schemas/FirmwareStatusNotificationResponse.json diff --git a/ocpp/v20/schemas/Get15118EVCertificateRequest_v1p0.json b/ocpp/v20/schemas/Get15118EVCertificateRequest.json similarity index 100% rename from ocpp/v20/schemas/Get15118EVCertificateRequest_v1p0.json rename to ocpp/v20/schemas/Get15118EVCertificateRequest.json diff --git a/ocpp/v20/schemas/Get15118EVCertificateResponse_v1p0.json b/ocpp/v20/schemas/Get15118EVCertificateResponse.json similarity index 100% rename from ocpp/v20/schemas/Get15118EVCertificateResponse_v1p0.json rename to ocpp/v20/schemas/Get15118EVCertificateResponse.json diff --git a/ocpp/v20/schemas/GetBaseReportRequest_v1p0.json b/ocpp/v20/schemas/GetBaseReportRequest.json similarity index 100% rename from ocpp/v20/schemas/GetBaseReportRequest_v1p0.json rename to ocpp/v20/schemas/GetBaseReportRequest.json diff --git a/ocpp/v20/schemas/GetBaseReportResponse_v1p0.json b/ocpp/v20/schemas/GetBaseReportResponse.json similarity index 100% rename from ocpp/v20/schemas/GetBaseReportResponse_v1p0.json rename to ocpp/v20/schemas/GetBaseReportResponse.json diff --git a/ocpp/v20/schemas/GetCertificateStatusRequest_v1p0.json b/ocpp/v20/schemas/GetCertificateStatusRequest.json similarity index 100% rename from ocpp/v20/schemas/GetCertificateStatusRequest_v1p0.json rename to ocpp/v20/schemas/GetCertificateStatusRequest.json diff --git a/ocpp/v20/schemas/GetCertificateStatusResponse_v1p0.json b/ocpp/v20/schemas/GetCertificateStatusResponse.json similarity index 100% rename from ocpp/v20/schemas/GetCertificateStatusResponse_v1p0.json rename to ocpp/v20/schemas/GetCertificateStatusResponse.json diff --git a/ocpp/v20/schemas/GetChargingProfilesRequest_v1p0.json b/ocpp/v20/schemas/GetChargingProfilesRequest.json similarity index 100% rename from ocpp/v20/schemas/GetChargingProfilesRequest_v1p0.json rename to ocpp/v20/schemas/GetChargingProfilesRequest.json diff --git a/ocpp/v20/schemas/GetChargingProfilesResponse_v1p0.json b/ocpp/v20/schemas/GetChargingProfilesResponse.json similarity index 100% rename from ocpp/v20/schemas/GetChargingProfilesResponse_v1p0.json rename to ocpp/v20/schemas/GetChargingProfilesResponse.json diff --git a/ocpp/v20/schemas/GetCompositeScheduleRequest_v1p0.json b/ocpp/v20/schemas/GetCompositeScheduleRequest.json similarity index 100% rename from ocpp/v20/schemas/GetCompositeScheduleRequest_v1p0.json rename to ocpp/v20/schemas/GetCompositeScheduleRequest.json diff --git a/ocpp/v20/schemas/GetCompositeScheduleResponse_v1p0.json b/ocpp/v20/schemas/GetCompositeScheduleResponse.json similarity index 100% rename from ocpp/v20/schemas/GetCompositeScheduleResponse_v1p0.json rename to ocpp/v20/schemas/GetCompositeScheduleResponse.json diff --git a/ocpp/v20/schemas/GetDisplayMessagesRequest_v1p0.json b/ocpp/v20/schemas/GetDisplayMessagesRequest.json similarity index 100% rename from ocpp/v20/schemas/GetDisplayMessagesRequest_v1p0.json rename to ocpp/v20/schemas/GetDisplayMessagesRequest.json diff --git a/ocpp/v20/schemas/GetDisplayMessagesResponse_v1p0.json b/ocpp/v20/schemas/GetDisplayMessagesResponse.json similarity index 100% rename from ocpp/v20/schemas/GetDisplayMessagesResponse_v1p0.json rename to ocpp/v20/schemas/GetDisplayMessagesResponse.json diff --git a/ocpp/v20/schemas/GetInstalledCertificateIdsRequest_v1p0.json b/ocpp/v20/schemas/GetInstalledCertificateIdsRequest.json similarity index 100% rename from ocpp/v20/schemas/GetInstalledCertificateIdsRequest_v1p0.json rename to ocpp/v20/schemas/GetInstalledCertificateIdsRequest.json diff --git a/ocpp/v20/schemas/GetInstalledCertificateIdsResponse_v1p0.json b/ocpp/v20/schemas/GetInstalledCertificateIdsResponse.json similarity index 100% rename from ocpp/v20/schemas/GetInstalledCertificateIdsResponse_v1p0.json rename to ocpp/v20/schemas/GetInstalledCertificateIdsResponse.json diff --git a/ocpp/v20/schemas/GetLocalListVersionRequest_v1p0.json b/ocpp/v20/schemas/GetLocalListVersionRequest.json similarity index 100% rename from ocpp/v20/schemas/GetLocalListVersionRequest_v1p0.json rename to ocpp/v20/schemas/GetLocalListVersionRequest.json diff --git a/ocpp/v20/schemas/GetLocalListVersionResponse_v1p0.json b/ocpp/v20/schemas/GetLocalListVersionResponse.json similarity index 100% rename from ocpp/v20/schemas/GetLocalListVersionResponse_v1p0.json rename to ocpp/v20/schemas/GetLocalListVersionResponse.json diff --git a/ocpp/v20/schemas/GetLogRequest_v1p0.json b/ocpp/v20/schemas/GetLogRequest.json similarity index 100% rename from ocpp/v20/schemas/GetLogRequest_v1p0.json rename to ocpp/v20/schemas/GetLogRequest.json diff --git a/ocpp/v20/schemas/GetLogResponse_v1p0.json b/ocpp/v20/schemas/GetLogResponse.json similarity index 100% rename from ocpp/v20/schemas/GetLogResponse_v1p0.json rename to ocpp/v20/schemas/GetLogResponse.json diff --git a/ocpp/v20/schemas/GetMonitoringReportRequest_v1p0.json b/ocpp/v20/schemas/GetMonitoringReportRequest.json similarity index 100% rename from ocpp/v20/schemas/GetMonitoringReportRequest_v1p0.json rename to ocpp/v20/schemas/GetMonitoringReportRequest.json diff --git a/ocpp/v20/schemas/GetMonitoringReportResponse_v1p0.json b/ocpp/v20/schemas/GetMonitoringReportResponse.json similarity index 100% rename from ocpp/v20/schemas/GetMonitoringReportResponse_v1p0.json rename to ocpp/v20/schemas/GetMonitoringReportResponse.json diff --git a/ocpp/v20/schemas/GetReportRequest_v1p0.json b/ocpp/v20/schemas/GetReportRequest.json similarity index 100% rename from ocpp/v20/schemas/GetReportRequest_v1p0.json rename to ocpp/v20/schemas/GetReportRequest.json diff --git a/ocpp/v20/schemas/GetReportResponse_v1p0.json b/ocpp/v20/schemas/GetReportResponse.json similarity index 100% rename from ocpp/v20/schemas/GetReportResponse_v1p0.json rename to ocpp/v20/schemas/GetReportResponse.json diff --git a/ocpp/v20/schemas/GetTransactionStatusRequest_v1p0.json b/ocpp/v20/schemas/GetTransactionStatusRequest.json similarity index 100% rename from ocpp/v20/schemas/GetTransactionStatusRequest_v1p0.json rename to ocpp/v20/schemas/GetTransactionStatusRequest.json diff --git a/ocpp/v20/schemas/GetTransactionStatusResponse_v1p0.json b/ocpp/v20/schemas/GetTransactionStatusResponse.json similarity index 100% rename from ocpp/v20/schemas/GetTransactionStatusResponse_v1p0.json rename to ocpp/v20/schemas/GetTransactionStatusResponse.json diff --git a/ocpp/v20/schemas/GetVariablesRequest_v1p0.json b/ocpp/v20/schemas/GetVariablesRequest.json similarity index 100% rename from ocpp/v20/schemas/GetVariablesRequest_v1p0.json rename to ocpp/v20/schemas/GetVariablesRequest.json diff --git a/ocpp/v20/schemas/GetVariablesResponse_v1p0.json b/ocpp/v20/schemas/GetVariablesResponse.json similarity index 100% rename from ocpp/v20/schemas/GetVariablesResponse_v1p0.json rename to ocpp/v20/schemas/GetVariablesResponse.json diff --git a/ocpp/v20/schemas/HeartbeatRequest_v1p0.json b/ocpp/v20/schemas/HeartbeatRequest.json similarity index 100% rename from ocpp/v20/schemas/HeartbeatRequest_v1p0.json rename to ocpp/v20/schemas/HeartbeatRequest.json diff --git a/ocpp/v20/schemas/HeartbeatResponse_v1p0.json b/ocpp/v20/schemas/HeartbeatResponse.json similarity index 100% rename from ocpp/v20/schemas/HeartbeatResponse_v1p0.json rename to ocpp/v20/schemas/HeartbeatResponse.json diff --git a/ocpp/v20/schemas/InstallCertificateRequest_v1p0.json b/ocpp/v20/schemas/InstallCertificateRequest.json similarity index 100% rename from ocpp/v20/schemas/InstallCertificateRequest_v1p0.json rename to ocpp/v20/schemas/InstallCertificateRequest.json diff --git a/ocpp/v20/schemas/InstallCertificateResponse_v1p0.json b/ocpp/v20/schemas/InstallCertificateResponse.json similarity index 100% rename from ocpp/v20/schemas/InstallCertificateResponse_v1p0.json rename to ocpp/v20/schemas/InstallCertificateResponse.json diff --git a/ocpp/v20/schemas/LogStatusNotificationRequest_v1p0.json b/ocpp/v20/schemas/LogStatusNotificationRequest.json similarity index 100% rename from ocpp/v20/schemas/LogStatusNotificationRequest_v1p0.json rename to ocpp/v20/schemas/LogStatusNotificationRequest.json diff --git a/ocpp/v20/schemas/LogStatusNotificationResponse_v1p0.json b/ocpp/v20/schemas/LogStatusNotificationResponse.json similarity index 100% rename from ocpp/v20/schemas/LogStatusNotificationResponse_v1p0.json rename to ocpp/v20/schemas/LogStatusNotificationResponse.json diff --git a/ocpp/v20/schemas/MeterValuesRequest_v1p0.json b/ocpp/v20/schemas/MeterValuesRequest.json similarity index 100% rename from ocpp/v20/schemas/MeterValuesRequest_v1p0.json rename to ocpp/v20/schemas/MeterValuesRequest.json diff --git a/ocpp/v20/schemas/MeterValuesResponse_v1p0.json b/ocpp/v20/schemas/MeterValuesResponse.json similarity index 100% rename from ocpp/v20/schemas/MeterValuesResponse_v1p0.json rename to ocpp/v20/schemas/MeterValuesResponse.json diff --git a/ocpp/v20/schemas/NotifyCentralChargingNeedsRequest_v1p0.json b/ocpp/v20/schemas/NotifyCentralChargingNeedsRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyCentralChargingNeedsRequest_v1p0.json rename to ocpp/v20/schemas/NotifyCentralChargingNeedsRequest.json diff --git a/ocpp/v20/schemas/NotifyCentralChargingNeedsResponse_v1p0.json b/ocpp/v20/schemas/NotifyCentralChargingNeedsResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyCentralChargingNeedsResponse_v1p0.json rename to ocpp/v20/schemas/NotifyCentralChargingNeedsResponse.json diff --git a/ocpp/v20/schemas/NotifyChargingLimitRequest_v1p0.json b/ocpp/v20/schemas/NotifyChargingLimitRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyChargingLimitRequest_v1p0.json rename to ocpp/v20/schemas/NotifyChargingLimitRequest.json diff --git a/ocpp/v20/schemas/NotifyChargingLimitResponse_v1p0.json b/ocpp/v20/schemas/NotifyChargingLimitResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyChargingLimitResponse_v1p0.json rename to ocpp/v20/schemas/NotifyChargingLimitResponse.json diff --git a/ocpp/v20/schemas/NotifyCustomerInformationRequest_v1p0.json b/ocpp/v20/schemas/NotifyCustomerInformationRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyCustomerInformationRequest_v1p0.json rename to ocpp/v20/schemas/NotifyCustomerInformationRequest.json diff --git a/ocpp/v20/schemas/NotifyCustomerInformationResponse_v1p0.json b/ocpp/v20/schemas/NotifyCustomerInformationResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyCustomerInformationResponse_v1p0.json rename to ocpp/v20/schemas/NotifyCustomerInformationResponse.json diff --git a/ocpp/v20/schemas/NotifyDisplayMessagesRequest_v1p0.json b/ocpp/v20/schemas/NotifyDisplayMessagesRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyDisplayMessagesRequest_v1p0.json rename to ocpp/v20/schemas/NotifyDisplayMessagesRequest.json diff --git a/ocpp/v20/schemas/NotifyDisplayMessagesResponse_v1p0.json b/ocpp/v20/schemas/NotifyDisplayMessagesResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyDisplayMessagesResponse_v1p0.json rename to ocpp/v20/schemas/NotifyDisplayMessagesResponse.json diff --git a/ocpp/v20/schemas/NotifyEVChargingNeedsRequest_v1p0.json b/ocpp/v20/schemas/NotifyEVChargingNeedsRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyEVChargingNeedsRequest_v1p0.json rename to ocpp/v20/schemas/NotifyEVChargingNeedsRequest.json diff --git a/ocpp/v20/schemas/NotifyEVChargingNeedsResponse_v1p0.json b/ocpp/v20/schemas/NotifyEVChargingNeedsResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyEVChargingNeedsResponse_v1p0.json rename to ocpp/v20/schemas/NotifyEVChargingNeedsResponse.json diff --git a/ocpp/v20/schemas/NotifyEVChargingScheduleRequest_v1p0.json b/ocpp/v20/schemas/NotifyEVChargingScheduleRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyEVChargingScheduleRequest_v1p0.json rename to ocpp/v20/schemas/NotifyEVChargingScheduleRequest.json diff --git a/ocpp/v20/schemas/NotifyEVChargingScheduleResponse_v1p0.json b/ocpp/v20/schemas/NotifyEVChargingScheduleResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyEVChargingScheduleResponse_v1p0.json rename to ocpp/v20/schemas/NotifyEVChargingScheduleResponse.json diff --git a/ocpp/v20/schemas/NotifyEventRequest_v1p0.json b/ocpp/v20/schemas/NotifyEventRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyEventRequest_v1p0.json rename to ocpp/v20/schemas/NotifyEventRequest.json diff --git a/ocpp/v20/schemas/NotifyEventResponse_v1p0.json b/ocpp/v20/schemas/NotifyEventResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyEventResponse_v1p0.json rename to ocpp/v20/schemas/NotifyEventResponse.json diff --git a/ocpp/v20/schemas/NotifyMonitoringReportRequest_v1p0.json b/ocpp/v20/schemas/NotifyMonitoringReportRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyMonitoringReportRequest_v1p0.json rename to ocpp/v20/schemas/NotifyMonitoringReportRequest.json diff --git a/ocpp/v20/schemas/NotifyMonitoringReportResponse_v1p0.json b/ocpp/v20/schemas/NotifyMonitoringReportResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyMonitoringReportResponse_v1p0.json rename to ocpp/v20/schemas/NotifyMonitoringReportResponse.json diff --git a/ocpp/v20/schemas/NotifyReportRequest_v1p0.json b/ocpp/v20/schemas/NotifyReportRequest.json similarity index 100% rename from ocpp/v20/schemas/NotifyReportRequest_v1p0.json rename to ocpp/v20/schemas/NotifyReportRequest.json diff --git a/ocpp/v20/schemas/NotifyReportResponse_v1p0.json b/ocpp/v20/schemas/NotifyReportResponse.json similarity index 100% rename from ocpp/v20/schemas/NotifyReportResponse_v1p0.json rename to ocpp/v20/schemas/NotifyReportResponse.json diff --git a/ocpp/v20/schemas/PublishFirmwareRequest_v1p0.json b/ocpp/v20/schemas/PublishFirmwareRequest.json similarity index 100% rename from ocpp/v20/schemas/PublishFirmwareRequest_v1p0.json rename to ocpp/v20/schemas/PublishFirmwareRequest.json diff --git a/ocpp/v20/schemas/PublishFirmwareResponse_v1p0.json b/ocpp/v20/schemas/PublishFirmwareResponse.json similarity index 100% rename from ocpp/v20/schemas/PublishFirmwareResponse_v1p0.json rename to ocpp/v20/schemas/PublishFirmwareResponse.json diff --git a/ocpp/v20/schemas/PublishFirmwareStatusNotificationRequest_v1p0.json b/ocpp/v20/schemas/PublishFirmwareStatusNotificationRequest.json similarity index 100% rename from ocpp/v20/schemas/PublishFirmwareStatusNotificationRequest_v1p0.json rename to ocpp/v20/schemas/PublishFirmwareStatusNotificationRequest.json diff --git a/ocpp/v20/schemas/PublishFirmwareStatusNotificationResponse_v1p0.json b/ocpp/v20/schemas/PublishFirmwareStatusNotificationResponse.json similarity index 100% rename from ocpp/v20/schemas/PublishFirmwareStatusNotificationResponse_v1p0.json rename to ocpp/v20/schemas/PublishFirmwareStatusNotificationResponse.json diff --git a/ocpp/v20/schemas/Renegotiate15118ScheduleRequest_v1p0.json b/ocpp/v20/schemas/Renegotiate15118ScheduleRequest.json similarity index 100% rename from ocpp/v20/schemas/Renegotiate15118ScheduleRequest_v1p0.json rename to ocpp/v20/schemas/Renegotiate15118ScheduleRequest.json diff --git a/ocpp/v20/schemas/Renegotiate15118ScheduleResponse_v1p0.json b/ocpp/v20/schemas/Renegotiate15118ScheduleResponse.json similarity index 100% rename from ocpp/v20/schemas/Renegotiate15118ScheduleResponse_v1p0.json rename to ocpp/v20/schemas/Renegotiate15118ScheduleResponse.json diff --git a/ocpp/v20/schemas/ReportChargingProfilesRequest_v1p0.json b/ocpp/v20/schemas/ReportChargingProfilesRequest.json similarity index 100% rename from ocpp/v20/schemas/ReportChargingProfilesRequest_v1p0.json rename to ocpp/v20/schemas/ReportChargingProfilesRequest.json diff --git a/ocpp/v20/schemas/ReportChargingProfilesResponse_v1p0.json b/ocpp/v20/schemas/ReportChargingProfilesResponse.json similarity index 100% rename from ocpp/v20/schemas/ReportChargingProfilesResponse_v1p0.json rename to ocpp/v20/schemas/ReportChargingProfilesResponse.json diff --git a/ocpp/v20/schemas/RequestStartTransactionRequest_v1p0.json b/ocpp/v20/schemas/RequestStartTransactionRequest.json similarity index 100% rename from ocpp/v20/schemas/RequestStartTransactionRequest_v1p0.json rename to ocpp/v20/schemas/RequestStartTransactionRequest.json diff --git a/ocpp/v20/schemas/RequestStartTransactionResponse_v1p0.json b/ocpp/v20/schemas/RequestStartTransactionResponse.json similarity index 100% rename from ocpp/v20/schemas/RequestStartTransactionResponse_v1p0.json rename to ocpp/v20/schemas/RequestStartTransactionResponse.json diff --git a/ocpp/v20/schemas/RequestStopTransactionRequest_v1p0.json b/ocpp/v20/schemas/RequestStopTransactionRequest.json similarity index 100% rename from ocpp/v20/schemas/RequestStopTransactionRequest_v1p0.json rename to ocpp/v20/schemas/RequestStopTransactionRequest.json diff --git a/ocpp/v20/schemas/RequestStopTransactionResponse_v1p0.json b/ocpp/v20/schemas/RequestStopTransactionResponse.json similarity index 100% rename from ocpp/v20/schemas/RequestStopTransactionResponse_v1p0.json rename to ocpp/v20/schemas/RequestStopTransactionResponse.json diff --git a/ocpp/v20/schemas/ReservationStatusUpdateRequest_v1p0.json b/ocpp/v20/schemas/ReservationStatusUpdateRequest.json similarity index 100% rename from ocpp/v20/schemas/ReservationStatusUpdateRequest_v1p0.json rename to ocpp/v20/schemas/ReservationStatusUpdateRequest.json diff --git a/ocpp/v20/schemas/ReservationStatusUpdateResponse_v1p0.json b/ocpp/v20/schemas/ReservationStatusUpdateResponse.json similarity index 100% rename from ocpp/v20/schemas/ReservationStatusUpdateResponse_v1p0.json rename to ocpp/v20/schemas/ReservationStatusUpdateResponse.json diff --git a/ocpp/v20/schemas/ReserveNowRequest_v1p0.json b/ocpp/v20/schemas/ReserveNowRequest.json similarity index 100% rename from ocpp/v20/schemas/ReserveNowRequest_v1p0.json rename to ocpp/v20/schemas/ReserveNowRequest.json diff --git a/ocpp/v20/schemas/ReserveNowResponse_v1p0.json b/ocpp/v20/schemas/ReserveNowResponse.json similarity index 100% rename from ocpp/v20/schemas/ReserveNowResponse_v1p0.json rename to ocpp/v20/schemas/ReserveNowResponse.json diff --git a/ocpp/v20/schemas/ResetRequest_v1p0.json b/ocpp/v20/schemas/ResetRequest.json similarity index 100% rename from ocpp/v20/schemas/ResetRequest_v1p0.json rename to ocpp/v20/schemas/ResetRequest.json diff --git a/ocpp/v20/schemas/ResetResponse_v1p0.json b/ocpp/v20/schemas/ResetResponse.json similarity index 100% rename from ocpp/v20/schemas/ResetResponse_v1p0.json rename to ocpp/v20/schemas/ResetResponse.json diff --git a/ocpp/v20/schemas/SecurityEventNotificationRequest_v1p0.json b/ocpp/v20/schemas/SecurityEventNotificationRequest.json similarity index 100% rename from ocpp/v20/schemas/SecurityEventNotificationRequest_v1p0.json rename to ocpp/v20/schemas/SecurityEventNotificationRequest.json diff --git a/ocpp/v20/schemas/SecurityEventNotificationResponse_v1p0.json b/ocpp/v20/schemas/SecurityEventNotificationResponse.json similarity index 100% rename from ocpp/v20/schemas/SecurityEventNotificationResponse_v1p0.json rename to ocpp/v20/schemas/SecurityEventNotificationResponse.json diff --git a/ocpp/v20/schemas/SendLocalListRequest_v1p0.json b/ocpp/v20/schemas/SendLocalListRequest.json similarity index 100% rename from ocpp/v20/schemas/SendLocalListRequest_v1p0.json rename to ocpp/v20/schemas/SendLocalListRequest.json diff --git a/ocpp/v20/schemas/SendLocalListResponse_v1p0.json b/ocpp/v20/schemas/SendLocalListResponse.json similarity index 100% rename from ocpp/v20/schemas/SendLocalListResponse_v1p0.json rename to ocpp/v20/schemas/SendLocalListResponse.json diff --git a/ocpp/v20/schemas/SetChargingProfileRequest_v1p0.json b/ocpp/v20/schemas/SetChargingProfileRequest.json similarity index 100% rename from ocpp/v20/schemas/SetChargingProfileRequest_v1p0.json rename to ocpp/v20/schemas/SetChargingProfileRequest.json diff --git a/ocpp/v20/schemas/SetChargingProfileResponse_v1p0.json b/ocpp/v20/schemas/SetChargingProfileResponse.json similarity index 100% rename from ocpp/v20/schemas/SetChargingProfileResponse_v1p0.json rename to ocpp/v20/schemas/SetChargingProfileResponse.json diff --git a/ocpp/v20/schemas/SetDisplayMessageRequest_v1p0.json b/ocpp/v20/schemas/SetDisplayMessageRequest.json similarity index 100% rename from ocpp/v20/schemas/SetDisplayMessageRequest_v1p0.json rename to ocpp/v20/schemas/SetDisplayMessageRequest.json diff --git a/ocpp/v20/schemas/SetDisplayMessageResponse_v1p0.json b/ocpp/v20/schemas/SetDisplayMessageResponse.json similarity index 100% rename from ocpp/v20/schemas/SetDisplayMessageResponse_v1p0.json rename to ocpp/v20/schemas/SetDisplayMessageResponse.json diff --git a/ocpp/v20/schemas/SetMonitoringBaseRequest_v1p0.json b/ocpp/v20/schemas/SetMonitoringBaseRequest.json similarity index 100% rename from ocpp/v20/schemas/SetMonitoringBaseRequest_v1p0.json rename to ocpp/v20/schemas/SetMonitoringBaseRequest.json diff --git a/ocpp/v20/schemas/SetMonitoringBaseResponse_v1p0.json b/ocpp/v20/schemas/SetMonitoringBaseResponse.json similarity index 100% rename from ocpp/v20/schemas/SetMonitoringBaseResponse_v1p0.json rename to ocpp/v20/schemas/SetMonitoringBaseResponse.json diff --git a/ocpp/v20/schemas/SetMonitoringLevelRequest_v1p0.json b/ocpp/v20/schemas/SetMonitoringLevelRequest.json similarity index 100% rename from ocpp/v20/schemas/SetMonitoringLevelRequest_v1p0.json rename to ocpp/v20/schemas/SetMonitoringLevelRequest.json diff --git a/ocpp/v20/schemas/SetMonitoringLevelResponse_v1p0.json b/ocpp/v20/schemas/SetMonitoringLevelResponse.json similarity index 100% rename from ocpp/v20/schemas/SetMonitoringLevelResponse_v1p0.json rename to ocpp/v20/schemas/SetMonitoringLevelResponse.json diff --git a/ocpp/v20/schemas/SetNetworkProfileRequest_v1p0.json b/ocpp/v20/schemas/SetNetworkProfileRequest.json similarity index 100% rename from ocpp/v20/schemas/SetNetworkProfileRequest_v1p0.json rename to ocpp/v20/schemas/SetNetworkProfileRequest.json diff --git a/ocpp/v20/schemas/SetNetworkProfileResponse_v1p0.json b/ocpp/v20/schemas/SetNetworkProfileResponse.json similarity index 100% rename from ocpp/v20/schemas/SetNetworkProfileResponse_v1p0.json rename to ocpp/v20/schemas/SetNetworkProfileResponse.json diff --git a/ocpp/v20/schemas/SetVariableMonitoringRequest_v1p0.json b/ocpp/v20/schemas/SetVariableMonitoringRequest.json similarity index 100% rename from ocpp/v20/schemas/SetVariableMonitoringRequest_v1p0.json rename to ocpp/v20/schemas/SetVariableMonitoringRequest.json diff --git a/ocpp/v20/schemas/SetVariableMonitoringResponse_v1p0.json b/ocpp/v20/schemas/SetVariableMonitoringResponse.json similarity index 100% rename from ocpp/v20/schemas/SetVariableMonitoringResponse_v1p0.json rename to ocpp/v20/schemas/SetVariableMonitoringResponse.json diff --git a/ocpp/v20/schemas/SetVariablesRequest_v1p0.json b/ocpp/v20/schemas/SetVariablesRequest.json similarity index 100% rename from ocpp/v20/schemas/SetVariablesRequest_v1p0.json rename to ocpp/v20/schemas/SetVariablesRequest.json diff --git a/ocpp/v20/schemas/SetVariablesResponse_v1p0.json b/ocpp/v20/schemas/SetVariablesResponse.json similarity index 100% rename from ocpp/v20/schemas/SetVariablesResponse_v1p0.json rename to ocpp/v20/schemas/SetVariablesResponse.json diff --git a/ocpp/v20/schemas/SignCertificateRequest_v1p0.json b/ocpp/v20/schemas/SignCertificateRequest.json similarity index 100% rename from ocpp/v20/schemas/SignCertificateRequest_v1p0.json rename to ocpp/v20/schemas/SignCertificateRequest.json diff --git a/ocpp/v20/schemas/SignCertificateResponse_v1p0.json b/ocpp/v20/schemas/SignCertificateResponse.json similarity index 100% rename from ocpp/v20/schemas/SignCertificateResponse_v1p0.json rename to ocpp/v20/schemas/SignCertificateResponse.json diff --git a/ocpp/v20/schemas/StatusNotificationRequest_v1p0.json b/ocpp/v20/schemas/StatusNotificationRequest.json similarity index 100% rename from ocpp/v20/schemas/StatusNotificationRequest_v1p0.json rename to ocpp/v20/schemas/StatusNotificationRequest.json diff --git a/ocpp/v20/schemas/StatusNotificationResponse_v1p0.json b/ocpp/v20/schemas/StatusNotificationResponse.json similarity index 100% rename from ocpp/v20/schemas/StatusNotificationResponse_v1p0.json rename to ocpp/v20/schemas/StatusNotificationResponse.json diff --git a/ocpp/v20/schemas/TransactionEventRequest_v1p0.json b/ocpp/v20/schemas/TransactionEventRequest.json similarity index 100% rename from ocpp/v20/schemas/TransactionEventRequest_v1p0.json rename to ocpp/v20/schemas/TransactionEventRequest.json diff --git a/ocpp/v20/schemas/TransactionEventResponse_v1p0.json b/ocpp/v20/schemas/TransactionEventResponse.json similarity index 100% rename from ocpp/v20/schemas/TransactionEventResponse_v1p0.json rename to ocpp/v20/schemas/TransactionEventResponse.json diff --git a/ocpp/v20/schemas/TriggerMessageRequest_v1p0.json b/ocpp/v20/schemas/TriggerMessageRequest.json similarity index 100% rename from ocpp/v20/schemas/TriggerMessageRequest_v1p0.json rename to ocpp/v20/schemas/TriggerMessageRequest.json diff --git a/ocpp/v20/schemas/TriggerMessageResponse_v1p0.json b/ocpp/v20/schemas/TriggerMessageResponse.json similarity index 100% rename from ocpp/v20/schemas/TriggerMessageResponse_v1p0.json rename to ocpp/v20/schemas/TriggerMessageResponse.json diff --git a/ocpp/v20/schemas/UnlockConnectorRequest_v1p0.json b/ocpp/v20/schemas/UnlockConnectorRequest.json similarity index 100% rename from ocpp/v20/schemas/UnlockConnectorRequest_v1p0.json rename to ocpp/v20/schemas/UnlockConnectorRequest.json diff --git a/ocpp/v20/schemas/UnlockConnectorResponse_v1p0.json b/ocpp/v20/schemas/UnlockConnectorResponse.json similarity index 100% rename from ocpp/v20/schemas/UnlockConnectorResponse_v1p0.json rename to ocpp/v20/schemas/UnlockConnectorResponse.json diff --git a/ocpp/v20/schemas/UnpublishFirmwareRequest_v1p0.json b/ocpp/v20/schemas/UnpublishFirmwareRequest.json similarity index 100% rename from ocpp/v20/schemas/UnpublishFirmwareRequest_v1p0.json rename to ocpp/v20/schemas/UnpublishFirmwareRequest.json diff --git a/ocpp/v20/schemas/UnpublishFirmwareResponse_v1p0.json b/ocpp/v20/schemas/UnpublishFirmwareResponse.json similarity index 100% rename from ocpp/v20/schemas/UnpublishFirmwareResponse_v1p0.json rename to ocpp/v20/schemas/UnpublishFirmwareResponse.json diff --git a/ocpp/v20/schemas/Update15118EVCertificateRequest_v1p0.json b/ocpp/v20/schemas/Update15118EVCertificateRequest.json similarity index 100% rename from ocpp/v20/schemas/Update15118EVCertificateRequest_v1p0.json rename to ocpp/v20/schemas/Update15118EVCertificateRequest.json diff --git a/ocpp/v20/schemas/Update15118EVCertificateResponse_v1p0.json b/ocpp/v20/schemas/Update15118EVCertificateResponse.json similarity index 100% rename from ocpp/v20/schemas/Update15118EVCertificateResponse_v1p0.json rename to ocpp/v20/schemas/Update15118EVCertificateResponse.json diff --git a/ocpp/v20/schemas/UpdateFirmwareRequest_v1p0.json b/ocpp/v20/schemas/UpdateFirmwareRequest.json similarity index 100% rename from ocpp/v20/schemas/UpdateFirmwareRequest_v1p0.json rename to ocpp/v20/schemas/UpdateFirmwareRequest.json diff --git a/ocpp/v20/schemas/UpdateFirmwareResponse_v1p0.json b/ocpp/v20/schemas/UpdateFirmwareResponse.json similarity index 100% rename from ocpp/v20/schemas/UpdateFirmwareResponse_v1p0.json rename to ocpp/v20/schemas/UpdateFirmwareResponse.json diff --git a/ocpp/v201/__init__.py b/ocpp/v201/__init__.py index ae4a68763..4b58393e2 100644 --- a/ocpp/v201/__init__.py +++ b/ocpp/v201/__init__.py @@ -1,8 +1,17 @@ +import pathlib + from ocpp.charge_point import ChargePoint as cp +from ocpp.messages import SchemaValidator from ocpp.v201 import call, call_result +_schemas_dir = pathlib.Path(__file__).parent.joinpath("schemas").resolve() +validator = SchemaValidator(str(_schemas_dir)) + class ChargePoint(cp): _call = call _call_result = call_result _ocpp_version = "2.0.1" + + def __init__(self, validator: SchemaValidator = validator, *args, **kwargs): + super().__init__(validator=validator, *args, **kwargs) diff --git a/ocpp/v21/__init__.py b/ocpp/v21/__init__.py new file mode 100644 index 000000000..f5f5b27be --- /dev/null +++ b/ocpp/v21/__init__.py @@ -0,0 +1,27 @@ +from typing import Optional + +from ocpp.charge_point import ChargePoint as cp +from ocpp.messages import SchemaValidator +from ocpp.v21 import call, call_result + + +class ChargePoint(cp): + _call = call + _call_result = call_result + _ocpp_version = "2.1" + + def __init__( + self, + id, + connection, + validator: Optional[SchemaValidator] = None, + *args, + **kwargs + ): + # The ocpp package doesn't come with the JSON schemas for OCPP 2.1. + if validator is None: + raise RuntimeError( + "Failed to initiate `ChargePoint` implementing OCPP 2.1: `validator` is not set. The ocpp package doesn't come with JSON schemas for OCPP 2.1. See https://github.com/mobilityhouse/ocpp/issues/458 for more information." + ) + + super().__init__(id, connection, validator, *args, **kwargs) diff --git a/ocpp/v21/call.py b/ocpp/v21/call.py new file mode 100644 index 000000000..cb4031759 --- /dev/null +++ b/ocpp/v21/call.py @@ -0,0 +1,620 @@ +from dataclasses import dataclass +from typing import Any, List, Optional + +from ocpp.v21 import enums +from ocpp.v21.datatypes import ( + EVSE, + AuthorizationData, + CertificateHashData, + ChargingLimit, + ChargingNeeds, + ChargingProfile, + ChargingProfileCriterion, + ChargingSchedule, + ChargingStation, + ClearChargingProfile, + ComponentVariable, + CustomData, + EventData, + Firmware, + GetVariableData, + IdToken, + LogParameters, + MessageInfo, + MeterValue, + MonitoringData, + NetworkConnectionProfile, + OCSPRequestData, + ReportData, + SetMonitoringData, + SetVariableData, + Transaction, +) +from ocpp.v21.enums import ( + BootReason, + CertificateAction, + CertificateSigningUse, + ChargingLimitSource, + ChargingRateUnit, + ComponentCriterion, + Connector, + ConnectorStatus, + EnergyTransferMode, + FirmwareStatus, + GetCertificateIdUse, + InstallCertificateUse, + Log, + MessagePriority, + MessageState, + MessageTrigger, + MonitoringBase, + MonitoringCriterion, + NotifyCRLStatus, + OperationalStatus, + PreconditioningStatus, + PublishFirmwareStatus, + ReportBase, + ReservationUpdateStatus, + TriggerReason, + Update, + UploadLogStatus, +) + + +@dataclass +class AFRRSignal: + signal: int + timestamp: str + custom_data: Optional[CustomData] = None + + +@dataclass +class Authorize: + id_token: IdToken + certificate: Optional[str] = None + custom_data: Optional[CustomData] = None + iso_15118_certificate_hash_data: Optional[List[OCSPRequestData]] = None + + +@dataclass +class BootNotification: + charging_station: ChargingStation + reason: BootReason + custom_data: Optional[CustomData] = None + + +@dataclass +class CancelReservation: + reservation_id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class CertificateSigned: + certificate_chain: str + certificate_type: Optional[CertificateSigningUse] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class ChangeAvailability: + operational_status: OperationalStatus + custom_data: Optional[CustomData] = None + evse: Optional[EVSE] = None + + +@dataclass +class ClearCache: + custom_data: Optional[CustomData] = None + + +@dataclass +class ClearChargingProfile: + charging_profile_criteria: Optional[ClearChargingProfile] = None + charging_profile_id: Optional[int] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class ClearDisplayMessage: + id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class ClearVariableMonitoring: + id: List[int] + custom_data: Optional[CustomData] = None + + +@dataclass +class ClearedChargingLimit: + charging_limit_source: ChargingLimitSource + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + + +@dataclass +class CostUpdated: + total_cost: float + transaction_id: str + custom_data: Optional[CustomData] = None + + +@dataclass +class CustomerInformation: + clear: bool + report: bool + request_id: int + custom_data: Optional[CustomData] = None + customer_certificate: Optional[CertificateHashData] = None + customer_identifier: Optional[str] = None + id_token: Optional[IdToken] = None + + +@dataclass +class DataTransfer: + vendor_id: str + custom_data: Optional[CustomData] = None + data: Any = None + message_id: Optional[str] = None + + +@dataclass +class DeleteCertificate: + certificate_hash_data: CertificateHashData + custom_data: Optional[CustomData] = None + + +@dataclass +class FirmwareStatusNotification: + status: FirmwareStatus + custom_data: Optional[CustomData] = None + request_id: Optional[int] = None + + +@dataclass +class Get15118EVCertificate: + action: CertificateAction + exi_request: str + iso_15118_schema_version: str + custom_data: Optional[CustomData] = None + maximum_contract_certificate_chains: Optional[int] = None + prioritized_emaids: Optional[List[str]] = None + + +@dataclass +class GetBaseReport: + report_base: ReportBase + request_id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class GetCRL: + certificate_hash_data: CertificateHashData + request_id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class GetCertificateStatus: + ocsp_request_data: OCSPRequestData + custom_data: Optional[CustomData] = None + + +@dataclass +class GetChargingProfiles: + charging_profile: ChargingProfileCriterion + request_id: int + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + + +@dataclass +class GetCompositeSchedule: + duration: int + evse_id: int + charging_rate_unit: Optional[ChargingRateUnit] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class GetDisplayMessages: + request_id: int + custom_data: Optional[CustomData] = None + id: Optional[List[int]] = None + priority: Optional[MessagePriority] = None + state: Optional[MessageState] = None + + +@dataclass +class GetInstalledCertificateIds: + certificate_type: Optional[List[GetCertificateIdUse]] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class GetLocalListVersion: + custom_data: Optional[CustomData] = None + + +@dataclass +class GetLog: + log: LogParameters + log_type: Log + request_id: int + custom_data: Optional[CustomData] = None + retries: Optional[int] = None + retry_interval: Optional[int] = None + + +@dataclass +class GetMonitoringReport: + request_id: int + component_variable: Optional[List[ComponentVariable]] = None + custom_data: Optional[CustomData] = None + monitoring_criteria: Optional[List[MonitoringCriterion]] = None + + +@dataclass +class GetReport: + request_id: int + component_criteria: Optional[List[ComponentCriterion]] = None + component_variable: Optional[List[ComponentVariable]] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class GetTransactionStatus: + custom_data: Optional[CustomData] = None + transaction_id: Optional[str] = None + + +@dataclass +class GetVariables: + get_variable_data: List[GetVariableData] + custom_data: Optional[CustomData] = None + + +@dataclass +class Heartbeat: + custom_data: Optional[CustomData] = None + + +@dataclass +class InstallCertificate: + certificate: str + certificate_type: InstallCertificateUse + custom_data: Optional[CustomData] = None + + +@dataclass +class LogStatusNotification: + status: UploadLogStatus + custom_data: Optional[CustomData] = None + request_id: Optional[int] = None + + +@dataclass +class MeterValues: + evse_id: int + meter_value: List[MeterValue] + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyAllowedEnergyTransfer: + allowed_energy_transfer: List[EnergyTransferMode] + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyCRL: + request_id: int + status: NotifyCRLStatus + custom_data: Optional[CustomData] = None + location: Optional[str] = None + + +@dataclass +class NotifyChargingLimit: + charging_limit: ChargingLimit + charging_schedule: Optional[List[ChargingSchedule]] = None + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + + +@dataclass +class NotifyCustomerInformation: + data: str + generated_at: str + request_id: int + seq_no: int + custom_data: Optional[CustomData] = None + tbc: bool = False + + +@dataclass +class NotifyDisplayMessages: + request_id: int + custom_data: Optional[CustomData] = None + message_info: Optional[List[MessageInfo]] = None + tbc: bool = False + + +@dataclass +class NotifyEVChargingNeeds: + charging_needs: ChargingNeeds + evse_id: int + custom_data: Optional[CustomData] = None + max_schedule_tuples: Optional[int] = None + + +@dataclass +class NotifyEVChargingSchedule: + charging_schedule: ChargingSchedule + evse_id: int + time_base: str + custom_data: Optional[CustomData] = None + power_tolerance_acceptance: Optional[bool] = None + selected_schedule_tuple_id: Optional[int] = None + + +@dataclass +class NotifyEvent: + event_data: List[EventData] + generated_at: str + seq_no: int + custom_data: Optional[CustomData] = None + tbc: bool = False + + +@dataclass +class NotifyMonitoringReport: + generated_at: str + request_id: int + seq_no: int + custom_data: Optional[CustomData] = None + monitor: Optional[List[MonitoringData]] = None + tbc: bool = False + + +@dataclass +class NotifyPriorityCharging: + activated: bool + transaction_id: str + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyReport: + generated_at: str + request_id: int + seq_no: int + custom_data: Optional[CustomData] = None + report_data: Optional[List[ReportData]] = None + tbc: bool = False + + +@dataclass +class PublishFirmware: + checksum: str + location: str + request_id: int + custom_data: Optional[CustomData] = None + retries: Optional[int] = None + retry_interval: Optional[int] = None + + +@dataclass +class PublishFirmwareStatusNotification: + status: PublishFirmwareStatus + custom_data: Optional[CustomData] = None + location: Optional[List[str]] = None + request_id: Optional[int] = None + + +@dataclass +class PullDynamicScheduleUpdate: + charging_profile_id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class ReportChargingProfiles: + charging_limit_source: ChargingLimitSource + charging_profile: List[ChargingProfile] + evse_id: int + request_id: int + custom_data: Optional[CustomData] = None + tbc: bool = False + + +@dataclass +class RequestStartTransaction: + id_token: IdToken + remote_start_id: int + charging_profile: Optional[ChargingProfile] = None + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + group_id_token: Optional[IdToken] = None + + +@dataclass +class RequestStopTransaction: + transaction_id: str + custom_data: Optional[CustomData] = None + + +@dataclass +class ReservationStatusUpdate: + reservation_id: int + reservation_update_status: ReservationUpdateStatus + custom_data: Optional[CustomData] = None + + +@dataclass +class ReserveNow: + expiry_date_time: str + id: int + id_token: IdToken + connector_type: Optional[Connector] = None + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + group_id_token: Optional[IdToken] = None + + +@dataclass +class Reset: + type: enums.Reset + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + + +@dataclass +class SecurityEventNotification: + timestamp: str + type: str + custom_data: Optional[CustomData] = None + tech_info: Optional[str] = None + + +@dataclass +class SendLocalList: + update_type: Update + version_number: int + custom_data: Optional[CustomData] = None + local_authorization_list: Optional[List[AuthorizationData]] = None + + +@dataclass +class SetChargingProfile: + charging_profile: ChargingProfile + evse_id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class SetDisplayMessage: + message: MessageInfo + custom_data: Optional[CustomData] = None + + +@dataclass +class SetMonitoringBase: + monitoring_base: MonitoringBase + custom_data: Optional[CustomData] = None + + +@dataclass +class SetMonitoringLevel: + severity: int + custom_data: Optional[CustomData] = None + + +@dataclass +class SetNetworkProfile: + configuration_slot: int + connection_data: NetworkConnectionProfile + custom_data: Optional[CustomData] = None + + +@dataclass +class SetVariableMonitoring: + set_monitoring_data: List[SetMonitoringData] + custom_data: Optional[CustomData] = None + + +@dataclass +class SetVariables: + set_variable_data: List[SetVariableData] + custom_data: Optional[CustomData] = None + + +@dataclass +class SignCertificate: + csr: str + certificate_type: Optional[CertificateSigningUse] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class StatusNotification: + connector_id: int + connector_status: ConnectorStatus + evse_id: int + timestamp: str + custom_data: Optional[CustomData] = None + + +@dataclass +class TransactionEvent: + event_type: enums.TransactionEvent + seq_no: int + timestamp: str + transaction_info: Transaction + trigger_reason: TriggerReason + cable_max_current: Optional[float] = None + custom_data: Optional[CustomData] = None + evse: Optional[EVSE] = None + id_token: Optional[IdToken] = None + meter_value: Optional[List[MeterValue]] = None + number_of_phases_used: Optional[int] = None + offline: bool = False + preconditioning_status: Optional[PreconditioningStatus] = None + reservation_id: Optional[int] = None + + +@dataclass +class TriggerMessage: + requested_message: MessageTrigger + custom_data: Optional[CustomData] = None + evse: Optional[EVSE] = None + + +@dataclass +class UnlockConnector: + connector_id: int + evse_id: int + custom_data: Optional[CustomData] = None + + +@dataclass +class UnpublishFirmware: + checksum: str + custom_data: Optional[CustomData] = None + + +@dataclass +class UpdateDynamicSchedule: + charging_profile_id: int + custom_data: Optional[CustomData] = None + discharge_limit: Optional[float] = None + discharge_limit_l2: Optional[float] = None + discharge_limit_l3: Optional[float] = None + limit: Optional[float] = None + limit_l2: Optional[float] = None + limit_l3: Optional[float] = None + setpoint: Optional[float] = None + setpoint_l2: Optional[float] = None + setpoint_l3: Optional[float] = None + setpoint_reactive: Optional[float] = None + setpoint_reactive_l2: Optional[float] = None + setpoint_reactive_l3: Optional[float] = None + + +@dataclass +class UpdateFirmware: + firmware: Firmware + request_id: int + custom_data: Optional[CustomData] = None + retries: Optional[int] = None + retry_interval: Optional[int] = None + + +@dataclass +class UsePriorityCharging: + activate: bool + transaction_id: str + custom_data: Optional[CustomData] = None diff --git a/ocpp/v21/call_result.py b/ocpp/v21/call_result.py new file mode 100644 index 000000000..aad3b2378 --- /dev/null +++ b/ocpp/v21/call_result.py @@ -0,0 +1,536 @@ +from dataclasses import dataclass +from typing import Any, List, Optional + +from ocpp.v21 import enums +from ocpp.v21.datatypes import ( + CertificateHashDataChain, + CompositeSchedule, + CustomData, + GetVariableResult, + IdTokenInfo, + MessageContent, + ResponseClearMonitoringResult, + SetMonitoringResult, + SetVariableResult, + StatusInfo, +) +from ocpp.v21.enums import ( + AuthorizeCertificateStatus, + CancelReservationStatus, + CertificateSignedStatus, + ChangeAvailabilityStatus, + ChargingProfileStatus, + ClearCacheStatus, + ClearChargingProfileStatus, + ClearMessageStatus, + CustomerInformationStatus, + DataTransferStatus, + DeleteCertificateStatus, + DisplayMessageStatus, + EnergyTransferMode, + GenericDeviceModelStatus, + GenericStatus, + GetChargingProfileStatus, + GetDisplayMessagesStatus, + GetInstalledCertificateStatus, + InstallCertificateStatus, + Iso15118EVCertificateStatus, + LogStatus, + NotifyAllowedEnergyTransferStatus, + NotifyEVChargingNeedsStatus, + PriorityChargingStatus, + RegistrationStatus, + RequestStartStopStatus, + ReserveNowStatus, + ResetStatus, + SendLocalListStatus, + SetNetworkProfileStatus, + TriggerMessageStatus, + UnlockStatus, + UnpublishFirmwareStatus, + UpdateFirmwareStatus, +) + + +@dataclass +class AFRRSignal: + status: GenericStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class Authorize: + id_token_info: IdTokenInfo + allowed_energy_transfer: Optional[List[EnergyTransferMode]] = None + certificate_status: Optional[AuthorizeCertificateStatus] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class BootNotification: + current_time: str + interval: int + status: RegistrationStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class CancelReservation: + status: CancelReservationStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class CertificateSigned: + status: CertificateSignedStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class ChangeAvailability: + status: ChangeAvailabilityStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class ClearCache: + status: ClearCacheStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class ClearChargingProfile: + status: ClearChargingProfileStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class ClearDisplayMessage: + status: ClearMessageStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class ClearVariableMonitoring: + clear_monitoring_result: List[ResponseClearMonitoringResult] + custom_data: Optional[CustomData] = None + + +@dataclass +class ClearedChargingLimit: + custom_data: Optional[CustomData] = None + + +@dataclass +class CostUpdated: + custom_data: Optional[CustomData] = None + + +@dataclass +class CustomerInformation: + status: CustomerInformationStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class DataTransfer: + status: DataTransferStatus + custom_data: Optional[CustomData] = None + data: Any = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class DeleteCertificate: + status: DeleteCertificateStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class FirmwareStatusNotification: + custom_data: Optional[CustomData] = None + + +@dataclass +class Get15118EVCertificate: + exi_response: str + status: Iso15118EVCertificateStatus + custom_data: Optional[CustomData] = None + remaining_contracts: Optional[int] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetBaseReport: + status: GenericDeviceModelStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetCRL: + request_id: int + status: GenericStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetCertificateStatus: + status: enums.GetCertificateStatus + custom_data: Optional[CustomData] = None + ocsp_result: Optional[str] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetChargingProfiles: + status: GetChargingProfileStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetCompositeSchedule: + status: GenericStatus + custom_data: Optional[CustomData] = None + schedule: Optional[CompositeSchedule] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetDisplayMessages: + status: GetDisplayMessagesStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetInstalledCertificateIds: + status: GetInstalledCertificateStatus + certificate_hash_data_chain: Optional[List[CertificateHashDataChain]] = None + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetLocalListVersion: + version_number: int + custom_data: Optional[CustomData] = None + + +@dataclass +class GetLog: + status: LogStatus + custom_data: Optional[CustomData] = None + filename: Optional[str] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetMonitoringReport: + status: GenericDeviceModelStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetReport: + status: GenericDeviceModelStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class GetTransactionStatus: + messages_in_queue: bool + custom_data: Optional[CustomData] = None + ongoing_indicator: Optional[bool] = None + + +@dataclass +class GetVariables: + get_variable_result: List[GetVariableResult] + custom_data: Optional[CustomData] = None + + +@dataclass +class Heartbeat: + current_time: str + custom_data: Optional[CustomData] = None + + +@dataclass +class InstallCertificate: + status: InstallCertificateStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class LogStatusNotification: + custom_data: Optional[CustomData] = None + + +@dataclass +class MeterValues: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyAllowedEnergyTransfer: + status: NotifyAllowedEnergyTransferStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class NotifyCRL: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyChargingLimit: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyCustomerInformation: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyDisplayMessages: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyEVChargingNeeds: + status: NotifyEVChargingNeedsStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class NotifyEVChargingSchedule: + status: GenericStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class NotifyEvent: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyMonitoringReport: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyPriorityCharging: + custom_data: Optional[CustomData] = None + + +@dataclass +class NotifyReport: + custom_data: Optional[CustomData] = None + + +@dataclass +class PublishFirmware: + status: GenericStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class PublishFirmwareStatusNotification: + custom_data: Optional[CustomData] = None + + +@dataclass +class PullDynamicScheduleUpdate: + custom_data: Optional[CustomData] = None + discharge_limit: Optional[float] = None + discharge_limit_l2: Optional[float] = None + discharge_limit_l3: Optional[float] = None + limit: Optional[float] = None + limit_l2: Optional[float] = None + limit_l3: Optional[float] = None + setpoint: Optional[float] = None + setpoint_l2: Optional[float] = None + setpoint_l3: Optional[float] = None + setpoint_reactive: Optional[float] = None + setpoint_reactive_l2: Optional[float] = None + setpoint_reactive_l3: Optional[float] = None + + +@dataclass +class ReportChargingProfiles: + custom_data: Optional[CustomData] = None + + +@dataclass +class RequestStartTransaction: + status: RequestStartStopStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + transaction_id: Optional[str] = None + + +@dataclass +class RequestStopTransaction: + status: RequestStartStopStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class ReservationStatusUpdate: + custom_data: Optional[CustomData] = None + + +@dataclass +class ReserveNow: + status: ReserveNowStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class Reset: + status: ResetStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SecurityEventNotification: + custom_data: Optional[CustomData] = None + + +@dataclass +class SendLocalList: + status: SendLocalListStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetChargingProfile: + status: ChargingProfileStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetDisplayMessage: + status: DisplayMessageStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetMonitoringBase: + status: GenericDeviceModelStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetMonitoringLevel: + status: GenericStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetNetworkProfile: + status: SetNetworkProfileStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetVariableMonitoring: + set_monitoring_result: List[SetMonitoringResult] + custom_data: Optional[CustomData] = None + + +@dataclass +class SetVariables: + set_variable_result: List[SetVariableResult] + custom_data: Optional[CustomData] = None + + +@dataclass +class SignCertificate: + status: GenericStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class StatusNotification: + custom_data: Optional[CustomData] = None + + +@dataclass +class TransactionEvent: + charging_priority: Optional[int] = None + custom_data: Optional[CustomData] = None + id_token_info: Optional[IdTokenInfo] = None + total_cost: Optional[float] = None + updated_personal_message: Optional[MessageContent] = None + + +@dataclass +class TriggerMessage: + status: TriggerMessageStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class UnlockConnector: + status: UnlockStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class UnpublishFirmware: + status: UnpublishFirmwareStatus + custom_data: Optional[CustomData] = None + + +@dataclass +class UpdateDynamicSchedule: + status: ChargingProfileStatus + custom_data: Optional[CustomData] = None + + +@dataclass +class UpdateFirmware: + status: UpdateFirmwareStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class UsePriorityCharging: + status: PriorityChargingStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None diff --git a/ocpp/v21/datatypes.py b/ocpp/v21/datatypes.py new file mode 100644 index 000000000..fbeb35495 --- /dev/null +++ b/ocpp/v21/datatypes.py @@ -0,0 +1,773 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import List, Optional + +from ocpp.v21 import enums +from ocpp.v21.enums import ( + APNAuthentication, + Attribute, + AuthorizationStatus, + ChargingLimitSource, + ChargingProfileKind, + ChargingProfilePurpose, + ChargingRateUnit, + ChargingState, + ClearMonitoringStatus, + ControlMode, + CostKind, + Data, + EnergyTransferMode, + EventNotification, + EventTrigger, + GetCertificateIdUse, + GetVariableStatus, + HashAlgorithm, + Location, + Measurand, + MessageFormat, + MessagePriority, + MessageState, + MobilityNeedsMode, + Monitor, + Mutability, + OCPPTransport, + OCPPVersion, + OperationMode, + Phase, + Pricing, + ReadingContext, + Reason, + RecurrencyKind, + SetMonitoringStatus, + SetVariableStatus, +) + + +@dataclass +class ACChargingParameters: + energy_amount: float + ev_max_current: float + ev_max_voltage: float + ev_min_current: float + custom_data: Optional[CustomData] = None + + +@dataclass +class APN: + apn: str + apn_authentication: APNAuthentication + apn_password: Optional[str] = None + apn_user_name: Optional[str] = None + custom_data: Optional[CustomData] = None + preferred_network: Optional[str] = None + sim_pin: Optional[int] = None + use_only_preferred_network: bool = False + + +@dataclass +class AbsolutePriceSchedule: + currency: str + language: str + price_algorithm: str + price_rule_stacks: List[PriceRuleStack] + price_schedule_id: int + time_anchor: str + additional_selected_services: Optional[List[AdditionalSelectedServices]] = None + custom_data: Optional[CustomData] = None + maximum_cost: Optional[RationalNumber] = None + minimum_cost: Optional[RationalNumber] = None + overstay_rule_list: Optional[OverstayRuleList] = None + price_schedule_description: Optional[str] = None + tax_rules: Optional[List[TaxRule]] = None + + +@dataclass +class AdditionalInfo: + additional_id_token: str + type: str + custom_data: Optional[CustomData] = None + + +@dataclass +class AdditionalSelectedServices: + service_fee: RationalNumber + service_name: str + custom_data: Optional[CustomData] = None + + +@dataclass +class AuthorizationData: + id_token: IdToken + custom_data: Optional[CustomData] = None + id_token_info: Optional[IdTokenInfo] = None + + +@dataclass +class CertificateHashData: + hash_algorithm: HashAlgorithm + issuer_key_hash: str + issuer_name_hash: str + serial_number: str + custom_data: Optional[CustomData] = None + + +@dataclass +class CertificateHashDataChain: + certificate_hash_data: CertificateHashData + certificate_type: GetCertificateIdUse + child_certificate_hash_data: Optional[List[CertificateHashData]] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class ChargingLimit: + charging_limit_source: ChargingLimitSource + custom_data: Optional[CustomData] = None + is_grid_critical: Optional[bool] = None + is_local_generation: Optional[bool] = None + + +@dataclass +class ChargingNeeds: + requested_energy_transfer: EnergyTransferMode + ac_charging_parameters: Optional[ACChargingParameters] = None + available_energy_transfer: Optional[List[EnergyTransferMode]] = None + control_mode: Optional[ControlMode] = None + custom_data: Optional[CustomData] = None + dc_charging_parameters: Optional[DCChargingParameters] = None + departure_time: Optional[str] = None + ev_energy_offer: Optional[EVEnergyOffer] = None + mobility_needs_mode: Optional[MobilityNeedsMode] = None + pricing: Optional[Pricing] = None + v2x_charging_parameters: Optional[V2XChargingParameters] = None + + +@dataclass +class ChargingProfile: + charging_profile_kind: ChargingProfileKind + charging_profile_purpose: ChargingProfilePurpose + charging_schedule: List[ChargingSchedule] + id: int + stack_level: int + custom_data: Optional[CustomData] = None + max_offline_duration: Optional[int] = None + price_schedule_signature: Optional[str] = None + recurrency_kind: Optional[RecurrencyKind] = None + transaction_id: Optional[str] = None + update_interval: Optional[int] = None + valid_from: Optional[str] = None + valid_to: Optional[str] = None + + +@dataclass +class ChargingProfileCriterion: + charging_limit_source: Optional[List[ChargingLimitSource]] = None + charging_profile_id: Optional[List[int]] = None + charging_profile_purpose: Optional[ChargingProfilePurpose] = None + custom_data: Optional[CustomData] = None + stack_level: Optional[int] = None + + +@dataclass +class ChargingSchedule: + charging_rate_unit: ChargingRateUnit + charging_schedule_period: List[ChargingSchedulePeriod] + id: int + absolute_price_schedule: Optional[AbsolutePriceSchedule] = None + custom_data: Optional[CustomData] = None + digest_value: Optional[str] = None + duration: Optional[int] = None + limit_beyond_soc: Optional[LimitBeyondSoC] = None + min_charging_rate: Optional[float] = None + power_tolerance: Optional[float] = None + price_level_schedule: Optional[PriceLevelSchedule] = None + sales_tariff: Optional[SalesTariff] = None + signature_id: Optional[int] = None + start_schedule: Optional[str] = None + + +@dataclass +class ChargingSchedulePeriod: + start_period: int + custom_data: Optional[CustomData] = None + discharge_limit: Optional[float] = None + discharge_limit_l2: Optional[float] = None + discharge_limit_l3: Optional[float] = None + dyn_update_time: Optional[str] = None + limit: Optional[float] = None + limit_l2: Optional[float] = None + limit_l3: Optional[float] = None + number_phases: Optional[int] = None + operation_mode: Optional[OperationMode] = None + phase_to_use: Optional[int] = None + preconditioning_request: Optional[bool] = None + set_point_reactive: Optional[float] = None + set_point_reactive_l2: Optional[float] = None + set_point_reactive_l3: Optional[float] = None + setpoint: Optional[float] = None + setpoint_l2: Optional[float] = None + setpoint_l3: Optional[float] = None + v2x_baseline: Optional[float] = None + v2x_freq_watt_curve: Optional[List[V2XFreqWattEntry]] = None + v2x_signal_watt_curve: Optional[List[V2XSignalWattEntry]] = None + + +@dataclass +class ChargingStation: + model: str + vendor_name: str + custom_data: Optional[CustomData] = None + firmware_version: Optional[str] = None + modem: Optional[Modem] = None + serial_number: Optional[str] = None + + +@dataclass +class ClearChargingProfile: + charging_profile_purpose: Optional[ChargingProfilePurpose] = None + custom_data: Optional[CustomData] = None + evse_id: Optional[int] = None + stack_level: Optional[int] = None + + +@dataclass +class Component: + name: str + custom_data: Optional[CustomData] = None + evse: Optional[EVSE] = None + instance: Optional[str] = None + + +@dataclass +class ComponentVariable: + component: Component + custom_data: Optional[CustomData] = None + variable: Optional[Variable] = None + + +@dataclass +class CompositeSchedule: + charging_rate_unit: ChargingRateUnit + charging_schedule_period: List[ChargingSchedulePeriod] + duration: int + evse_id: int + schedule_start: str + custom_data: Optional[CustomData] = None + + +@dataclass +class ConsumptionCost: + cost: List[Cost] + start_value: float + custom_data: Optional[CustomData] = None + + +@dataclass +class Cost: + amount: int + cost_kind: CostKind + amount_multiplier: Optional[int] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class CustomData: + vendor_id: str + + +@dataclass +class DCChargingParameters: + ev_max_current: float + ev_max_voltage: float + bulk_soc: Optional[int] = None + custom_data: Optional[CustomData] = None + energy_amount: Optional[float] = None + ev_energy_capacity: Optional[float] = None + ev_max_power: Optional[float] = None + full_soc: Optional[int] = None + state_of_charge: Optional[int] = None + + +@dataclass +class EVAbsolutePriceSchedule: + currency: str + ev_absolute_price_schedule_entries: List[EVAbsolutePriceScheduleEntry] + price_algorithm: str + time_anchor: str + custom_data: Optional[CustomData] = None + + +@dataclass +class EVAbsolutePriceScheduleEntry: + duration: int + ev_price_rule: List[EVPriceRule] + custom_data: Optional[CustomData] = None + + +@dataclass +class EVEnergyOffer: + ev_power_schedule: EVPowerSchedule + custom_data: Optional[CustomData] = None + ev_absolute_price_schedule: Optional[EVAbsolutePriceSchedule] = None + + +@dataclass +class EVPowerSchedule: + ev_power_schedule_entries: List[EVPowerScheduleEntry] + time_anchor: str + custom_data: Optional[CustomData] = None + + +@dataclass +class EVPowerScheduleEntry: + duration: int + power: float + custom_data: Optional[CustomData] = None + + +@dataclass +class EVPriceRule: + energy_fee: float + power_range_start: float + custom_data: Optional[CustomData] = None + + +@dataclass +class EVSE: + id: int + connector_id: Optional[int] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class EventData: + actual_value: str + component: Component + event_id: int + event_notification_type: EventNotification + timestamp: str + trigger: EventTrigger + variable: Variable + cause: Optional[int] = None + cleared: Optional[bool] = None + custom_data: Optional[CustomData] = None + tech_code: Optional[str] = None + tech_info: Optional[str] = None + transaction_id: Optional[str] = None + variable_monitoring_id: Optional[int] = None + + +@dataclass +class Firmware: + location: str + retrieve_date_time: str + custom_data: Optional[CustomData] = None + install_date_time: Optional[str] = None + signature: Optional[str] = None + signing_certificate: Optional[str] = None + + +@dataclass +class GetVariableData: + component: Component + variable: Variable + attribute_type: Attribute = Attribute.actual + custom_data: Optional[CustomData] = None + + +@dataclass +class GetVariableResult: + attribute_status: GetVariableStatus + component: Component + variable: Variable + attribute_status_info: Optional[StatusInfo] = None + attribute_type: Attribute = Attribute.actual + attribute_value: Optional[str] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class IdToken: + id_token: str + type: enums.IdToken + additional_info: Optional[List[AdditionalInfo]] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class IdTokenInfo: + status: AuthorizationStatus + cache_expiry_date_time: Optional[str] = None + charging_priority: Optional[int] = None + custom_data: Optional[CustomData] = None + evse_id: Optional[List[int]] = None + group_id_token: Optional[IdToken] = None + language1: Optional[str] = None + language2: Optional[str] = None + personal_message: Optional[MessageContent] = None + + +@dataclass +class LimitBeyondSoC: + limit: float + soc: int + custom_data: Optional[CustomData] = None + + +@dataclass +class LogParameters: + remote_location: str + custom_data: Optional[CustomData] = None + latest_timestamp: Optional[str] = None + oldest_timestamp: Optional[str] = None + + +@dataclass +class MessageContent: + content: str + format: MessageFormat + custom_data: Optional[CustomData] = None + language: Optional[str] = None + + +@dataclass +class MessageInfo: + id: int + message: MessageContent + priority: MessagePriority + custom_data: Optional[CustomData] = None + display: Optional[Component] = None + end_date_time: Optional[str] = None + start_date_time: Optional[str] = None + state: Optional[MessageState] = None + transaction_id: Optional[str] = None + + +@dataclass +class MeterValue: + sampled_value: List[SampledValue] + timestamp: str + custom_data: Optional[CustomData] = None + + +@dataclass +class Modem: + custom_data: Optional[CustomData] = None + iccid: Optional[str] = None + imsi: Optional[str] = None + + +@dataclass +class MonitoringData: + component: Component + variable: Variable + variable_monitoring: List[VariableMonitoring] + custom_data: Optional[CustomData] = None + + +@dataclass +class NetworkConnectionProfile: + message_timeout: int + ocpp_csms_url: str + ocpp_interface: OCPPTransport + ocpp_transport: OCPPTransport + ocpp_version: OCPPVersion + security_profile: int + apn: Optional[APN] = None + custom_data: Optional[CustomData] = None + vpn: Optional[VPN] = None + + +@dataclass +class OCSPRequestData: + hash_algorithm: HashAlgorithm + issuer_key_hash: str + issuer_name_hash: str + responder_url: str + serial_number: str + custom_data: Optional[CustomData] = None + + +@dataclass +class OverstayRuleList: + custom_data: Optional[CustomData] = None + overstay_power_threshold: Optional[RationalNumber] = None + overstay_time_threshold: Optional[int] = None + + +@dataclass +class PriceLevelSchedule: + number_of_price_levels: int + price_level_schedule_entries: List[PriceLevelScheduleEntry] + price_schedule_id: int + time_anchor: str + custom_data: Optional[CustomData] = None + price_schedule_description: Optional[str] = None + + +@dataclass +class PriceLevelScheduleEntry: + duration: int + price_level: int + custom_data: Optional[CustomData] = None + + +@dataclass +class PriceRule: + energy_fee: RationalNumber + power_range_start: RationalNumber + carbon_dioxide_emission: Optional[int] = None + custom_data: Optional[CustomData] = None + parking_fee: Optional[RationalNumber] = None + parking_fee_period: Optional[int] = None + renewable_generation_percentage: Optional[int] = None + + +@dataclass +class PriceRuleStack: + duration: int + price_rule: List[PriceRule] + custom_data: Optional[CustomData] = None + + +@dataclass +class RationalNumber: + exponent: int + value: int + custom_data: Optional[CustomData] = None + + +@dataclass +class RelativeTimeInterval: + start: int + custom_data: Optional[CustomData] = None + duration: Optional[int] = None + + +@dataclass +class ReportData: + component: Component + variable: Variable + variable_attribute: List[VariableAttribute] + custom_data: Optional[CustomData] = None + variable_characteristics: Optional[VariableCharacteristics] = None + + +@dataclass +class ResponseClearMonitoringResult: + id: int + status: ClearMonitoringStatus + custom_data: Optional[CustomData] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SalesTariff: + id: int + sales_tariff_entry: List[SalesTariffEntry] + custom_data: Optional[CustomData] = None + num_e_price_levels: Optional[int] = None + sales_tariff_description: Optional[str] = None + + +@dataclass +class SalesTariffEntry: + relative_time_interval: RelativeTimeInterval + consumption_cost: Optional[List[ConsumptionCost]] = None + custom_data: Optional[CustomData] = None + e_price_level: Optional[int] = None + + +@dataclass +class SampledValue: + value: float + context: ReadingContext = ReadingContext.sample_periodic + custom_data: Optional[CustomData] = None + location: Location = Location.outlet + measurand: Measurand = Measurand.energy_active_import_register + phase: Optional[Phase] = None + signed_meter_value: Optional[SignedMeterValue] = None + unit_of_measure: Optional[UnitOfMeasure] = None + + +@dataclass +class SetMonitoringData: + component: Component + severity: int + type: Monitor + value: float + variable: Variable + custom_data: Optional[CustomData] = None + id: Optional[int] = None + transaction: bool = False + + +@dataclass +class SetMonitoringResult: + component: Component + severity: int + status: SetMonitoringStatus + type: Monitor + variable: Variable + custom_data: Optional[CustomData] = None + id: Optional[int] = None + status_info: Optional[StatusInfo] = None + + +@dataclass +class SetVariableData: + attribute_value: str + component: Component + variable: Variable + attribute_type: Attribute = Attribute.actual + custom_data: Optional[CustomData] = None + + +@dataclass +class SetVariableResult: + attribute_status: SetVariableStatus + component: Component + variable: Variable + attribute_status_info: Optional[StatusInfo] = None + attribute_type: Attribute = Attribute.actual + custom_data: Optional[CustomData] = None + + +@dataclass +class SignedMeterValue: + encoding_method: str + public_key: str + signed_meter_data: str + signing_method: str + custom_data: Optional[CustomData] = None + + +@dataclass +class StatusInfo: + reason_code: str + additional_info: Optional[str] = None + custom_data: Optional[CustomData] = None + + +@dataclass +class TaxRule: + applies_to_energy_fee: bool + applies_to_minimum_maximum_cost: bool + applies_to_overstay_fee: bool + applies_to_parking_fee: bool + tax_rate: RationalNumber + tax_rule_id: int + custom_data: Optional[CustomData] = None + tax_included_in_price: Optional[bool] = None + tax_rule_name: Optional[str] = None + + +@dataclass +class Transaction: + transaction_id: str + charging_state: Optional[ChargingState] = None + custom_data: Optional[CustomData] = None + operation_mode: Optional[OperationMode] = None + remote_start_id: Optional[int] = None + stopped_reason: Optional[Reason] = None + time_spent_charging: Optional[int] = None + + +@dataclass +class UnitOfMeasure: + custom_data: Optional[CustomData] = None + multiplier: int = 0 + unit: str = "Wh" + + +@dataclass +class V2XChargingParameters: + custom_data: Optional[CustomData] = None + ev_max_energy_request: Optional[float] = None + ev_max_v2x_energy_request: Optional[float] = None + ev_min_energy_request: Optional[float] = None + ev_min_v2x_energy_request: Optional[float] = None + ev_target_energy_request: Optional[float] = None + max_charge_current: Optional[float] = None + max_charge_power: Optional[float] = None + max_charge_power_l2: Optional[float] = None + max_charge_power_l3: Optional[float] = None + max_discharge_current: Optional[float] = None + max_discharge_power: Optional[float] = None + max_discharge_power_l2: Optional[float] = None + max_discharge_power_l3: Optional[float] = None + max_voltage: Optional[float] = None + min_charge_current: Optional[float] = None + min_charge_power: Optional[float] = None + min_charge_power_l2: Optional[float] = None + min_charge_power_l3: Optional[float] = None + min_discharge_current: Optional[float] = None + min_discharge_power: Optional[float] = None + min_discharge_power_l2: Optional[float] = None + min_discharge_power_l3: Optional[float] = None + min_voltage: Optional[float] = None + target_soc: Optional[int] = None + + +@dataclass +class V2XFreqWattEntry: + frequency: float + power: float + custom_data: Optional[CustomData] = None + + +@dataclass +class V2XSignalWattEntry: + power: float + signal: int + custom_data: Optional[CustomData] = None + + +@dataclass +class VPN: + key: str + password: str + server: str + type: enums.VPN + user: str + custom_data: Optional[CustomData] = None + group: Optional[str] = None + + +@dataclass +class Variable: + name: str + custom_data: Optional[CustomData] = None + instance: Optional[str] = None + + +@dataclass +class VariableAttribute: + constant: bool = False + custom_data: Optional[CustomData] = None + mutability: Mutability = Mutability.read_write + persistent: bool = False + type: Attribute = Attribute.actual + value: Optional[str] = None + + +@dataclass +class VariableCharacteristics: + data_type: Data + supports_monitoring: bool + custom_data: Optional[CustomData] = None + max_limit: Optional[float] = None + min_limit: Optional[float] = None + unit: Optional[str] = None + values_list: Optional[str] = None + + +@dataclass +class VariableMonitoring: + id: int + severity: int + transaction: bool + type: Monitor + value: float + custom_data: Optional[CustomData] = None diff --git a/ocpp/v21/enums.py b/ocpp/v21/enums.py new file mode 100644 index 000000000..c6ff3838b --- /dev/null +++ b/ocpp/v21/enums.py @@ -0,0 +1,790 @@ +try: + # breaking change introduced in python 3.11 + from enum import StrEnum +except ImportError: # pragma: no cover + from enum import Enum # pragma: no cover + + class StrEnum(str, Enum): # pragma: no cover + pass # pragma: no cover + + +class APNAuthentication(StrEnum): + pap = "PAP" + chap = "CHAP" + none = "NONE" + auto = "AUTO" + + +class Attribute(StrEnum): + actual = "Actual" + target = "Target" + min_set = "MinSet" + max_set = "MaxSet" + + +class AuthorizationStatus(StrEnum): + accepted = "Accepted" + blocked = "Blocked" + expired = "Expired" + invalid = "Invalid" + no_credit = "NoCredit" + not_allowed_type_evse = "NotAllowedTypeEVSE" + not_at_this_location = "NotAtThisLocation" + not_at_this_time = "NotAtThisTime" + concurrent_tx = "ConcurrentTx" + unknown = "Unknown" + + +class AuthorizeCertificateStatus(StrEnum): + accepted = "Accepted" + signature_error = "SignatureError" + certificate_expired = "CertificateExpired" + certificate_revoked = "CertificateRevoked" + no_certificate_available = "NoCertificateAvailable" + cert_chain_error = "CertChainError" + contract_cancelled = "ContractCancelled" + + +class BootReason(StrEnum): + application_reset = "ApplicationReset" + firmware_update = "FirmwareUpdate" + local_reset = "LocalReset" + power_up = "PowerUp" + remote_reset = "RemoteReset" + scheduled_reset = "ScheduledReset" + triggered = "Triggered" + unknown = "Unknown" + watchdog = "Watchdog" + + +class CancelReservationStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class CertificateAction(StrEnum): + install = "Install" + update = "Update" + + +class CertificateSignedStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class CertificateSigningUse(StrEnum): + charging_station_certificate = "ChargingStationCertificate" + v2g_certificate = "V2GCertificate" + + +class ChangeAvailabilityStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + scheduled = "Scheduled" + + +class ChargingLimitSource(StrEnum): + cso = "CSO" + ems = "EMS" + other = "Other" + so = "SO" + + +class ChargingProfileKind(StrEnum): + absolute = "Absolute" + recurring = "Recurring" + relative = "Relative" + dynamic = "Dynamic" + + +class ChargingProfilePurpose(StrEnum): + charging_station_external_constraints = "ChargingStationExternalConstraints" + charging_station_max_profile = "ChargingStationMaxProfile" + tx_default_profile = "TxDefaultProfile" + tx_profile = "TxProfile" + priority_charging = "PriorityCharging" + local_generation = "LocalGeneration" + + +class ChargingProfileStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class ChargingRateUnit(StrEnum): + w = "W" + a = "A" + + +class ChargingState(StrEnum): + ev_connected = "EVConnected" + charging = "Charging" + suspended_ev = "SuspendedEV" + suspended_evse = "SuspendedEVSE" + idle = "Idle" + + +class ClearCacheStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class ClearChargingProfileStatus(StrEnum): + accepted = "Accepted" + unknown = "Unknown" + + +class ClearMessageStatus(StrEnum): + accepted = "Accepted" + unknown = "Unknown" + + +class ClearMonitoringStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + not_found = "NotFound" + + +class ComponentCriterion(StrEnum): + active = "Active" + available = "Available" + enabled = "Enabled" + problem = "Problem" + + +class Connector(StrEnum): + c_ccs1 = "cCCS1" + c_ccs2 = "cCCS2" + c_g105 = "cG105" + c_tesla = "cTesla" + c_type1 = "cType1" + c_type2 = "cType2" + s309_1_p_16a = "s309-1P-16A" + s309_1_p_32a = "s309-1P-32A" + s309_3_p_16a = "s309-3P-16A" + s309_3_p_32a = "s309-3P-32A" + s_bs1361 = "sBS1361" + s_cee_7_7 = "sCEE-7-7" + s_type2 = "sType2" + s_type3 = "sType3" + other1_ph_max16a = "Other1PhMax16A" + other1_ph_over16a = "Other1PhOver16A" + other3_ph = "Other3Ph" + pan = "Pan" + w_inductive = "wInductive" + w_resonant = "wResonant" + undetermined = "Undetermined" + unknown = "Unknown" + + +class ConnectorStatus(StrEnum): + available = "Available" + occupied = "Occupied" + reserved = "Reserved" + unavailable = "Unavailable" + faulted = "Faulted" + + +class ControlMode(StrEnum): + scheduled = "Scheduled" + dynamic = "Dynamic" + + +class CostKind(StrEnum): + carbon_dioxide_emission = "CarbonDioxideEmission" + relative_price_percentage = "RelativePricePercentage" + renewable_generation_percentage = "RenewableGenerationPercentage" + + +class CustomerInformationStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + invalid = "Invalid" + + +class Data(StrEnum): + string = "string" + decimal = "decimal" + integer = "integer" + date_time = "dateTime" + boolean = "boolean" + option_list = "OptionList" + sequence_list = "SequenceList" + member_list = "MemberList" + + +class DataTransferStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + unknown_message_id = "UnknownMessageId" + unknown_vendor_id = "UnknownVendorId" + + +class DeleteCertificateStatus(StrEnum): + accepted = "Accepted" + failed = "Failed" + not_found = "NotFound" + + +class DisplayMessageStatus(StrEnum): + accepted = "Accepted" + not_supported_message_format = "NotSupportedMessageFormat" + rejected = "Rejected" + not_supported_priority = "NotSupportedPriority" + not_supported_state = "NotSupportedState" + unknown_transaction = "UnknownTransaction" + + +class EnergyTransferMode(StrEnum): + ac_single_phase = "AC_single_phase" + ac_two_phase = "AC_two_phase" + ac_three_phase = "AC_three_phase" + dc = "DC" + ac_single_phase_bpt = "AC_single_phase_BPT" + ac_two_phase_bpt = "AC_two_phase_BPT" + ac_three_phase_bpt = "AC_three_phase_BPT" + dc_bpt = "DC_BPT" + dc_acdp = "DC_ACDP" + dc_acdp_bpt = "DC_ACDP_BPT" + wpt = "WPT" + + +class EventNotification(StrEnum): + hard_wired_notification = "HardWiredNotification" + hard_wired_monitor = "HardWiredMonitor" + preconfigured_monitor = "PreconfiguredMonitor" + custom_monitor = "CustomMonitor" + + +class EventTrigger(StrEnum): + alerting = "Alerting" + delta = "Delta" + periodic = "Periodic" + + +class FirmwareStatus(StrEnum): + downloaded = "Downloaded" + download_failed = "DownloadFailed" + downloading = "Downloading" + download_scheduled = "DownloadScheduled" + download_paused = "DownloadPaused" + idle = "Idle" + installation_failed = "InstallationFailed" + installing = "Installing" + installed = "Installed" + install_rebooting = "InstallRebooting" + install_scheduled = "InstallScheduled" + install_verification_failed = "InstallVerificationFailed" + invalid_signature = "InvalidSignature" + signature_verified = "SignatureVerified" + + +class GenericDeviceModelStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + not_supported = "NotSupported" + empty_result_set = "EmptyResultSet" + + +class GenericStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class GetCertificateIdUse(StrEnum): + v2g_root_certificate = "V2GRootCertificate" + mo_root_certificate = "MORootCertificate" + csms_root_certificate = "CSMSRootCertificate" + v2g_certificate_chain = "V2GCertificateChain" + manufacturer_root_certificate = "ManufacturerRootCertificate" + oem_root_certificate = "OEMRootCertificate" + + +class GetCertificateStatus(StrEnum): + accepted = "Accepted" + failed = "Failed" + + +class GetChargingProfileStatus(StrEnum): + accepted = "Accepted" + no_profiles = "NoProfiles" + + +class GetDisplayMessagesStatus(StrEnum): + accepted = "Accepted" + unknown = "Unknown" + + +class GetInstalledCertificateStatus(StrEnum): + accepted = "Accepted" + not_found = "NotFound" + + +class GetVariableStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + unknown_component = "UnknownComponent" + unknown_variable = "UnknownVariable" + not_supported_attribute_type = "NotSupportedAttributeType" + + +class HashAlgorithm(StrEnum): + sha256 = "SHA256" + sha384 = "SHA384" + sha512 = "SHA512" + + +class IdToken(StrEnum): + central = "Central" + e_maid = "eMAID" + iso14443 = "ISO14443" + iso15693 = "ISO15693" + key_code = "KeyCode" + local = "Local" + mac_address = "MacAddress" + no_authorization = "NoAuthorization" + evccid = "EVCCID" + nema = "NEMA" + + +class InstallCertificateStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + failed = "Failed" + + +class InstallCertificateUse(StrEnum): + v2g_root_certificate = "V2GRootCertificate" + mo_root_certificate = "MORootCertificate" + csms_root_certificate = "CSMSRootCertificate" + oem_root_certificate = "OEMRootCertificate" + manufacturer_root_certificate = "ManufacturerRootCertificate" + + +class Iso15118EVCertificateStatus(StrEnum): + accepted = "Accepted" + failed = "Failed" + + +class Location(StrEnum): + body = "Body" + cable = "Cable" + ev = "EV" + inlet = "Inlet" + outlet = "Outlet" + local_grid = "LocalGrid" + + +class Log(StrEnum): + diagnostics_log = "DiagnosticsLog" + security_log = "SecurityLog" + data_collector_log = "DataCollectorLog" + + +class LogStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + accepted_canceled = "AcceptedCanceled" + + +class Measurand(StrEnum): + current_export = "Current.Export" + current_export_offered = "Current.Export.Offered" + current_export_minimum = "Current.Export.Minimum" + current_import = "Current.Import" + current_import_offered = "Current.Import.Offered" + current_import_minimum = "Current.Import.Minimum" + current_offered = "Current.Offered" + display_present_soc = "Display.PresentSOC" + display_minimum_soc = "Display.MinimumSOC" + display_target_soc = "Display.TargetSOC" + display_maximum_soc = "Display.MaximumSOC" + display_remaining_time_to_minimum_soc = "Display.RemainingTimeToMinimumSOC" + display_remaining_time_to_target_soc = "Display.RemainingTimeToTargetSOC" + display_remaining_time_to_maximum_soc = "Display.RemainingTimeToMaximumSOC" + display_charging_complete = "Display.ChargingComplete" + display_battery_energy_capacity = "Display.BatteryEnergyCapacity" + display_inlet_hot = "Display.InletHot" + energy_active_export_interval = "Energy.Active.Export.Interval" + energy_active_export_register = "Energy.Active.Export.Register" + energy_active_import_interval = "Energy.Active.Import.Interval" + energy_active_import_register = "Energy.Active.Import.Register" + energy_active_net = "Energy.Active.Net" + energy_active_setpoint_interval = "Energy.Active.Setpoint.Interval" + energy_apparent_export = "Energy.Apparent.Export" + energy_apparent_import = "Energy.Apparent.Import" + energy_apparent_net = "Energy.Apparent.Net" + energy_reactive_export_interval = "Energy.Reactive.Export.Interval" + energy_reactive_export_register = "Energy.Reactive.Export.Register" + energy_reactive_import_interval = "Energy.Reactive.Import.Interval" + energy_reactive_import_register = "Energy.Reactive.Import.Register" + energy_reactive_net = "Energy.Reactive.Net" + energy_request_target = "EnergyRequest.Target" + energy_request_minimum = "EnergyRequest.Minimum" + energy_request_maximum = "EnergyRequest.Maximum" + energy_request_minimum_v2x = "EnergyRequest.Minimum.V2X" + energy_request_maximum_v2x = "EnergyRequest.Maximum.V2X" + energy_request_bulk = "EnergyRequest.Bulk" + frequency = "Frequency" + power_active_export = "Power.Active.Export" + power_active_import = "Power.Active.Import" + power_active_setpoint = "Power.Active.Setpoint" + power_active_residual = "Power.Active.Residual" + power_export_minimum = "Power.Export.Minimum" + power_export_offered = "Power.Export.Offered" + power_factor = "Power.Factor" + power_import_offered = "Power.Import.Offered" + power_import_minimum = "Power.Import.Minimum" + power_offered = "Power.Offered" + power_reactive_export = "Power.Reactive.Export" + power_reactive_import = "Power.Reactive.Import" + soc = "SoC" + voltage = "Voltage" + voltage_minimum = "Voltage.Minimum" + voltage_maximum = "Voltage.Maximum" + + +class MessageFormat(StrEnum): + ascii = "ASCII" + html = "HTML" + uri = "URI" + utf8 = "UTF8" + + +class MessagePriority(StrEnum): + always_front = "AlwaysFront" + in_front = "InFront" + normal_cycle = "NormalCycle" + + +class MessageState(StrEnum): + charging = "Charging" + faulted = "Faulted" + idle = "Idle" + unavailable = "Unavailable" + + +class MessageTrigger(StrEnum): + boot_notification = "BootNotification" + log_status_notification = "LogStatusNotification" + firmware_status_notification = "FirmwareStatusNotification" + heartbeat = "Heartbeat" + meter_values = "MeterValues" + sign_charging_station_certificate = "SignChargingStationCertificate" + sign_v2g_certificate = "SignV2GCertificate" + status_notification = "StatusNotification" + transaction_event = "TransactionEvent" + sign_combined_certificate = "SignCombinedCertificate" + publish_firmware_status_notification = "PublishFirmwareStatusNotification" + + +class MobilityNeedsMode(StrEnum): + evcc = "EVCC" + evcc_secc = "EVCC_SECC" + + +class Monitor(StrEnum): + upper_threshold = "UpperThreshold" + lower_threshold = "LowerThreshold" + delta = "Delta" + periodic = "Periodic" + periodic_clock_aligned = "PeriodicClockAligned" + + +class MonitoringBase(StrEnum): + all = "All" + factory_default = "FactoryDefault" + hard_wired_only = "HardWiredOnly" + + +class MonitoringCriterion(StrEnum): + threshold_monitoring = "ThresholdMonitoring" + delta_monitoring = "DeltaMonitoring" + periodic_monitoring = "PeriodicMonitoring" + + +class Mutability(StrEnum): + read_only = "ReadOnly" + write_only = "WriteOnly" + read_write = "ReadWrite" + + +class NotifyAllowedEnergyTransferStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class NotifyCRLStatus(StrEnum): + available = "Available" + unavailable = "Unavailable" + + +class NotifyEVChargingNeedsStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + processing = "Processing" + no_charging_profile = "NoChargingProfile" + + +class OCPPTransport(StrEnum): + soap = "SOAP" + json = "JSON" + + +class OCPPVersion(StrEnum): + ocpp12 = "OCPP12" + ocpp15 = "OCPP15" + ocpp16 = "OCPP16" + ocpp20 = "OCPP20" + + +class OperationMode(StrEnum): + idle = "Idle" + charging_only = "ChargingOnly" + central_setpoint = "CentralSetpoint" + external_setpoint = "ExternalSetpoint" + external_limits = "ExternalLimits" + central_frequency = "CentralFrequency" + local_frequency = "LocalFrequency" + local_load_balancing = "LocalLoadBalancing" + + +class OperationalStatus(StrEnum): + inoperative = "Inoperative" + operative = "Operative" + + +class Phase(StrEnum): + l1 = "L1" + l2 = "L2" + l3 = "L3" + n = "N" + l1_n = "L1-N" + l2_n = "L2-N" + l3_n = "L3-N" + l1_l2 = "L1-L2" + l2_l3 = "L2-L3" + l3_l1 = "L3-L1" + + +class PreconditioningStatus(StrEnum): + unknown = "Unknown" + ready = "Ready" + not_ready = "NotReady" + preconditioning = "Preconditioning" + + +class Pricing(StrEnum): + no_pricing = "NoPricing" + absolute_pricing = "AbsolutePricing" + price_levels = "PriceLevels" + + +class PriorityChargingStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + no_profile = "NoProfile" + + +class PublishFirmwareStatus(StrEnum): + idle = "Idle" + download_scheduled = "DownloadScheduled" + downloading = "Downloading" + downloaded = "Downloaded" + published = "Published" + download_failed = "DownloadFailed" + download_paused = "DownloadPaused" + invalid_checksum = "InvalidChecksum" + checksum_verified = "ChecksumVerified" + publish_failed = "PublishFailed" + + +class ReadingContext(StrEnum): + interruption_begin = "Interruption.Begin" + interruption_end = "Interruption.End" + other = "Other" + sample_clock = "Sample.Clock" + sample_periodic = "Sample.Periodic" + transaction_begin = "Transaction.Begin" + transaction_end = "Transaction.End" + trigger = "Trigger" + + +class Reason(StrEnum): + de_authorized = "DeAuthorized" + emergency_stop = "EmergencyStop" + energy_limit_reached = "EnergyLimitReached" + ev_disconnected = "EVDisconnected" + ground_fault = "GroundFault" + immediate_reset = "ImmediateReset" + master_pass = "MasterPass" + local = "Local" + out_of_credit = "OutOfCredit" + other = "Other" + overcurrent_fault = "OvercurrentFault" + power_loss = "PowerLoss" + power_quality = "PowerQuality" + reboot = "Reboot" + remote = "Remote" + soc_limit_reached = "SOCLimitReached" + stopped_by_ev = "StoppedByEV" + time_limit_reached = "TimeLimitReached" + timeout = "Timeout" + charging_needs_not_accepted = "ChargingNeedsNotAccepted" + + +class RecurrencyKind(StrEnum): + daily = "Daily" + weekly = "Weekly" + + +class RegistrationStatus(StrEnum): + accepted = "Accepted" + pending = "Pending" + rejected = "Rejected" + + +class ReportBase(StrEnum): + configuration_inventory = "ConfigurationInventory" + full_inventory = "FullInventory" + summary_inventory = "SummaryInventory" + + +class RequestStartStopStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + + +class ReservationUpdateStatus(StrEnum): + expired = "Expired" + removed = "Removed" + + +class ReserveNowStatus(StrEnum): + accepted = "Accepted" + faulted = "Faulted" + occupied = "Occupied" + rejected = "Rejected" + unavailable = "Unavailable" + + +class Reset(StrEnum): + immediate = "Immediate" + on_idle = "OnIdle" + + +class ResetStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + scheduled = "Scheduled" + + +class SendLocalListStatus(StrEnum): + accepted = "Accepted" + failed = "Failed" + version_mismatch = "VersionMismatch" + + +class SetMonitoringStatus(StrEnum): + accepted = "Accepted" + unknown_component = "UnknownComponent" + unknown_variable = "UnknownVariable" + unsupported_monitor_type = "UnsupportedMonitorType" + rejected = "Rejected" + duplicate = "Duplicate" + + +class SetNetworkProfileStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + failed = "Failed" + + +class SetVariableStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + unknown_component = "UnknownComponent" + unknown_variable = "UnknownVariable" + not_supported_attribute_type = "NotSupportedAttributeType" + reboot_required = "RebootRequired" + + +class TransactionEvent(StrEnum): + ended = "Ended" + started = "Started" + updated = "Updated" + + +class TriggerMessageStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + not_implemented = "NotImplemented" + + +class TriggerReason(StrEnum): + abnormal_condition = "AbnormalCondition" + authorized = "Authorized" + cable_plugged_in = "CablePluggedIn" + charging_rate_changed = "ChargingRateChanged" + charging_state_changed = "ChargingStateChanged" + deauthorized = "Deauthorized" + energy_limit_reached = "EnergyLimitReached" + ev_communication_lost = "EVCommunicationLost" + ev_connect_timeout = "EVConnectTimeout" + ev_departed = "EVDeparted" + ev_detected = "EVDetected" + meter_value_clock = "MeterValueClock" + meter_value_periodic = "MeterValuePeriodic" + remote_start = "RemoteStart" + remote_stop = "RemoteStop" + reset_command = "ResetCommand" + signed_data_received = "SignedDataReceived" + stop_authorized = "StopAuthorized" + time_limit_reached = "TimeLimitReached" + trigger = "Trigger" + unlock_command = "UnlockCommand" + operation_mode_changed = "OperationModeChanged" + + +class UnlockStatus(StrEnum): + unlocked = "Unlocked" + unlock_failed = "UnlockFailed" + ongoing_authorized_transaction = "OngoingAuthorizedTransaction" + unknown_connector = "UnknownConnector" + + +class UnpublishFirmwareStatus(StrEnum): + download_ongoing = "DownloadOngoing" + no_firmware = "NoFirmware" + unpublished = "Unpublished" + + +class Update(StrEnum): + differential = "Differential" + full = "Full" + + +class UpdateFirmwareStatus(StrEnum): + accepted = "Accepted" + rejected = "Rejected" + accepted_canceled = "AcceptedCanceled" + invalid_certificate = "InvalidCertificate" + revoked_certificate = "RevokedCertificate" + + +class UploadLogStatus(StrEnum): + bad_message = "BadMessage" + idle = "Idle" + not_supported_operation = "NotSupportedOperation" + permission_denied = "PermissionDenied" + uploaded = "Uploaded" + upload_failure = "UploadFailure" + uploading = "Uploading" + accepted_canceled = "AcceptedCanceled" + + +class VPN(StrEnum): + ik_ev2 = "IKEv2" + ip_sec = "IPSec" + l2_tp = "L2TP" + pptp = "PPTP" diff --git a/poetry.lock b/poetry.lock index 2374d7c58..7494d5527 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,42 +1,55 @@ +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. + [[package]] name = "alabaster" version = "0.7.12" description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] [[package]] name = "asynctest" version = "0.13.0" description = "Enhance the standard unittest package with features for testing asyncio libraries" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, + {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, +] [[package]] name = "attrs" version = "22.2.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, +] [package.extras] -cov = ["attrs", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs"] -docs = ["furo", "sphinx", "myst-parser", "zope.interface", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] -tests = ["attrs", "zope.interface"] -tests-no-zope = ["hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist", "cloudpickle", "mypy (>=0.971,<0.990)", "pytest-mypy-plugins"] -tests_no_zope = ["hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist", "cloudpickle", "mypy (>=0.971,<0.990)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] [[package]] name = "babel" version = "2.11.0" description = "Internationalization utilities" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, + {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, +] [package.dependencies] pytz = ">=2015.7" @@ -45,9 +58,22 @@ pytz = ">=2015.7" name = "black" version = "22.12.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, + {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"}, + {file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"}, + {file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"}, + {file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"}, + {file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"}, + {file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"}, + {file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"}, + {file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"}, + {file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"}, + {file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"}, + {file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"}, +] [package.dependencies] click = ">=8.0.0" @@ -68,28 +94,37 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, +] [[package]] name = "charset-normalizer" version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" optional = false python-versions = ">=3.6.0" +files = [ + {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, +] [package.extras] -unicode_backport = ["unicodedata2"] +unicode-backport = ["unicodedata2"] [[package]] name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -99,17 +134,72 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "coverage" version = "7.0.0" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "coverage-7.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2569682d6ea9628da8d6ba38579a48b1e53081226ec7a6c82b5024b3ce5009f"}, + {file = "coverage-7.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ec256a592b497f26054195f7d7148892aca8c4cdcc064a7cc66ef7a0455b811"}, + {file = "coverage-7.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5885a4ceb6dde34271bb0adafa4a248a7f589c89821e9da3110c39f92f41e21b"}, + {file = "coverage-7.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d43d406a4d73aa7f855fa44fa77ff47e739b565b2af3844600cdc016d01e46b9"}, + {file = "coverage-7.0.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18df11efa615b79b9ecc13035a712957ff6283f7b244e57684e1c092869f541"}, + {file = "coverage-7.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f6a4bf5bdee93f6817797beba7086292c2ebde6df0d5822e0c33f8b05415c339"}, + {file = "coverage-7.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:33efe89cd0efef016db19d8d05aa46631f76793de90a61b6717acb202b36fe60"}, + {file = "coverage-7.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96b5b1f1079e48f56bfccf103bcf44d48b9eb5163f1ea523fad580f15d3fe5e0"}, + {file = "coverage-7.0.0-cp310-cp310-win32.whl", hash = "sha256:fb85b7a7a4b204bd59d6d0b0c8d87d9ffa820da225e691dfaffc3137dc05b5f6"}, + {file = "coverage-7.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:793dcd9d42035746fc7637df4336f7581df19d33c5c5253cf988c99d8e93a8ba"}, + {file = "coverage-7.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d564142a03d3bc8913499a458e931b52ddfe952f69b6cd4b24d810fd2959044a"}, + {file = "coverage-7.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0a8b0e86bede874bf5da566b02194fbb12dd14ce3585cabd58452007f272ba81"}, + {file = "coverage-7.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e645c73cbfc4577d93747d3f793115acf6f907a7eb9208fa807fdcf2da1964a4"}, + {file = "coverage-7.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de06e7585abe88c6d38c1b73ce4c3cb4c1a79fbb0da0d0f8e8689ef5729ec60d"}, + {file = "coverage-7.0.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a30b646fbdd5bc52f506e149fa4fbdef82432baf6b81774e61ec4e3b43b9cbde"}, + {file = "coverage-7.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:db8141856dc9be0917413df7200f53accf1d84c8b156868e6af058a1ea8e903a"}, + {file = "coverage-7.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:59e71912c7fc78d08a567ee65656123878f49ca1b5672e660ea70bf8dfbebf8f"}, + {file = "coverage-7.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b8f7cd942dda3795fc9eadf303cc53a422ac057e3b70c2ad6d4276ec6a83a541"}, + {file = "coverage-7.0.0-cp311-cp311-win32.whl", hash = "sha256:bf437a04b9790d3c9cd5b48e9ce9aa84229040e3ae7d6c670a55118906113c5a"}, + {file = "coverage-7.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:a7e1bb36b4e57a2d304322021b35d4e4a25fa0d501ba56e8e51efaebf4480556"}, + {file = "coverage-7.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:215f40ef86f1958a1151fa7fad2b4f2f99534c4e10a34a1e065eba3f19ef8868"}, + {file = "coverage-7.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae088eb1cbdad8206931b1bf3f11dee644e038a9300be84d3e705e29356e5b1d"}, + {file = "coverage-7.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9071e197faa24837b967bc9aa0b9ef961f805a75f1ee3ea1f3367f55cd46c3c"}, + {file = "coverage-7.0.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f1e6d9c70d45a960d3f3d781ea62b167fdf2e0e1f6bb282b96feea653adb923"}, + {file = "coverage-7.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9fadd15f9fcfd7b16d9cccce9f5e6ec6f9b8df860633ad9aa62c2b14c259560f"}, + {file = "coverage-7.0.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:10b6246cae61896ab4c7568e498e492cbb73a2dfa4c3af79141c43cf806f929a"}, + {file = "coverage-7.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a8785791c2120af114ea7a06137f7778632e568a5aa2bbfc3b46c573b702af74"}, + {file = "coverage-7.0.0-cp37-cp37m-win32.whl", hash = "sha256:30220518dd89c4878908d73f5f3d1269f86e9e045354436534587a18c7b9da85"}, + {file = "coverage-7.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bc904aa96105d73357de03de76336b1e3db28e2b12067d36625fd9646ab043fd"}, + {file = "coverage-7.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2331b7bd84a1be79bd17ca8e103ce38db8cbf7cb354dc56e651ba489cf849212"}, + {file = "coverage-7.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e907db8bdd0ad1253a33c20fdc5f0f6209d271114a9c6f1fcdf96617343f7ca0"}, + {file = "coverage-7.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0deee68e0dae1d6e3fe6943c76d7e66fbeb6519bd08e4e5366bcc28a8a9aca"}, + {file = "coverage-7.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fff0f08bc5ffd0d78db821971472b4adc2ee876b86f743e46d634fb8e3c22f"}, + {file = "coverage-7.0.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a290b7921c1c05787b953e5854d394e887df40696f21381cc33c4e2179bf50ac"}, + {file = "coverage-7.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:100546219af59d2ad82d4575de03a303eb27b75ea36ffbd1677371924d50bcbc"}, + {file = "coverage-7.0.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c1ba6e63b831112b9484ff5905370d89e43d4316bac76d403031f60d61597466"}, + {file = "coverage-7.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c685fc17d6f4f1a3833e9dac27d0b931f7ccb52be6c30d269374203c7d0204a2"}, + {file = "coverage-7.0.0-cp38-cp38-win32.whl", hash = "sha256:8938f3a10f45019b502020ba9567b97b6ecc8c76b664b421705c5406d4f92fe8"}, + {file = "coverage-7.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:c4b63888bef2928d0eca12cbce0760cfb696acb4fe226eb55178b6a2a039328a"}, + {file = "coverage-7.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cda63459eb20652b22e038729a8f5063862c189a3963cb042a764b753172f75e"}, + {file = "coverage-7.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e06abac1a4aec1ff989131e43ca917fc7bd296f34bf0cfe86cbf74343b21566d"}, + {file = "coverage-7.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b94ad926e933976627f040f96dd1d9b0ac91f8d27e868c30a28253b9b6ac2d"}, + {file = "coverage-7.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6b4af31fb49a2ae8de1cd505fa66c403bfcc5066e845ac19d8904dcfc9d40da"}, + {file = "coverage-7.0.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36b62f0220459e528ad5806cc7dede71aa716e067d2cb10cb4a09686b8791fba"}, + {file = "coverage-7.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:43ec1935c6d6caab4f3bc126d20bd709c0002a175d62208ebe745be37a826a41"}, + {file = "coverage-7.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8593c9baf1f0f273afa22f5b45508b76adc7b8e94e17e7d98fbe1e3cd5812af2"}, + {file = "coverage-7.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fee283cd36c3f14422d9c1b51da24ddbb5e1eed89ad2480f6a9f115df38b5df8"}, + {file = "coverage-7.0.0-cp39-cp39-win32.whl", hash = "sha256:97c0b001ff15b8e8882995fc07ac0a08c8baf8b13c1145f3f12e0587bbb0e335"}, + {file = "coverage-7.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:8dbf83a4611c591b5de65069b6fd4dd3889200ed270cd2f7f5ac765d3842889f"}, + {file = "coverage-7.0.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:bcaf18e46668057051a312c714a4548b81f7e8fb3454116ad97be7562d2a99e4"}, + {file = "coverage-7.0.0.tar.gz", hash = "sha256:9a175da2a7320e18fc3ee1d147639a2b3a8f037e508c96aa2da160294eb50e17"}, +] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -121,17 +211,23 @@ toml = ["tomli"] name = "docutils" version = "0.17.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, +] [[package]] name = "exceptiongroup" version = "1.1.0" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, + {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, +] [package.extras] test = ["pytest (>=6)"] @@ -140,9 +236,12 @@ test = ["pytest (>=6)"] name = "flake8" version = "5.0.4" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.6.1" +files = [ + {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, + {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, +] [package.dependencies] importlib-metadata = {version = ">=1.1.0,<4.3", markers = "python_version < \"3.8\""} @@ -154,78 +253,99 @@ pyflakes = ">=2.5.0,<2.6.0" name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] [[package]] name = "importlib-metadata" version = "4.2.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, + {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, +] [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] [[package]] name = "importlib-resources" version = "5.10.1" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "importlib_resources-5.10.1-py3-none-any.whl", hash = "sha256:c09b067d82e72c66f4f8eb12332f5efbebc9b007c0b6c40818108c9870adc363"}, + {file = "importlib_resources-5.10.1.tar.gz", hash = "sha256:32bb095bda29741f6ef0e5278c42df98d135391bee5f932841efc0041f748dc3"}, +] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [[package]] name = "iniconfig" version = "1.1.1" description = "iniconfig: brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] [[package]] name = "isort" version = "5.11.4" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.7.0" +files = [ + {file = "isort-5.11.4-py3-none-any.whl", hash = "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b"}, + {file = "isort-5.11.4.tar.gz", hash = "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6"}, +] [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] pipfile-deprecated-finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] [package.dependencies] MarkupSafe = ">=2.0" @@ -237,9 +357,12 @@ i18n = ["Babel (>=2.7)"] name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, +] [package.dependencies] attrs = ">=17.4.0" @@ -257,69 +380,131 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "markupsafe" version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] [[package]] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] [[package]] name = "mypy-extensions" version = "0.4.3" description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] [[package]] name = "packaging" version = "22.0" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "packaging-22.0-py3-none-any.whl", hash = "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3"}, + {file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"}, +] [[package]] name = "pathspec" version = "0.10.3" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, + {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, +] [[package]] name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] [[package]] name = "platformdirs" version = "2.6.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "platformdirs-2.6.0-py3-none-any.whl", hash = "sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca"}, + {file = "platformdirs-2.6.0.tar.gz", hash = "sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e"}, +] [package.extras] -docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx-autodoc-typehints (>=1.19.4)", "sphinx (>=5.3)"] -test = ["appdirs (==1.4.4)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest (>=7.2)"] +docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] +test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} @@ -332,25 +517,34 @@ testing = ["pytest", "pytest-benchmark"] name = "pycodestyle" version = "2.9.1" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, + {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, +] [[package]] name = "pyflakes" version = "2.5.0" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, +] [[package]] name = "pygments" version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, + {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, +] [package.extras] plugins = ["importlib-metadata"] @@ -359,17 +553,43 @@ plugins = ["importlib-metadata"] name = "pyrsistent" version = "0.19.2" description = "Persistent/Functional/Immutable data structures" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pyrsistent-0.19.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d6982b5a0237e1b7d876b60265564648a69b14017f3b5f908c5be2de3f9abb7a"}, + {file = "pyrsistent-0.19.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d5730b0507d9285a96fca9716310d572e5464cadd19f22b63a6976254d77a"}, + {file = "pyrsistent-0.19.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:055ab45d5911d7cae397dc418808d8802fb95262751872c841c170b0dbf51eed"}, + {file = "pyrsistent-0.19.2-cp310-cp310-win32.whl", hash = "sha256:456cb30ca8bff00596519f2c53e42c245c09e1a4543945703acd4312949bfd41"}, + {file = "pyrsistent-0.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:b39725209e06759217d1ac5fcdb510e98670af9e37223985f330b611f62e7425"}, + {file = "pyrsistent-0.19.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aede922a488861de0ad00c7630a6e2d57e8023e4be72d9d7147a9fcd2d30712"}, + {file = "pyrsistent-0.19.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:879b4c2f4d41585c42df4d7654ddffff1239dc4065bc88b745f0341828b83e78"}, + {file = "pyrsistent-0.19.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43bec251bbd10e3cb58ced80609c5c1eb238da9ca78b964aea410fb820d00d6"}, + {file = "pyrsistent-0.19.2-cp37-cp37m-win32.whl", hash = "sha256:d690b18ac4b3e3cab73b0b7aa7dbe65978a172ff94970ff98d82f2031f8971c2"}, + {file = "pyrsistent-0.19.2-cp37-cp37m-win_amd64.whl", hash = "sha256:3ba4134a3ff0fc7ad225b6b457d1309f4698108fb6b35532d015dca8f5abed73"}, + {file = "pyrsistent-0.19.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a178209e2df710e3f142cbd05313ba0c5ebed0a55d78d9945ac7a4e09d923308"}, + {file = "pyrsistent-0.19.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e371b844cec09d8dc424d940e54bba8f67a03ebea20ff7b7b0d56f526c71d584"}, + {file = "pyrsistent-0.19.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111156137b2e71f3a9936baf27cb322e8024dac3dc54ec7fb9f0bcf3249e68bb"}, + {file = "pyrsistent-0.19.2-cp38-cp38-win32.whl", hash = "sha256:e5d8f84d81e3729c3b506657dddfe46e8ba9c330bf1858ee33108f8bb2adb38a"}, + {file = "pyrsistent-0.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:9cd3e9978d12b5d99cbdc727a3022da0430ad007dacf33d0bf554b96427f33ab"}, + {file = "pyrsistent-0.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f1258f4e6c42ad0b20f9cfcc3ada5bd6b83374516cd01c0960e3cb75fdca6770"}, + {file = "pyrsistent-0.19.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21455e2b16000440e896ab99e8304617151981ed40c29e9507ef1c2e4314ee95"}, + {file = "pyrsistent-0.19.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd880614c6237243ff53a0539f1cb26987a6dc8ac6e66e0c5a40617296a045e"}, + {file = "pyrsistent-0.19.2-cp39-cp39-win32.whl", hash = "sha256:71d332b0320642b3261e9fee47ab9e65872c2bd90260e5d225dabeed93cbd42b"}, + {file = "pyrsistent-0.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:dec3eac7549869365fe263831f576c8457f6c833937c68542d08fde73457d291"}, + {file = "pyrsistent-0.19.2-py3-none-any.whl", hash = "sha256:ea6b79a02a28550c98b6ca9c35b9f492beaa54d7c5c9e9949555893c8a9234d0"}, + {file = "pyrsistent-0.19.2.tar.gz", hash = "sha256:bfa0351be89c9fcbcb8c9879b826f4353be10f58f8a677efab0c017bf7137ec2"}, +] [[package]] name = "pytest" version = "7.2.0" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, + {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, +] [package.dependencies] attrs = ">=19.2.0" @@ -388,9 +608,12 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2. name = "pytest-asyncio" version = "0.20.3" description = "Pytest support for asyncio" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-asyncio-0.20.3.tar.gz", hash = "sha256:83cbf01169ce3e8eb71c6c278ccb0574d1a7a3bb8eaaf5e50e0ad342afb33b36"}, + {file = "pytest_asyncio-0.20.3-py3-none-any.whl", hash = "sha256:f129998b209d04fcc65c96fc85c11e5316738358909a8399e93be553d7656442"}, +] [package.dependencies] pytest = ">=6.1.0" @@ -398,38 +621,47 @@ typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] +testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] [[package]] name = "pytest-cov" version = "4.0.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, + {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, +] [package.dependencies] coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytz" version = "2022.7" description = "World timezone definitions, modern and historical" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "pytz-2022.7-py2.py3-none-any.whl", hash = "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd"}, + {file = "pytz-2022.7.tar.gz", hash = "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a"}, +] [[package]] name = "requests" version = "2.28.1" description = "Python HTTP for Humans." -category = "dev" optional = false python-versions = ">=3.7, <4" +files = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] [package.dependencies] certifi = ">=2017.4.17" @@ -439,23 +671,45 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "setuptools" +version = "68.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] [[package]] name = "sphinx" version = "2.4.5" description = "Python documentation generator" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "Sphinx-2.4.5-py3-none-any.whl", hash = "sha256:02d7e9dc5f30caa42a682b26de408b755a55c7b07f356a30a3b6300bf7d4740e"}, + {file = "Sphinx-2.4.5.tar.gz", hash = "sha256:b00394e90463e7482c4cf59e7db1c8604baeca1468abfc062904dedc1cea6fcc"}, +] [package.dependencies] alabaster = ">=0.7,<0.8" @@ -467,6 +721,7 @@ Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" requests = ">=2.5.0" +setuptools = "*" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" @@ -477,258 +732,263 @@ sphinxcontrib-serializinghtml = "*" [package.extras] docs = ["sphinxcontrib-websupport"] -test = ["pytest (<5.3.3)", "pytest-cov", "html5lib", "flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.761)", "docutils-stubs"] +test = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-import-order", "html5lib", "mypy (>=0.761)", "pytest (<5.3.3)", "pytest-cov"] [[package]] name = "sphinxcontrib-applehelp" version = "1.0.2" description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" version = "2.0.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, + {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, +] [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest", "html5lib"] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] [package.extras] -test = ["pytest", "flake8", "mypy"] +test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" optional = false python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] [[package]] name = "typed-ast" version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, +] [[package]] name = "typing-extensions" version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, +] [[package]] name = "urllib3" version = "1.26.13" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, + {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, +] [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "websockets" +version = "11.0.3" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"}, + {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"}, + {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"}, + {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"}, + {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"}, + {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"}, + {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"}, + {file = "websockets-11.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af"}, + {file = "websockets-11.0.3-cp37-cp37m-win32.whl", hash = "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f"}, + {file = "websockets-11.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788"}, + {file = "websockets-11.0.3-cp38-cp38-win32.whl", hash = "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74"}, + {file = "websockets-11.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"}, + {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"}, + {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"}, + {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"}, + {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, +] + [[package]] name = "zipp" version = "3.11.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, + {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, +] [package.extras] -docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "pytest-flake8"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] -lock-version = "1.1" +lock-version = "2.0" python-versions = "^3.7" -content-hash = "1faa57c1b0477263f6f1766bbb1559aed9a250182754f3d735bf65abba91a0a1" - -[metadata.files] -alabaster = [ - {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, - {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, -] -asynctest = [ - {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, - {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, -] -attrs = [] -babel = [] -black = [] -certifi = [] -charset-normalizer = [] -click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] -colorama = [] -coverage = [] -docutils = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, -] -exceptiongroup = [] -flake8 = [] -idna = [] -imagesize = [] -importlib-metadata = [ - {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, - {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, -] -importlib-resources = [] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -isort = [] -jinja2 = [] -jsonschema = [] -markupsafe = [] -mccabe = [] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -packaging = [] -pathspec = [] -pkgutil-resolve-name = [] -platformdirs = [] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -pycodestyle = [] -pyflakes = [] -pygments = [] -pyrsistent = [] -pytest = [] -pytest-asyncio = [] -pytest-cov = [] -pytz = [] -requests = [] -snowballstemmer = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] -sphinx = [ - {file = "Sphinx-2.4.5-py3-none-any.whl", hash = "sha256:02d7e9dc5f30caa42a682b26de408b755a55c7b07f356a30a3b6300bf7d4740e"}, - {file = "Sphinx-2.4.5.tar.gz", hash = "sha256:b00394e90463e7482c4cf59e7db1c8604baeca1468abfc062904dedc1cea6fcc"}, -] -sphinxcontrib-applehelp = [ - {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, - {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, -] -sphinxcontrib-devhelp = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, -] -sphinxcontrib-htmlhelp = [ - {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, - {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, -] -sphinxcontrib-jsmath = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] -sphinxcontrib-qthelp = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, -] -sphinxcontrib-serializinghtml = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -typed-ast = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, -] -typing-extensions = [] -urllib3 = [] -zipp = [] +content-hash = "d71ee26994b1122e3ad17e242d3cf2e81d125ae13dd0b65a4b8c84c7145f24a5" diff --git a/pyproject.toml b/pyproject.toml index f48fbcd18..23a2375dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,9 @@ black = "^22" isort = "^5" flake8 = "^5" +[tool.poetry.group.dev.dependencies] +websockets = "^11.0.3" + [tool.black] line-length = 88 diff --git a/tests/test_charge_point.py b/tests/test_charge_point.py index de505baad..cd46a1c79 100644 --- a/tests/test_charge_point.py +++ b/tests/test_charge_point.py @@ -4,6 +4,7 @@ from ocpp.charge_point import camel_to_snake_case, remove_nones, snake_to_camel_case from ocpp.routing import create_route_map, on +from ocpp.v16 import validator from ocpp.v16.call import ( BootNotificationPayload, GetConfigurationPayload, @@ -24,7 +25,7 @@ def foo(self): raise RuntimeError("this will be raised") try: - ChargePoint("blah", None) + ChargePoint("blah", validator, None) except RuntimeError as e: assert str(e) == "this will be raised" pytest.fail("Getter was called during ChargePoint creation") @@ -41,8 +42,8 @@ class ChargerB(cp): def heartbeat(self, **kwargs): pass - A = ChargerA("A", None) - B = ChargerB("B", None) + A = ChargerA("A", validator, None) + B = ChargerB("B", validator, None) route_mapA = create_route_map(A) route_mapB = create_route_map(B) assert route_mapA["Heartbeat"] != route_mapB["Heartbeat"] diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 35c3c4ebc..ec49264f4 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -6,6 +6,7 @@ TypeConstraintViolationError, ) from ocpp.messages import Call, validate_payload +from ocpp.v16 import validator def test_exception_with_error_details(): @@ -36,7 +37,7 @@ def test_exception_show_triggered_message_type_constraint(): ) with pytest.raises(TypeConstraintViolationError) as exception_info: - validate_payload(call, "1.6") + validate_payload(call, validator) assert ocpp_message in str(exception_info.value) @@ -54,5 +55,5 @@ def test_exception_show_triggered_message_format(): ) with pytest.raises(FormatViolationError) as exception_info: - validate_payload(call, "1.6") + validate_payload(call, validator) assert ocpp_message in str(exception_info.value) diff --git a/tests/test_messages.py b/tests/test_messages.py index 60c798b0a..4b0e9eabf 100644 --- a/tests/test_messages.py +++ b/tests/test_messages.py @@ -1,5 +1,6 @@ import decimal import json +import sys from datetime import datetime import pytest @@ -24,9 +25,14 @@ unpack, validate_payload, ) +from ocpp.v16 import validator from ocpp.v16.enums import Action +def is_python_3_11_or_higher() -> bool: + return sys.version_info.major >= 3 and sys.version_info.minor >= 11 + + def test_unpack_with_invalid_json(): """ Test that correct exception is raised when unpack is called with invalid @@ -69,9 +75,9 @@ def test_get_validator_with_valid_name(): """ Test if correct validator is returned and if validator is added to cache. """ - schema = get_validator(MessageType.Call, "Reset", ocpp_version="1.6") + schema = get_validator(MessageType.Call, "ResetRequest", ocpp_version="1.6") - assert schema == _validators["Reset_1.6"] + assert schema == _validators["ResetRequest_1.6"] assert schema.schema == { "$schema": "http://json-schema.org/draft-04/schema#", "title": "ResetRequest", @@ -122,7 +128,7 @@ def test_validate_set_charging_profile_payload(): }, ) - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) def test_validate_get_composite_profile_payload(): @@ -147,7 +153,7 @@ def test_validate_get_composite_profile_payload(): }, ) - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) @pytest.mark.parametrize("ocpp_version", ["1.6", "2.0"]) @@ -162,7 +168,7 @@ def test_validate_payload_with_valid_payload(ocpp_version): payload={"currentTime": datetime.now().isoformat()}, ) - validate_payload(message, ocpp_version=ocpp_version) + validate_payload(message, validator) def test_validate_payload_with_invalid_additional_properties_payload(): @@ -177,7 +183,7 @@ def test_validate_payload_with_invalid_additional_properties_payload(): ) with pytest.raises(FormatViolationError): - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) def test_validate_payload_with_invalid_type_payload(): @@ -197,7 +203,7 @@ def test_validate_payload_with_invalid_type_payload(): ) with pytest.raises(TypeConstraintViolationError): - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) def test_validate_payload_with_invalid_missing_property_payload(): @@ -217,7 +223,7 @@ def test_validate_payload_with_invalid_missing_property_payload(): ) with pytest.raises(ProtocolError): - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) def test_validate_payload_with_invalid_message_type_id(): @@ -226,7 +232,7 @@ def test_validate_payload_with_invalid_message_type_id(): a message type id other than 2, Call, or 3, CallError. """ with pytest.raises(ValidationError): - validate_payload(dict(), ocpp_version="1.6") + validate_payload({}, validator) def test_validate_payload_with_non_existing_schema(): @@ -241,7 +247,7 @@ def test_validate_payload_with_non_existing_schema(): ) with pytest.raises(NotImplementedError): - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) def test_call_error_representation(): @@ -258,12 +264,20 @@ def test_call_error_representation(): ) +@pytest.mark.xfail( + is_python_3_11_or_higher(), + reason="Python 3.11 changed the behavior of how enums are formatted. See https://github.com/mobilityhouse/ocpp/issues/447", +) def test_call_representation(): call = Call(unique_id="1", action=Action.Heartbeat, payload={}) assert str(call) == "" +@pytest.mark.xfail( + is_python_3_11_or_higher(), + reason="Python 3.11 changed the behavior of how enums are formatted. See https://github.com/mobilityhouse/ocpp/issues/447", +) def test_call_result_representation(): call = CallResult( unique_id="1", action=Action.Authorize, payload={"status": "Accepted"} @@ -327,7 +341,7 @@ def test_serializing_custom_types(): ) try: - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) except TypeConstraintViolationError as error: # Before the fix, this call would fail with a TypError. Lack of any error # makes this test pass. @@ -361,7 +375,7 @@ def test_validate_meter_values_hertz(): }, ) - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) def test_validate_set_maxlength_violation_payload(): @@ -379,4 +393,4 @@ def test_validate_set_maxlength_violation_payload(): ) with pytest.raises(TypeConstraintViolationError): - validate_payload(message, ocpp_version="1.6") + validate_payload(message, validator) From 222528f70a8f3e3ee475a7fa62e282cdfb2ff40a Mon Sep 17 00:00:00 2001 From: Auke Oosterhoff Date: Fri, 21 Jul 2023 16:57:34 +0200 Subject: [PATCH 2/2] Fix lint error --- ocpp/messages.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ocpp/messages.py b/ocpp/messages.py index 20b8533d2..c6639942b 100644 --- a/ocpp/messages.py +++ b/ocpp/messages.py @@ -2,10 +2,10 @@ also contain some helper functions for packing and unpacking messages. """ from __future__ import annotations -import pathlib import decimal import json import os +import pathlib from dataclasses import asdict, is_dataclass from typing import Callable, Dict, Union @@ -19,10 +19,10 @@ OCPPError, PropertyConstraintViolationError, ProtocolError, + SchemaNotFoundError, TypeConstraintViolationError, UnknownCallErrorCodeError, ValidationError, - SchemaNotFoundError, ) _validators: Dict[str, Draft4Validator] = {}