diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6935732
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,199 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+test*
+.hist
+.test/
+*.7z
+
+*.pyc
+*.map
+*.dblite
+*.elf
+*.bin
+*.hex
+*.axf
+*.exe
+*.pdb
+*.idb
+*.ilk
+*.old
+*.crf
+build
+Debug
+output
+rtthread
+settings
+documentation/html
+*~
+*.o
+*.obj
+*.bak
+*.dep
+*.lib
+*.a
+*.i
+*.d
+*.dfinish
+*.su
+#source insight 4 project files
+*.si4project
+tools/kconfig-frontends/kconfig-mconf
+packages
+dist
+rt-studio-project
+cconfig.h
+GPUCache
+
+#cscope files
+cscope.*
+ncscope.*
+
+#ctag files
+tags
+
+.idea
+.vscode
+*.code-workspace
+*.eide.*
+.history
+CMakeLists.txt
+cmake-build-debug
+*.mk
+debug.txt
diff --git a/README.md b/README.md
index 082d40b..de13588 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# OCPP
+[中文](./README_ZH.md) | English
+
## Introduction
This is based on QuecPython.
@@ -80,7 +82,7 @@ if __name__ == "__main__":
## Project Files Description
-```
+```shell
|-- code
|-- ocpp
|-- v16
@@ -103,26 +105,30 @@ if __name__ == "__main__":
|-- requirements.txt
|-- v16_server_demo.py
|-- docs
+ |-- docs/en
+ |-- docs/en/API_Reference.md
+ |-- docs/zh
+ |-- docs/zh/API说明手册.md
|-- OCPP_1.6_documentation_2019_12-2.zip
```
- `code` floder is incloud all OCPP client codes.
- + `code/ocpp` floder is incloud ocpp procotal codes.
- + `code/ocpp/v16/call.py` is incloud all request data format.
- + `code/ocpp/v16/call_result.py` is incloud all response data format.
- + `code/ocpp/v16/datatypes.py` is incloud some data format for part of request data.
- + `code/ocpp/v16/enums.py` is incloud some enumes of request / response data.
- + `code/ocpp/charge_point.py` is charge point class.
- + `code/tools` floder is incloud some auxiliary function module.
- + `code/tools/logging.py` is log module.
- + `code/tools/uuid.py` is uuid module.
- + `code/tools/uwebsocket.py` is client of websocket module.
- + `code/ocpp/v16_client_qpy_demo.py` is incloud all charge point request demo of ocpp.
+ - `code/ocpp` floder is incloud ocpp procotal codes.
+ - `code/ocpp/v16/call.py` is incloud all request data format.
+ - `code/ocpp/v16/call_result.py` is incloud all response data format.
+ - `code/ocpp/v16/datatypes.py` is incloud some data format for part of request data.
+ - `code/ocpp/v16/enums.py` is incloud some enumes of request / response data.
+ - `code/ocpp/charge_point.py` is charge point class.
+ - `code/tools` floder is incloud some auxiliary function module.
+ - `code/tools/logging.py` is log module.
+ - `code/tools/uuid.py` is uuid module.
+ - `code/tools/uwebsocket.py` is client of websocket module.
+ - `code/ocpp/v16_client_qpy_demo.py` is incloud all charge point request demo of ocpp.
- `demo` floder is incloud OCPP server demo based on Cpython.
- + `demo/requirements.txt` is incloud dependency packages of OCPP server demo running environment.
- + `demo/v16_server_demo.py` is OCPP server demo code based on Cpython.
+ - `demo/requirements.txt` is incloud dependency packages of OCPP server demo running environment.
+ - `demo/v16_server_demo.py` is OCPP server demo code based on Cpython.
- `docs` floder is incloud OCPP protocal documents.
- + `docs/OCPP_1.6_documentation_2019_12-2.zip` is OCPP v1.6 protocal documents.
+ - `docs/OCPP_1.6_documentation_2019_12-2.zip` is OCPP v1.6 protocal documents.
## How To Use
@@ -132,15 +138,15 @@ if __name__ == "__main__":
#### 1. Install environments
-1. Operating System: Window or Linux.
+- Operating System: Window or Linux.
-2. Language: Python (Python-3.11.2).
+- Language: Python (Python-3.11.2).
-3. Dependency packages: `pip install -r demo/requirements.txt`.
+- Dependency packages: `pip install -r demo/requirements.txt`.
#### 2. Config server and running demo
-1. Change your server port in `demo/v16_server_demo.py`.
+- Change your server port in `demo/v16_server_demo.py`.
```python
async def main():
@@ -154,7 +160,7 @@ async def main():
await server.wait_closed()
```
-2. Running `python demo/v16_server_demo.py`. When output `INFO:root:WebSocket Server Started`, the server is started.
+- Running `python demo/v16_server_demo.py`. When output `INFO:root:WebSocket Server Started`, the server is started.
```python
>>> python v16_server_demo.py
@@ -163,7 +169,7 @@ INFO:websockets.server:server listening on 0.0.0.0:31499
INFO:root:WebSocket Server Started
```
-### Running OCPP Client.
+### Running OCPP Client
#### 1. Running environment
@@ -171,7 +177,7 @@ You need to use our QuecPython module.
#### 2. Config client and running demo
-1. Config your server host and port in `code/ocpp/v16_client_qpy_demo.py`
+- Config your server host and port in `code/ocpp/v16_client_qpy_demo.py`
```python
if __name__ == "__main__":
@@ -187,16 +193,40 @@ if __name__ == "__main__":
utime.sleep_ms(200)
```
-2. Download code to QuecPython module
+- Download code to QuecPython module
**Note:**
-> You can find documents in [QuecPython Document Center](https://python.quectel.com/doc/Getting_started/en/index.html) for how to download python code and running python demo in our QuecPython module
+> You can find documents in [QuecPython Document Center](https://python.quectel.com/doc/Getting_started/en/index.html) for how to download python code and running python demo in our QuecPython module
-You can download full `code` floder to our QuecPython module and run `v16_client_qpy_demo.py` to test ocpp Charging Station / Charge point.
+You can download full `code` floder to our QuecPython module and run `v16_client_qpy_demo.py` to test OCPP Charging Station / Charge point.
You can see log `Connected to central system.` in our QPYcom REPL, than the `BootNotification` message is sented to server.
**Note:**
> You can refer to `code.ocpp.v16_client_qpy_demo.py` to write client requests that conform to business logic.
+
+## Usage
+
+- [API Reference Manual](./docs/en/API_Reference.md)
+- [Client Example Code](./code/v16_client_qpy_demo.py)
+- [Server Example Code](./demo/v16_server_demo.py)
+
+## Contribution
+
+We welcome contributions to improve this project! Please follow these steps to contribute:
+
+1. Fork the repository.
+2. Create a new branch (`git checkout -b feature/your-feature`).
+3. Commit your changes (`git commit -m 'Add your feature'`).
+4. Push to the branch (`git push origin feature/your-feature`).
+5. Open a Pull Request.
+
+## License
+
+This project is licensed under the Apache License. See the [LICENSE](./LICENSE) file for details.
+
+## Support
+
+If you have any questions or need support, please refer to the [QuecPython documentation](https://python.quectel.com/doc/en) or open an issue in this repository.
diff --git a/README_ZH.md b/README_ZH.md
new file mode 100644
index 0000000..f0a60ff
--- /dev/null
+++ b/README_ZH.md
@@ -0,0 +1,43 @@
+# OCPP
+
+中文 | [English](./README.md)
+
+## 介绍
+
+随着新能源产业在技术上及产业化上的不断进步,以及在政策的激励下,新能源汽车开始慢慢普及,然而充电设施的不完善、不规范、标准不统一等因素制约着新能源汽车产业的发展。在此背景下,OCPP(开放充电协议)便应运而生,其目的在于解决充电桩和充电管理系统间的互联互通。
+
+OCPP(全称Open Charge Point Protocol,开放充电协议)的技术编委会是位于荷兰的OCA(全称Open Charge Alliance,开放充电联盟)。该联盟主要负责推进开放充电协议OCPP和开放智能充电协议OSCP。该联盟发起方是荷兰的ElaadNL,该公司从2009年开始在荷兰运营3000多个充电站点
+
+开放充电协议 (OCPP) 是一个全球开放性的通讯标准,主要用于解决私营的充电网络间通讯产生的各种困难。OCPP支持充电站点与各供应商中央管理系统间的无缝通讯管理。在过去的很多年内,私营充电网络的封闭特性已经给大量电动汽车车主和地产管理者造成很多无谓的挫折感,引发整个行业对一个开放模型的广泛呼吁。
+
+该协议的第一个版本是 OCPP 1.5而2017年OCPP 已经在 49 个国家应用于 40,000 多个充电设施,因此实质上它已经成为充电设施网络通讯的行业标准。目前OCA 已经在 1.5 的标准之后继续推出了 OCPP 1.6 和 OCPP 2.0 标准。
+
+该项目基于 QuecPython 进行开发使用。
+
+Python 包实现了开放充电点协议(OCPP)的 JSON 版本。目前支持 OCPP 1.6(勘误表 v4)。
+
+该库的目的是提供构建充电站/充电点的构建块。 **该库不提供完整的解决方案,因为任何实现都是特定于其预期用途的**。应检查该库中的文档,因为这些文档提供了有关如何最好地构建完整解决方案的指导。
+
+## 用法
+
+- [API 参考手册](./docs/zh/API参考手册.md)
+- [客户端示例代码](./code/v16_client_qpy_demo.py)
+- [服务端示例代码](./demo/v16_server_demo.py)
+
+## 贡献
+
+我们欢迎对本项目的改进做出贡献!请按照以下步骤进行贡献:
+
+1. Fork 此仓库。
+2. 创建一个新分支(`git checkout -b feature/your-feature`)。
+3. 提交您的更改(`git commit -m 'Add your feature'`)。
+4. 推送到分支(`git push origin feature/your-feature`)。
+5. 打开一个 Pull Request。
+
+## 许可证
+
+本项目使用 Apache 许可证。详细信息请参阅 [LICENSE](./LICENSE) 文件。
+
+## 支持
+
+如果您有任何问题或需要支持,请参阅 [QuecPython 文档](https://python.quectel.com/doc) 或在本仓库中打开一个 issue。
diff --git a/code/ocpp/v16/enums.py b/code/ocpp/v16/enums.py
index f1486f0..896dbc1 100644
--- a/code/ocpp/v16/enums.py
+++ b/code/ocpp/v16/enums.py
@@ -159,24 +159,6 @@ class ChargePointErrorCode(StrEnum):
under_voltage = "UnderVoltage"
weak_signal = "WeakSignal"
- # Soon to be deprecated enums
- connectorLockFailure = "ConnectorLockFailure"
- evCommunicationError = "EVCommunicationError"
- groundFailure = "GroundFailure"
- highTemperature = "HighTemperature"
- internalError = "InternalError"
- localListConflict = "LocalListConflict"
- noError = "NoError"
- otherError = "OtherError"
- overCurrentFailure = "OverCurrentFailure"
- overVoltage = "OverVoltage"
- powerMeterFailure = "PowerMeterFailure"
- powerSwitchFailure = "PowerSwitchFailure"
- readerFailure = "ReaderFailure"
- resetFailure = "ResetFailure"
- underVoltage = "UnderVoltage"
- weakSignal = "WeakSignal"
-
class ChargePointStatus(StrEnum):
"""
@@ -200,10 +182,6 @@ class ChargePointStatus(StrEnum):
unavailable = "Unavailable"
faulted = "Faulted"
- # Soon to be deprecated enums
- suspendedevse = "SuspendedEVSE"
- suspendedev = "SuspendedEV"
-
class ChargingProfileKindType(StrEnum):
"""
@@ -259,11 +237,6 @@ class ChargingProfilePurposeType(StrEnum):
tx_default_profile = "TxDefaultProfile"
tx_profile = "TxProfile"
- # Soon to be deprecated enums
- chargepointmaxprofile = "ChargePointMaxProfile"
- txdefaultprofile = "TxDefaultProfile"
- txprofile = "TxProfile"
-
class ChargingProfileStatus(StrEnum):
"""
@@ -273,8 +246,6 @@ class ChargingProfileStatus(StrEnum):
accepted = "Accepted"
rejected = "Rejected"
not_supported = "NotSupported"
- # Soon to be deprecated enums
- notSupported = "NotSupported"
class ChargingRateUnitType(StrEnum):
@@ -327,10 +298,6 @@ class ConfigurationStatus(StrEnum):
reboot_required = "RebootRequired"
not_supported = "NotSupported"
- # Soon to be deprecated enums
- rebootRequired = "RebootRequired"
- notSupported = "NotSupported"
-
class ConfigurationKey(StrEnum):
"""
@@ -416,10 +383,6 @@ class DataTransferStatus(StrEnum):
unknown_message_id = "UnknownMessageId"
unknown_vendor_id = "UnknownVendorId"
- # Soon to be deprecated enums
- unknownMessageId = "UnknownMessageId"
- unknownVendorId = "UnknownVendorId"
-
class DeleteCertificateStatus(StrEnum):
"""
@@ -441,9 +404,6 @@ class DiagnosticsStatus(StrEnum):
upload_failed = "UploadFailed"
uploading = "Uploading"
- # Soon to be deprecated enums
- uploadFailed = "UploadFailed"
-
class FirmwareStatus(StrEnum):
"""
@@ -469,10 +429,6 @@ class FirmwareStatus(StrEnum):
invalid_signature = "InvalidSignature"
signature_verified = "SignatureVerified"
- # Soon to be deprecated enums
- downloadFailed = "DownloadFailed"
- installationFailed = "InstallationFailed"
-
class GenericStatus(StrEnum):
"""
@@ -574,25 +530,6 @@ class Measurand(StrEnum):
temperature = "Temperature"
voltage = "Voltage"
- # Soon to be deprecated enums
- currentExport = "Current.Export"
- currentImport = "Current.Import"
- currentOffered = "Current.Offered"
- energyActiveExportRegister = "Energy.Active.Export.Register"
- energyActiveImportRegister = "Energy.Active.Import.Register"
- energyReactiveExportRegister = "Energy.Reactive.Export.Register"
- energyReactiveImportRegister = "Energy.Reactive.Import.Register"
- energyActiveExportInterval = "Energy.Active.Export.Interval"
- energyActiveImportInterval = "Energy.Active.Import.Interval"
- energyReactiveExportInterval = "Energy.Reactive.Export.Interval"
- energyReactiveImportInterval = "Energy.Reactive.Import.Interval"
- powerActiveExport = "Power.Active.Export"
- powerActiveImport = "Power.Active.Import"
- powerFactor = "Power.Factor"
- powerOffered = "Power.Offered"
- powerReactiveExport = "Power.Reactive.Export"
- powerReactiveImport = "Power.Reactive.Import"
-
class MessageTrigger(StrEnum):
"""
@@ -613,13 +550,6 @@ class MessageTrigger(StrEnum):
log_status_notification = "LogStatusNotification"
sign_charge_point_certificate = "SignChargePointCertificate"
- # Soon to be deprecated enums
- bootNotification = "BootNotification"
- diagnosticsStatusNotification = "DiagnosticsStatusNotification"
- firmwareStatusNotification = "FirmwareStatusNotification"
- meterValues = "MeterValues"
- statusNotification = "StatusNotification"
-
class Phase(StrEnum):
"""
@@ -639,14 +569,6 @@ class Phase(StrEnum):
l2_l3 = "L2-L3"
l3_l1 = "L3-L1"
- # Soon to be deprecated enums
- l1n = "L1-N"
- l2n = "L2-N"
- l3n = "L3-N"
- l1l2 = "L1-L2"
- l2l3 = "L2-L3"
- l3l1 = "L3-L1"
-
class ReadingContext(StrEnum):
"""
@@ -662,14 +584,6 @@ class ReadingContext(StrEnum):
transaction_end = "Transaction.End"
trigger = "Trigger"
- # Soon to be deprecated enums
- interruptionBegin = "Interruption.Begin"
- interruptionEnd = "Interruption.End"
- sampleClock = "Sample.Clock"
- samplePeriodic = "Sample.Periodic"
- transactionBegin = "Transaction.Begin"
- transactionEnd = "Transaction.End"
-
class Reason(StrEnum):
"""
@@ -688,15 +602,6 @@ class Reason(StrEnum):
unlock_command = "UnlockCommand"
de_authorized = "DeAuthorized"
- # Soon to be deprecated enums
- emergencyStop = "EmergencyStop"
- evDisconnected = "EVDisconnected"
- hardReset = "HardReset"
- powerLoss = "PowerLoss"
- softReset = "SoftReset"
- unlockCommand = "UnlockCommand"
- deAuthorized = "DeAuthorized"
-
class RecurrencyKind(StrEnum):
"""
@@ -768,9 +673,6 @@ class TriggerMessageStatus(StrEnum):
rejected = "Rejected"
not_implemented = "NotImplemented"
- # Soon to be deprecated enums
- notImplemented = "NotImplemented"
-
class UnitOfMeasure(StrEnum):
"""
@@ -807,10 +709,6 @@ class UnlockStatus(StrEnum):
unlock_failed = "UnlockFailed"
not_supported = "NotSupported"
- # Soon to be deprecated enums
- unlockFailed = "UnlockFailed"
- notSupported = "NotSupported"
-
class UpdateFirmwareStatus(StrEnum):
"""
@@ -848,10 +746,6 @@ class UpdateStatus(StrEnum):
not_supported = "NotSupported"
version_mismatch = "VersionMismatch"
- # Soon to be deprecated enums
- notSupported = "NotSupported"
- versionMismatch = "VersionMismatch"
-
class UpdateType(StrEnum):
"""
@@ -870,6 +764,3 @@ class ValueFormat(StrEnum):
raw = "Raw"
signed_data = "SignedData"
-
- # Soon to be deprecated enums
- signedData = "SignedData"
diff --git a/code/tools/logging.py b/code/tools/logging.py
index 1c70c5f..67453aa 100644
--- a/code/tools/logging.py
+++ b/code/tools/logging.py
@@ -25,145 +25,194 @@
"""
import uos
+import sys
import utime
import ql_fs
import _thread
-import usys as sys
+
+__all__ = [
+ "CRITICAL", "FATAL", "ERROR", "WARNING", "WARN", "INFO", "DEBUG", "NOTSET",
+ "Logger", "getLogger", "setLogFile", "setSaveLog", "getSaveLog", "setLogLevel",
+ "getLogLevel", "setLogDebug", "getLogDebug",
+]
_LOG_LOCK = _thread.allocate_lock()
-_LOG_LEVEL_CODE = {
- "debug": 0,
- "info": 1,
- "warn": 2,
- "error": 3,
- "critical": 4,
+
+CRITICAL = 50
+FATAL = CRITICAL
+ERROR = 40
+WARNING = 30
+WARN = WARNING
+INFO = 20
+DEBUG = 10
+NOTSET = 0
+
+_levelToName = {
+ CRITICAL: 'CRITICAL',
+ ERROR: 'ERROR',
+ WARNING: 'WARNING',
+ INFO: 'INFO',
+ DEBUG: 'DEBUG',
+ NOTSET: 'NOTSET',
+}
+
+_nameToLevel = {
+ 'CRITICAL': CRITICAL,
+ 'FATAL': FATAL,
+ 'ERROR': ERROR,
+ 'WARNING': WARNING,
+ 'WARN': WARN,
+ 'INFO': INFO,
+ 'DEBUG': DEBUG,
+ 'NOTSET': NOTSET,
}
-_log_dict = {}
-_log_path = "/usr/log/"
-_log_name = "project.log"
-_log_file = _log_path + _log_name
-_log_save = False
-_log_size = 0x2000
-_log_back = 8
-_log_level = "debug"
-_log_debug = True
+_LOG_DICT = {}
+_LOG_PATH = "/usr/"
+_LOG_NAME = "project.log"
+_LOG_FILE = _LOG_PATH + _LOG_NAME
+_LOG_SAVE = False
+_LOG_SIZE = 0x8000
+_LOG_BACK = 8
+_LOG_LEVEL = DEBUG
+_LOG_DEBUG = True
class Logger:
def __init__(self, name):
self.__name = name
+ self.__file = None
+
+ def __open_log(self):
+ global _LOG_FILE
+ if not self.__file:
+ self.__file = open(_LOG_FILE, "wb")
+
+ def __close_log(self):
+ if self.__file:
+ self.__file.close()
+ self.__file = None
+
+ def __write_log(self, msg):
+ if self.__file:
+ self.__file.write(msg)
+ self.__file.flush()
def __save_log(self, msg):
- global _log_path
- global _log_file
try:
+ msg += "\n" if not msg.endswith("\n") else ""
log_size = 0
- if not ql_fs.path_exists(_log_path):
- uos.mkdir(_log_path[:-1])
- if ql_fs.path_exists(_log_file):
- log_size = ql_fs.path_getsize(_log_file)
- if log_size + len(msg) >= _log_size:
- for i in range(_log_back, 0, -1):
- bak_file = _log_file + "." + str(i)
+ if not ql_fs.path_exists(_LOG_PATH):
+ uos.mkdir(_LOG_PATH[:-1])
+ if ql_fs.path_exists(_LOG_FILE):
+ log_size = ql_fs.path_getsize(_LOG_FILE)
+ if log_size + len(msg) >= _LOG_SIZE:
+ self.__close_log()
+ for i in range(_LOG_BACK, 0, -1):
+ bak_file = _LOG_FILE + "." + str(i)
if ql_fs.path_exists(bak_file):
- if i == _log_back:
+ if i == _LOG_BACK:
uos.remove(bak_file)
else:
- uos.rename(bak_file, _log_file + "." + str(i + 1))
- uos.rename(_log_file, _log_file + ".1")
- with open(_log_file, "a") as lf:
- lf.write(msg)
+ uos.rename(bak_file, _LOG_FILE + "." + str(i + 1))
+ uos.rename(_LOG_FILE, _LOG_FILE + ".1")
+ self.__open_log()
+ self.__write_log(msg)
except Exception as e:
sys.print_exception(e)
def __log(self, level, *message):
- global _log_save
with _LOG_LOCK:
- if _log_debug is False:
- if _log_level == "debug" and level == "debug":
- return
- if _LOG_LEVEL_CODE.get(level) < _LOG_LEVEL_CODE.get(_log_level):
- return
+ if _LOG_DEBUG is False and ((_LOG_LEVEL == level == DEBUG) or level < _LOG_LEVEL):
+ return
_time = "{}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(*utime.localtime())
- msg = "[{}][{}][{}]".format(_time, self.__name, level)
+ msg = "[{}][{}][{}]".format(_time, self.__name, _levelToName[level])
print(msg, *message)
- if _log_save:
+ if _LOG_SAVE:
msg = msg + " " + " ".join(message) if message else msg
self.__save_log(msg)
def critical(self, *message):
- self.__log("critical", *message)
+ self.__log(CRITICAL, *message)
+
+ def fatal(self, *message):
+ self.critical(*message)
def error(self, *message):
- self.__log("error", *message)
+ self.__log(ERROR, *message)
+
+ def warning(self, *message):
+ self.__log(WARNING, *message)
def warn(self, *message):
- self.__log("warn", *message)
+ self.warning(*message)
def info(self, *message):
- self.__log("info", *message)
+ self.__log(INFO, *message)
def debug(self, *message):
- self.__log("debug", *message)
+ self.__log(DEBUG, *message)
def getLogger(name):
- global _log_dict
- if not _log_dict.get(name):
- _log_dict[name] = Logger(name)
- return _log_dict[name]
+ global _LOG_DICT
+ if not _LOG_DICT.get(name):
+ _LOG_DICT[name] = Logger(name)
+ return _LOG_DICT[name]
def setLogFile(path, name):
- global _log_path, _log_name, _log_file
+ global _LOG_PATH, _LOG_NAME, _LOG_FILE
if not path.endswith("/"):
path += "/"
- _log_path = path
- _log_name = name
- _log_file = _log_path + _log_name
+ _LOG_PATH = path
+ _LOG_NAME = name
+ _LOG_FILE = _LOG_PATH + _LOG_NAME
return 0
def setSaveLog(save, size=None, backups=None):
- global _log_save, _log_size, _log_back
+ global _LOG_SAVE, _LOG_SIZE, _LOG_BACK
if not isinstance(save, bool):
return (1, "save is not bool.")
- _log_save = save
- if _log_save:
+ _LOG_SAVE = save
+ if _LOG_SAVE:
if not isinstance(size, int):
return (2, "size is not int.")
- _log_size = size
+ _LOG_SIZE = size
if not isinstance(backups, int):
return (3, "backups is not int.")
- _log_back = backups
+ _LOG_BACK = backups
return (0, "success.")
def getSaveLog():
- return _log_save
+ return _LOG_SAVE
def setLogLevel(level):
- global _log_level
- level = level.lower()
- if level not in _LOG_LEVEL_CODE.keys():
- return False
- _log_level = level
- return True
+ global _LOG_LEVEL
+ level = level.upper()
+ if _nameToLevel.get(level) is not None:
+ _LOG_LEVEL = _nameToLevel.get(level)
+ return True
+ if _levelToName.get(level) is not None:
+ _LOG_LEVEL = level
+ return True
+ return False
def getLogLevel():
- return _log_level
+ return _levelToName.get(_LOG_LEVEL)
def setLogDebug(debug):
- global _log_debug
+ global _LOG_DEBUG
if isinstance(debug, bool):
- _log_debug = debug
+ _LOG_DEBUG = debug
return True
return False
def getLogDebug():
- return _log_debug
+ return _LOG_DEBUG
diff --git a/code/v16_client_qpy_demo.py b/code/v16_client_qpy_demo.py
index 5e27d61..402d4de 100644
--- a/code/v16_client_qpy_demo.py
+++ b/code/v16_client_qpy_demo.py
@@ -37,26 +37,16 @@
RegistrationStatus,
CancelReservationStatus,
CertificateSignedStatus,
- # AvailabilityType,
AvailabilityStatus,
ConfigurationStatus,
ClearCacheStatus,
- # ChargingProfilePurposeType,
HashAlgorithm,
ClearChargingProfileStatus,
DeleteCertificateStatus,
- # MessageTrigger,
TriggerMessageStatus,
ChargingRateUnitType,
GetCompositeScheduleStatus,
- # CertificateUse,
GetInstalledCertificateStatus,
- # Log,
- # ChargingProfileKindType,
- # RecurrencyKind,
- # ResetType,
- # UpdateType,
- # AuthorizationStatus,
DiagnosticsStatus,
FirmwareStatus,
UploadLogStatus,
@@ -82,11 +72,6 @@
)
from usr.ocpp.v16.datatypes import (
CertificateHashData,
- # LogParameters,
- # ChargingProfile,
- # AuthorizationData,
- # IdTagInfo,
- # Firmware,
MeterValue,
SampledValue,
ChargingSchedule,
diff --git a/docs/en/API_Reference.md b/docs/en/API_Reference.md
new file mode 100644
index 0000000..a5dced4
--- /dev/null
+++ b/docs/en/API_Reference.md
@@ -0,0 +1,285 @@
+# OCPP API Reference
+
+[中文](../zh/API参考手册.md) | English
+
+The protocol function of this module is based on websocket and uses json format data for data interaction.
+
+This module designs the `ocpp.charge_point.ChargePoint` abstract class, which is used as a base class. Users need to conduct secondary development according to the actual situation of their own projects. Based on this abstract class, they encapsulate the corresponding versions that their own projects need to use and send and receiving functions.
+
+Currently, the project only supports OCPP v1.6, and support will continue to be expanded in the future.
+
+This article is mainly divided into two modules:
+
+1. Introduction and usage instructions of the relevant interfaces and associated decorators of the `ChargePoint` base class.
+2. Secondary development example of implementing data sending and receiving interface based on `ChargePoint` base class.
+
+## Charging Station / Charging Point Abstract Class
+
+### `ChargePoint`
+
+- `ocpp.charge_point.ChargePoint` is a charging station/charging point abstract class.
+- This abstract class encapsulates the [`call`](#cp-call) interface for sending data based on the websocket protocol and the [`start`](#cp-start) interface for receiving and processing server messages.
+- The secondary development of this abstract class requires the use of [`ocpp.routing.on`](#routing-on) and [`ocpp.routing.atfer`](#routing-after) decorators to encapsulate the receiving message processing function.
+- This abstract class is usually inherited in the corresponding version, such as: `ocpp.v16.ChargePoint`, adding [`_call`](#cp-_call), [`_call_result`](#cp-_call_result), [`_ocpp_version`](#cp-_ocpp_version) attribute value.
+- This module is based on the websocket protocol and requires the use of the [QuecPython uwebscoket](https://python.quectel.com/doc/API_reference/zh/networklib/uwebsocket.html "QuecPython uwebsocket module usage instructions") module.
+
+#### Initialization
+
+```python
+from usr.tools import uwebsocket
+from usr.ocpp.v16 import ChargePoint as cp
+
+# It is recommended to use the device IMEI or device MAC address as the unique identifier of the device.
+IMEI = "XXXX"
+# Corresponding server IP address.
+host = "xxx.xxx.xxx.xxx"
+# Corresponding server port number.
+port = "xxxx"
+# Instantiate a uwebsocket object.
+ws = uwebsocket.Client.connect(
+ "ws://{host}:{port}/{IMEI}",
+ # Add the corresponding OCPP version number in the header for identification by the server. Different servers have different requirements, so fill in the information according to the actual situation.
+ headers={"Sec-WebSocket-Protocol": "ocpp1.6.0"},
+ debug=False
+)
+
+# Instantiate a ChargePoint object.
+cp = ChargePoint(IMEI, ws)
+```
+
+**Parameter Description:**
+
+|Parameters|Type|Description|
+|:---|:---|:---|
+|id|str|Device ID|
+|connection|obj|uwebsocket object|
+|response_timeout|int|Request response timeout, unit: seconds, default: 30|
+
+**Return Value Description:**
+
+|Type|Description|
+|:---|:---|
+|obj|ChargePoint object|
+
+#### `ChargePoint.start`
+
+- Start a loop to receive server data, usually start a separate thread to run this method.
+
+```python
+import _thread
+
+# Set the thread stack size according to actual usage.
+_thread.stack_size(0x4000)
+# Start a thread to receive and parse data sent by the server.
+_thread.start_new_thread(cp.start, ())
+```
+
+#### `ChargePoint.call`
+
+- Sends a Call message to the server and returns the response payload.
+- This method is usually used in secondary encapsulated functions.
+
+```python
+class ChargePoint(cp):
+
+ # The client sends a request to the authentication interface.
+ def send_authorize(self):
+ # Use the AuthorizePayload class to generate the data structure of the client request authentication interface.
+ request = self._call.AuthorizePayload(
+ id_tag="xxx",
+ )
+ # Call the call method to send a message and wait for a response.
+ response = self.call(request)
+ logger.info("response %s" % response)
+
+ # Determine whether the parsed response is the response data structure of the request authentication interface, and if so, process the response data.
+ if isinstance(response, self._call_result.AuthorizePayload):
+ logger.info("id_tag_info %s." % response.id_tag_info)
+```
+
+**Parameter Description:**
+
+|Parameters|Type|Description|
+|:---|:---|:---|
+|payload|obj|`vxx.call.xxx` Request message data structure object|
+|suppress|bool|Whether an exception will be thrown when a request returns CallError
`True` - Skip the exception and return directly
`False` - Throw an exception
Default: `True`|
+|unique_id|str|The unique identifier of the message. When not transmitted, a uuid4 value is automatically generated as the unique identifier. Default: None|
+
+**Return Value Description:**
+
+|Type|Description|
+|:---|:---|
+|obj|`vxx.call_result.xxx` Response message data structure object|
+
+#### `ChargePoint._call`
+
+- When this class is imported from the corresponding version module, there will be this attribute, which is the corresponding version of the `call` module. For example: `ocpp.v16.ChargePoint._call` is equivalent to `ocpp.v16.call`.
+- This attribute is mainly used for secondary development and is convenient for encapsulating interfaces.
+- [OCPP v1.6 Request Message Data Structure](./Request_and_Response_Message_Data_Structure_Description_V16.md#request-message-structure)
+
+#### `ChargePoint._call_result`
+
+- When this class is imported from the corresponding version module, there will be this attribute, which is the corresponding version of the `call_result` module. For example: `ocpp.v16.ChargePoint._call_result` is equivalent to `ocpp.v16.call_result`.
+- This attribute is mainly used for secondary development and is convenient for encapsulating interfaces.
+- [OCPP v1.6 Response message Data Structure](./Request_and_Response_Message_Data_Structure_Description_V16.md#response-message-structure)
+
+#### `ChargePoint._ocpp_version`
+
+- When this class is imported from the corresponding version module, there will be this attribute, which is the corresponding ocpp protocol version number.
+
+## Decorator For Functions That Handle Server Messages
+
+### `ocpp.routing.on`
+
+- This decorator is used to process the encapsulation function of the message sent by the corresponding server.
+- The input parameter of the decorated function is the data structure information of the received message, and returns the data structure information of the response corresponding to the message, which is used to send it to the server for message response.
+
+```python
+class ChargePoint(cp):
+
+ # The client receives the cancellation message processing interface
+ # and uses the ocpp.routing.on decorator to register the processing function corresponding to
+ # the received message. This function is used to receive the message body data of
+ # the corresponding message and needs to return the response data structure of the corresponding message.
+ @on(Action.CancelReservation)
+ def on_cancel_reservation(self, reservation_id):
+ logger.info("reservation_id %s" % (reservation_id))
+
+ # After receiving the message, you can perform business function processing here,
+ # or respond first, and then perform business processing in the function decorated by ocpp.routing.after.
+
+ # This function must return the response message body of the corresponding message,
+ # which is used to respond to server messages.
+ return self._call_result.CancelReservationPayload(
+ status=CancelReservationStatus.accepted
+ )
+```
+
+**Parameter Description:**
+
+|Parameters|Type|Description|
+|:---|:---|:---|
+|action|str|For the corresponding message type, you can directly use the data in the `ocpp.vxx.enums.Actions` enumeration value.|
+|skip_schema_validation|bool|Whether to skip request or response message body data verification
`True` - skip verification
`False` - do not skip verification
Default: `False`|
+|call_unique_id_required|bool|Whether to pass the message unique identifier as a parameter into the decorated function
`True` - Yes
`False` - No
Default: `False`|
+
+### `ocpp.routing.after`
+
+- This decorator is used to process the encapsulated function corresponding to the message sent by the server, which is called after the function decorated by `ocpp.routing.on` is called.
+- The input parameters of the decorated function are the data structure information of the received message, and there are no special requirements for the return value.
+
+```python
+class ChargePoint(cp):
+
+ # After the client receives the cancellation message,
+ # after the response is completed or after no response is required,
+ # the client can use the ocpp.routing.after decorator to register
+ # the processing function corresponding to the received message
+ # if it needs to perform business processing functions.
+ @after(Action.CancelReservation, call_unique_id_required=True)
+ def after_cancel_reservation(self, reservation_id, call_unique_id):
+ logger.info("reservation_id %s, call_unique_id %s" % (reservation_id, call_unique_id))
+ # The corresponding business function can be processed here.
+ # This function has no special requirements for the return value.
+ return
+```
+
+**Parameter Description:**
+
+|Parameters|Type|Description|
+|:---|:---|:---|
+|action|str|For the corresponding message type, you can directly use the data in the `ocpp.vxx.enums.Actions` enumeration value.|
+|call_unique_id_required|bool|Whether to pass the message unique identifier as a parameter into the decorated function
`True` - Yes
`False` - No
Default: `False`|
+
+## Secondary Development Example Based On `ChargePoint`
+
+- This abstract class encapsulates the websocket-based protocol and needs to instantiate the `uwebsocket` object as a parameter to initialize the `ChargePoint` module.
+- When using it, import the `ChargePoint` class from the corresponding version, such as: `from usr.ocpp.v16 import ChargePoint as cp`.
+
+**Note:**
+
+The following only lists examples of processing functions for a client to send messages and a client to receive messages for reference. Which request messages and receive messages need to be used in the actual project need to be developed according to the actual requirements of the project.
+
+```python
+import utime
+import _thread
+# Import the uwebsocket module and instantiate objects for the ChargePoint class.
+from usr.tools import uwebsocket, logging
+# Import the v16 version of ChargePoint as the project base class.
+from usr.ocpp.v16 import ChargePoint as cp
+
+
+# Secondary development based on the v16 version of the project base class,
+# encapsulating the client sending interface and message receiving interface that need to be used.
+class ChargePoint(cp):
+
+ # The client sends a request to the authentication interface.
+ def send_authorize(self):
+ # Use the AuthorizePayload class to generate the data structure of the client request authentication interface.
+ request = self._call.AuthorizePayload(
+ id_tag="xxx",
+ )
+ # Call the call method to send a message and wait for a response.
+ response = self.call(request)
+ logger.info("response %s" % response)
+
+ # Determine whether the parsed response is the response data structure of
+ # the request authentication interface, and if so, process the response data.
+ if isinstance(response, self._call_result.AuthorizePayload):
+ logger.info("id_tag_info %s." % response.id_tag_info)
+
+ # The client receives the cancellation message processing interface and
+ # uses the ocpp.routing.on decorator to register the processing function corresponding to the received message.
+ # This function is used to receive the message body data of the corresponding message and needs to
+ # return the response data structure of the corresponding message.
+ @on(Action.CancelReservation)
+ def on_cancel_reservation(self, reservation_id):
+ logger.info("reservation_id %s" % (reservation_id))
+
+ # After receiving the message, you can perform business function processing here,
+ # or respond first, and then perform business processing in the function decorated by ocpp.routing.after.
+
+ # This function must return the response message body of the corresponding message,
+ # which is used to respond to server messages.
+ return self._call_result.CancelReservationPayload(
+ status=CancelReservationStatus.accepted
+ )
+
+ # After the client receives the cancellation message,
+ # after the response is completed or after no response is required,
+ # the client can use the ocpp.routing.after decorator to register the processing function
+ # corresponding to the received message if it needs to perform business processing functions.
+ @after(Action.CancelReservation)
+ def after_cancel_reservation(self, reservation_id):
+ logger.info("reservation_id %s" % (reservation_id))
+ # The corresponding business function can be processed here.
+ # This function has no special requirements for the return value.
+ return
+
+# It is recommended to use device IMEI or device MAC address as device identification.
+IMEI = "XXXX"
+# Corresponding server IP address.
+host = "xxx.xxx.xxx.xxx"
+# Corresponding server port number.
+port = "xxxx"
+# Instantiate a uwebsocket object.
+ws = uwebsocket.Client.connect(
+ "ws://{host}:{port}/{IMEI}",
+ # Add the corresponding OCPP version number in the header for identification by the server.
+ # Different servers have different requirements, so fill in the information according to the actual situation.
+ headers={"Sec-WebSocket-Protocol": "ocpp1.6.0"},
+ debug=False
+)
+
+# Instantiate a secondary developed ChargePoint object containing specific business functions.
+cp = ChargePoint(IMEI, ws)
+
+# Start a thread to receive data sent by the server.
+_thread.start_new_thread(cp.start, ())
+
+# Send request authentication message.
+cp.send_authorize()
+
+# Waiting to receive server data.
+utime.sleep(10)
+```
diff --git a/docs/en/Request_and_Response_Message_Data_Structure_Description_V16.md b/docs/en/Request_and_Response_Message_Data_Structure_Description_V16.md
new file mode 100644
index 0000000..7d05b92
--- /dev/null
+++ b/docs/en/Request_and_Response_Message_Data_Structure_Description_V16.md
@@ -0,0 +1,1417 @@
+# OCPP v1.6 Version Request and Response Message Data Structure Description
+
+[中文](../zh/请求与应答消息数据结构说明_V16.md) | English
+
+- The relevant data module of OCPP v1.6 version is under the path `ocpp.v16`
+- All message data structures are abstracted into classes corresponding to the message names. The parameters for class instantiation are the parameters that need to be included in the message body. Just instantiate the corresponding request message class object or response message class object.
+
+**Example:**
+
+```python
+call.CancelReservationPayload(
+ reservation_id=123
+)
+
+call_result.CancelReservationPayload(
+ status=CancelReservationStatus.accepted
+)
+```
+
+## Request Message Structure
+
+- The request message structure file is `ocpp.v16.call`.
+
+### Server Request Message Structure
+
+- Corresponding to the client receiving message structure.
+
+#### `call.CancelReservationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|reservation_id|int||Yes|
+
+#### `call.CertificateSignedPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|certificate_chain|str|The maximum length: 10000|Yes|
+
+#### `call.ChangeAvailabilityPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|type|str|[`AvailabilityType`](#enums-availabilitytype "AvailabilityType Enumeration Value")|Yes|
+
+#### `call.ChangeConfigurationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|key|str|The maximum length: 50|Yes|
+|value|str|The maximum length: 500|Yes|
+
+#### `call.ClearCachePayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call.ClearChargingProfilePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|id|int||No|
+|connector_id|int||No|
+|charging_profile_purpose|str|[`ChargingProfilePurposeType`](#enums-chargingprofilepurposetype "ChargingProfilePurposeType Enumeration Value")|No|
+|stack_level|int||No|
+
+#### `call.DeleteCertificatePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|certificate_hash_data|obj|[`CertificateHashData`](#datatypes-certificatehashdata "CertificateHashData Structured Data")|Yes|
+
+#### `call.ExtendedTriggerMessagePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|requested_message|str|[`MessageTrigger`](#enums-messagetrigger "MessageTrigger Enumeration Value")|Yes|
+|connector_id|int||No|
+
+#### `call.GetCompositeSchedulePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|duration|int||Yes|
+|charging_rate_unit|str|[`ChargingRateUnitType`](#enums-chargingrateunittype "ChargingRateUnitType Enumeration Value")|Yes|
+
+#### `call.GetConfigurationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|key|list|List element `str`, Maximum length of a single string: 50|No|
+
+#### `call.GetDiagnosticsPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|location|str|uri|Yes|
+|retries|int||No|
+|retry_interval|int||No|
+|start_time|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+|stop_time|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+
+#### `call.GetInstalledCertificateIdsPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|certificate_type|str|[`CertificateUse`](#enums-certificateuse "CertificateUse Enumeration Value")|Yes|
+
+#### `call.GetLocalListVersionPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call.GetLogPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|log|obj|[`LogParameters`](#datatypes-logparameters "LogParameters Structured Data")|Yes|
+|log_type|str|[`Log`](#enums-log "Log Enumeration Value")|Yes|
+|request_id|int||Yes|
+|retries|int||No|
+|retry_interval|int||No|
+
+#### `call.InstallCertificatePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|certificate_type|str|[`CertificateUse`](#enums-certificateuse "CertificateUse Enumeration Value")|Yes|
+|certificate|str|The maximum length: 5500|Yes|
+
+#### `call.RemoteStartTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|id_tag|str|The maximum length: 20|Yes|
+|connector_id|int||No|
+|charging_profile|obj|[`ChargingProfile`](#datatypes-chargingprofile "ChargingProfile Structured Data")|No|
+
+#### `call.RemoteStopTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|transaction_id|int||Yes|
+
+#### `call.ReserveNowPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|expiry_date|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|id_tag|str|The maximum length: 20|Yes|
+|reservation_id|int||Yes|
+|parent_id_tag|str|The maximum length: 20|No|
+
+#### `call.ResetPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|type|str|[`ResetType`](#enums-resettype "ResetType Enumeration Value")|Yes|
+
+#### `call.SendLocalListPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|list_version|int||Yes|
+|update_type|str|[`UpdateType`](#enums-updatetype "UpdateType Enumeration Value")|Yes|
+|local_authorization_list|list|List element is [`AuthorizationData`](#datatypes-authorizationdata "AuthorizationData Structured Data")|No|
+
+#### `call.SetChargingProfilePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|cs_charging_profiles|obj|[`ChargingProfile`](#datatypes-chargingprofile "ChargingProfile Structured Data")|Yes|
+
+#### `call.SignedUpdateFirmwarePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|request_id|int||Yes|
+|firmware|obj|[`Firmware`](#datatypes-firmware "Firmware Structured Data")|Yes|
+|retries|int||No|
+|retry_interval|int||No|
+
+#### `call.TriggerMessagePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|requested_message|str|[`MessageTrigger`](#enums-messagetrigger "MessageTrigger Enumeration Value")|Yes|
+|connector_id|int||No|
+
+#### `call.UnlockConnectorPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+
+#### `call.UpdateFirmwarePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|location|str|uri|Yes|
+|retrieve_date|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|retries|int||No|
+|retry_interval|int||No|
+
+### Client Request Message Structure
+
+- Corresponding to the message structure received by the server.
+
+#### `call.AuthorizePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|id_tag|str|The maximum length: 20|Yes|
+
+#### `call.BootNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|charge_point_model|str|The maximum length: 20|Yes|
+|charge_point_vendor|str|The maximum length: 20|Yes|
+|charge_box_serial_number|str|The maximum length: 25|No|
+|charge_point_serial_number|str|The maximum length: 25|No|
+|firmware_version|str|The maximum length: 50|No|
+|iccid|str|The maximum length: 20|No|
+|imsi|str|The maximum length: 20|No|
+|meter_serial_number|str|The maximum length: 25|No|
+|meter_type|str|The maximum length: 25|No|
+
+#### `call.DiagnosticsStatusNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`DiagnosticsStatus`](#enums-diagnosticsstatus "DiagnosticsStatus Enumeration Value")|Yes|
+
+#### `call.FirmwareStatusNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`FirmwareStatus`](#enums-firmwarestatus "FirmwareStatus Enumeration Value")|Yes|
+
+#### `call.HeartbeatPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call.LogStatusNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`UploadLogStatus`](#enums-uploadlogstatus "UploadLogStatus Enumeration Value")|Yes|
+|request_id|int||Yes|
+
+#### `call.MeterValuesPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|meter_value|list|List element is [`MeterValue`](#datatypes-metervalue "MeterValue Structured Data")|Yes|
+|transaction_id|int||No|
+
+#### `call.SecurityEventNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|type|str|The maximum length: 50|Yes|
+|timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|tech_info|str|The maximum length: 255|No|
+
+#### `call.SignCertificatePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|csr|str|The maximum length: 5500|Yes|
+
+#### `call.SignedFirmwareStatusNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`FirmwareStatus`](#enums-firmwarestatus "FirmwareStatus Enumeration Value")|Yes|
+|request_id|int||Yes|
+
+#### `call.StartTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|id_tag|str|The maximum length: 20|Yes|
+|meter_start|int||Yes|
+|timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|reservation_id|int||No|
+
+#### `call.StopTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|meter_stop|int||Yes|
+|timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|transaction_id|int||Yes|
+|reason|str|[`Reason`](#enums-reason "Reason Enumeration Value")|No|
+|id_tag|str|The maximum length: 20|No|
+|transaction_data|list|List element is [`MeterValue`](#datatypes-metervalue "MeterValue Structured Data")|No|
+
+#### `call.StatusNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|connector_id|int||Yes|
+|error_code|str|[`ChargePointErrorCode`](#enums-chargepointerrorcode "ChargePointErrorCode Enumeration Value")|Yes|
+|status|str|[`ChargePointStatus`](#enums-chargepointstatus "ChargePointStatus Enumeration Value")|Yes|
+|timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|info|str|The maximum length: 50|No|
+|vendor_id|str|The maximum length: 255|No|
+|vendor_error_code|str|The maximum length: 50|No|
+
+### A Message Structure That Both The Server and The Client Can Request
+
+#### `call.DataTransferPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|vendor_id|str|The maximum length: 255|Yes|
+|message_id|str|The maximum length: 50|No|
+|data|str||No|
+
+## Response Message Structure
+
+- The response message structure file is `ocpp.v16.call_result`.
+
+### Server Response Client Request Message Structure
+
+#### `call_result.AuthorizePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo Structured Data")|Yes|
+
+#### `call_result.BootNotificationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|current_time|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|interval|int||Yes|
+|status|str|[`RegistrationStatus`](#enums-registrationstatus "RegistrationStatus Enumeration Value")|Yes|
+
+#### `call_result.DiagnosticsStatusNotificationPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.FirmwareStatusNotificationPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.HeartbeatPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|current_time|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+
+#### `call_result.LogStatusNotificationPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.SecurityEventNotificationPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.SignCertificatePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`GenericStatus`](#enums-genericstatus "GenericStatus Enumeration Value")|Yes|
+
+#### `call_result.MeterValuesPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.StartTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|transaction_id|int||Yes|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo Structured Data")|Yes|
+
+#### `call_result.StatusNotificationPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.StopTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo Structured Data")|Yes|
+
+### Client Response Server Sequest Message Structure
+
+#### `call_result.CancelReservationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`CancelReservationStatus`](#enums-cancelreservationstatus "CancelReservationStatus Enumeration Value")|Yes|
+
+#### `call_result.CertificateSignedPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`CertificateSignedStatus`](#enums-certificatesignedstatus "CertificateSignedStatus Enumeration Value")|Yes|
+
+#### `call_result.ChangeAvailabilityPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`AvailabilityStatus`](#enums-availabilitystatus "AvailabilityStatus Enumeration Value")|Yes|
+
+#### `call_result.ChangeConfigurationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`ConfigurationStatus`](#enums-configurationstatus "ConfigurationStatus Enumeration Value")|Yes|
+
+#### `call_result.ClearCachePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`ClearCacheStatus`](#enums-clearcachestatus "ClearCacheStatus Enumeration Value")|Yes|
+
+#### `call_result.ClearChargingProfilePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`ClearChargingProfileStatus`](#enums-clearchargingprofilestatus "ClearChargingProfileStatus Enumeration Value")|Yes|
+
+#### `call_result.DeleteCertificatePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`DeleteCertificateStatus`](#enums-deletecertificatestatus "DeleteCertificateStatus Enumeration Value")|Yes|
+
+#### `call_result.ExtendedTriggerMessagePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`TriggerMessageStatus`](#enums-triggermessagestatus "TriggerMessageStatus Enumeration Value")|Yes|
+
+#### `call_result.GetInstalledCertificateIdsPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`GetInstalledCertificateStatus`](#enums-getinstalledcertificatestatus "GetInstalledCertificateStatus Enumeration Value")|Yes|
+|certificate_hash_data|list|List element is [`CertificateHashData`](#datatypes-certificatehashdata "CertificateHashData Structured Data")|No|
+
+#### `call_result.GetCompositeSchedulePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`GetCompositeScheduleStatus`](#enums-getcompositeschedulestatus "GetCompositeScheduleStatus Enumeration Value")|Yes|
+|connector_id|int||No|
+|schedule_start|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+|charging_schedule|obj|[`ChargingSchedule`](#datatypes-chargingschedule "ChargingSchedule Structured Data")|No|
+
+#### `call_result.GetConfigurationPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|configuration_key|list|List element is [`KeyValue`](#datatypes-keyvalue "KeyValue Structured Data")|No|
+|unknown_key|list|List element `str`, Maximum length of a single string: 50|No|
+
+#### `call_result.GetDiagnosticsPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|file_name|str|The maximum length: 255|No|
+
+#### `call_result.GetLocalListVersionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|list_version|int||Yes|
+
+#### `call_result.GetLogPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`LogStatus`](#enums-logstatus "LogStatus Enumeration Value")|Yes|
+|file_name|str|The maximum length: 255|No|
+
+#### `call_result.InstallCertificatePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`CertificateStatus`](#enums-certificatestatus "CertificateStatus Enumeration Value")|Yes|
+
+#### `call_result.RemoteStartTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`RemoteStartStopStatus`](#enums-remotestartstopstatus "RemoteStartStopStatus Enumeration Value")|Yes|
+
+#### `call_result.RemoteStopTransactionPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`RemoteStartStopStatus`](#enums-remotestartstopstatus "RemoteStartStopStatus Enumeration Value")|Yes|
+
+#### `call_result.ReserveNowPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`ReservationStatus`](#enums-reservationstatus "ReservationStatus Enumeration Value")|Yes|
+
+#### `call_result.ResetPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`ResetStatus`](#enums-resetstatus "ResetStatus Enumeration Value")|Yes|
+
+#### `call_result.SendLocalListPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`UpdateStatus`](#enums-updatestatus "UpdateStatus Enumeration Value")|Yes|
+
+#### `call_result.SetChargingProfilePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`ChargingProfileStatus`](#enums-chargingprofilestatus "ChargingProfileStatus Enumeration Value")|Yes|
+
+#### `call_result.SignedFirmwareStatusNotificationPayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+#### `call_result.SignedUpdateFirmwarePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`UpdateFirmwareStatus`](#enums-updatefirmwarestatus "UpdateFirmwareStatus Enumeration Value")|Yes|
+
+#### `call_result.TriggerMessagePayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`TriggerMessageStatus`](#enums-triggermessagestatus "TriggerMessageStatus Enumeration Value")|Yes|
+
+#### `call_result.UnlockConnectorPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`UnlockStatus`](#enums-unlockstatus "UnlockStatus Enumeration Value")|Yes|
+
+#### `call_result.UpdateFirmwarePayload`
+
+**Parameter Description:**
+
+- No Parameters
+
+### A Response Message Structure That Both The Server and The Client Can Request
+
+#### `call_result.DataTransferPayload`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`DataTransferStatus`](#enums-datatransferstatus "DataTransferStatus Enumeration Value")|Yes|
+|data|str||No|
+
+## Data Structure In Message Body
+
+- Other data structure corresponding files `ocpp.v16.datatypes`
+
+### `datatypes.IdTagInfo`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|status|str|[`AuthorizationStatus`](#enums-authorizationstatus "AuthorizationStatus Enumeration Value")|Yes|
+|parent_id_tag|str|The maximum length: 20|No|
+|expiry_date|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+
+### `datatypes.AuthorizationData`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|id_tag|str||Yes|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo Structured Data")|No|
+
+### `datatypes.ChargingSchedulePeriod`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|start_period|int||Yes|
+|limit|float||Yes|
+|number_phases|int||No|
+
+### `datatypes.ChargingSchedule`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|charging_rate_unit|str|[`ChargingRateUnitType`](#enums-chargingrateunittype "ChargingRateUnitType Enumeration Value")|Yes|
+|charging_schedule_period|list|List element is [`ChargingSchedulePeriod`](#datatypes-chargingscheduleperiod "ChargingSchedulePeriod Structured Data")|Yes|
+|duration|int||No|
+|start_schedule|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+|min_charging_rate|float||No|
+
+### `datatypes.ChargingProfile`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|charging_profile_id|int||Yes|
+|stack_level|int||Yes|
+|charging_profile_purpose|obj|[`ChargingProfilePurposeType`](#enums-chargingprofilepurposetype "ChargingProfilePurposeType Enumeration Value")|Yes|
+|charging_profile_kind|obj|[`ChargingProfileKindType`](#enums-chargingprofilekindtype "ChargingProfileKindType Enumeration Value")|Yes|
+|charging_schedule|obj|[`ChargingSchedule`](#datatypes-chargingschedule "ChargingSchedule Structured Data")|Yes|
+|transaction_id|int||No|
+|recurrency_kind|str|[`RecurrencyKind`](#enums-recurrencykind "RecurrencyKind Enumeration Value")|No|
+|valid_from|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+|valid_to|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+
+### `datatypes.KeyValue`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|key|str||Yes|
+|readonly|bool||Yes|
+|value|str||No|
+
+### `datatypes.SampledValue`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|value|str||Yes|
+|context|str|[`ReadingContext`](#enums-readingcontext "ReadingContext Enumeration Value")|No|
+|format|str|[`ValueFormat`](#enums-valueformat "ValueFormat Enumeration Value")|No|
+|measurand|str|[`Measurand`](#enums-measurand "Measurand Enumeration Value")|No|
+|phase|str|[`Phase`](#enums-phase "Phase Enumeration Value")|No|
+|location|str|[`Location`](#enums-location "Location Enumeration Value")|No|
+|unit|str|[`UnitOfMeasure`](#enums-unitofmeasure "UnitOfMeasure Enumeration Value")|No|
+
+### `datatypes.MeterValue`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|sampled_value|list|List element is [`SampledValue`](#datatypes-sampledvalue "SampledValue Structured Data")|No|
+
+### `datatypes.CertificateHashData`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|hash_algorithm|str|[`HashAlgorithm`](#enums-hashalgorithm "HashAlgorithm Enumeration Value")|Yes|
+|issuer_name_hash|str|The maximum length: 128|Yes|
+|issuer_key_hash|str|The maximum length: 128|Yes|
+|serial_number|str|The maximum length: 40|Yes|
+
+### `datatypes.Firmware`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|location|str|The maximum length: 512|Yes|
+|retrieve_date_time|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|Yes|
+|signing_certificate|str|The maximum length: 5500|Yes|
+|signature|str|The maximum length: 800|Yes|
+|install_date_time|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+
+### `datatypes.LogParameters`
+
+**Parameter Description:**
+
+|Parameter|Type|Description|Required|
+|:---|:---|:---|:---|
+|remote_location|str|The maximum length: 512|Yes|
+|oldest_timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+|latest_timestamp|str|UTC time (YYYY-MM-DDTHH:mm:SS.000000)|No|
+
+## Enumeration Value In Message Body
+
+- The enumeration value corresponds to the file `ocpp.v16.enums`.
+
+### `enums.Action`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|Authorize|str|`Authorize`|
+|BootNotification|str|`BootNotification`|
+|CancelReservation|str|`CancelReservation`|
+|CertificateSigned|str|`CertificateSigned`|
+|ChangeAvailability|str|`ChangeAvailability`|
+|ChangeConfiguration|str|`ChangeConfiguration`|
+|ClearCache|str|`ClearCache`|
+|ClearChargingProfile|str|`ClearChargingProfile`|
+|DataTransfer|str|`DataTransfer`|
+|DeleteCertificate|str|`DeleteCertificate`|
+|DiagnosticsStatusNotification|str|`DiagnosticsStatusNotification`|
+|ExtendedTriggerMessage|str|`ExtendedTriggerMessage`|
+|FirmwareStatusNotification|str|`FirmwareStatusNotification`|
+|GetCompositeSchedule|str|`GetCompositeSchedule`|
+|GetConfiguration|str|`GetConfiguration`|
+|GetDiagnostics|str|`GetDiagnostics`|
+|GetInstalledCertificateIds|str|`GetInstalledCertificateIds`|
+|GetLocalListVersion|str|`GetLocalListVersion`|
+|GetLog|str|`GetLog`|
+|Heartbeat|str|`Heartbeat`|
+|InstallCertificate|str|`InstallCertificate`|
+|LogStatusNotification|str|`LogStatusNotification`|
+|MeterValues|str|`MeterValues`|
+|RemoteStartTransaction|str|`RemoteStartTransaction`|
+|RemoteStopTransaction|str|`RemoteStopTransaction`|
+|ReserveNow|str|`ReserveNow`|
+|Reset|str|`Reset`|
+|SecurityEventNotification|str|`SecurityEventNotification`|
+|SendLocalList|str|`SendLocalList`|
+|SetChargingProfile|str|`SetChargingProfile`|
+|SignCertificate|str|`SignCertificate`|
+|SignedFirmwareStatusNotification|str|`SignedFirmwareStatusNotification`|
+|SignedUpdateFirmware|str|`SignedUpdateFirmware`|
+|StartTransaction|str|`StartTransaction`|
+|StatusNotification|str|`StatusNotification`|
+|StopTransaction|str|`StopTransaction`|
+|TriggerMessage|str|`TriggerMessage`|
+|UnlockConnector|str|`UnlockConnector`|
+|UpdateFirmware|str|`UpdateFirmware`|
+
+### `enums.AuthorizationStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|blocked|str|`Blocked`|
+|expired|str|`Expired`|
+|invalid|str|`Invalid`|
+|concurrent_tx|str|`ConcurrentTx`|
+
+### `enums.AvailabilityStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|scheduled|str|`Scheduled`|
+
+### `enums.AvailabilityType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|inoperative|str|`Inoperative`|
+|operative|str|`Operative`|
+
+### `enums.CancelReservationStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.CertificateSignedStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.CertificateStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|failed|str|`Failed`|
+
+### `enums.CertificateUse`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|central_system_root_certificate|str|`CentralSystemRootCertificate`|
+|manufacturer_root_certificate|str|`ManufacturerRootCertificate`|
+
+### `enums.ChargePointErrorCode`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|connector_lock_failure|str|`ConnectorLockFailure`|
+|ev_communication_error|str|`EVCommunicationError`|
+|ground_failure|str|`GroundFailure`|
+|high_temperature|str|`HighTemperature`|
+|internal_error|str|`InternalError`|
+|local_list_conflict|str|`LocalListConflict`|
+|no_error|str|`NoError`|
+|other_error|str|`OtherError`|
+|over_current_failure|str|`OverCurrentFailure`|
+|over_voltage|str|`OverVoltage`|
+|power_meter_failure|str|`PowerMeterFailure`|
+|power_switch_failure|str|`PowerSwitchFailure`|
+|reader_failure|str|`ReaderFailure`|
+|reset_failure|str|`ResetFailure`|
+|under_voltage|str|`UnderVoltage`|
+|weak_signal|str|`WeakSignal`|
+
+### `enums.ChargePointStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|available|str|`Available`|
+|preparing|str|`Preparing`|
+|charging|str|`Charging`|
+|suspended_evse|str|`SuspendedEVSE`|
+|suspended_ev|str|`SuspendedEV`|
+|finishing|str|`Finishing`|
+|reserved|str|`Reserved`|
+|unavailable|str|`Unavailable`|
+|faulted|str|`Faulted`|
+
+### `enums.ChargingProfileKindType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|absolute|str|`Absolute`|
+|recurring|str|`Recurring`|
+|relative|str|`Relative`|
+
+### `enums.ChargingProfilePurposeType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|charge_point_max_profile|str|`ChargePointMaxProfile`|
+|tx_default_profile|str|`TxDefaultProfile`|
+|tx_profile|str|`TxProfile`|
+
+### `enums.ChargingProfileStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|not_supported|str|`NotSupported`|
+
+### `enums.ChargingRateUnitType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|watts|str|`W`|
+|amps|str|`A`|
+
+### `enums.CiStringType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|ci_string_20|int|`20`|
+|ci_string_25|int|`25`|
+|ci_string_50|int|`50`|
+|ci_string_255|int|`255`|
+|ci_string_500|int|`500`|
+
+### `enums.ClearCacheStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.ClearChargingProfileStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|unknown|str|`Unknown`|
+
+### `enums.ConfigurationStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|reboot_required|str|`RebootRequired`|
+|not_supported|str|`NotSupported`|
+
+### `enums.ConfigurationKey`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|allow_offline_tx_for_unknown_id|str|`AllowOfflineTxForUnknownId`|
+|authorization_cache_enabled|str|`AuthorizationCacheEnabled`|
+|authorize_remote_tx_requests|str|`AuthorizeRemoteTxRequests`|
+|blink_repeat|str|`BlinkRepeat`|
+|clock_aligned_data_interval|str|`ClockAlignedDataInterval`|
+|connection_time_out|str|`ConnectionTimeOut`|
+|connector_phase_rotation|str|`ConnectorPhaseRotation`|
+|connector_phase_rotation_max_length|str|`ConnectorPhaseRotationMaxLength`|
+|get_configuration_max_keys|str|`GetConfigurationMaxKeys`|
+|heartbeat_interval|str|`HeartbeatInterval`|
+|light_intensity|str|`LightIntensity`|
+|local_authorize_offline|str|`LocalAuthorizeOffline`|
+|local_pre_authorize|str|`LocalPreAuthorize`|
+|max_energy_on_invalid_id|str|`MaxEnergyOnInvalidId`|
+|meter_values_aligned_data|str|`MeterValuesAlignedData`|
+|meter_values_aligned_data_max_length|str|`MeterValuesAlignedDataMaxLength`|
+|meter_values_sampled_data|str|`MeterValuesSampledData`|
+|meter_values_sampled_data_max_length|str|`MeterValuesSampledDataMaxLength`|
+|meter_value_sample_interval|str|`MeterValueSampleInterval`|
+|minimum_status_duration|str|`MinimumStatusDuration`|
+|number_of_connectors|str|`NumberOfConnectors`|
+|reset_retries|str|`ResetRetries`|
+|stop_transaction_on_ev_side_disconnect|str|`StopTransactionOnEVSideDisconnect`|
+|stop_transaction_on_invalid_id|str|`StopTransactionOnInvalidId`|
+|stop_txn_aligned_data|str|`StopTxnAlignedData`|
+|stop_txn_aligned_data_max_length|str|`StopTxnAlignedDataMaxLength`|
+|stop_txn_sampled_data|str|`StopTxnSampledData`|
+|stop_txn_sampled_data_max_length|str|`StopTxnSampledDataMaxLength`|
+|supported_feature_profiles|str|`SupportedFeatureProfiles`|
+|supported_feature_profiles_max_length|str|`SupportedFeatureProfilesMaxLength`|
+|transaction_message_attempts|str|`TransactionMessageAttempts`|
+|transaction_message_retry_interval|str|`TransactionMessageRetryInterval`|
+|unlock_connector_on_ev_side_disconnect|str|`UnlockConnectorOnEVSideDisconnect`|
+|web_socket_ping_interval|str|`WebSocketPingInterval`|
+|local_auth_list_enabled|str|`LocalAuthListEnabled`|
+|local_auth_list_max_length|str|`LocalAuthListMaxLength`|
+|send_local_list_max_length|str|`SendLocalListMaxLength`|
+|reserve_connector_zero_supported|str|`ReserveConnectorZeroSupported`|
+|charge_profile_max_stack_level|str|`ChargeProfileMaxStackLevel`|
+|charging_schedule_allowed_charging_rate_unit|str|`ChargingScheduleAllowedChargingRateUnit`|
+|charging_schedule_max_periods|str|`ChargingScheduleMaxPeriods`|
+|connector_switch_3to1_phase_supported|str|`ConnectorSwitch3to1PhaseSupported`|
+|max_charging_profiles_installed|str|`MaxChargingProfilesInstalled`|
+|central_contract_validation_allowed|str|`CentralContractValidationAllowed`|
+|certificate_signed_max_chain_size|str|`CertificateSignedMaxChainSize`|
+|cert_signing_wait_minimum|str|`CertSigningWaitMinimum`|
+|cert_signing_repeat_times|str|`CertSigningRepeatTimes`|
+|certificate_store_max_length|str|`CertificateStoreMaxLength`|
+|contract_validation_offline|str|`ContractValidationOffline`|
+|iso_15118_pnc_enabled|str|`ISO15118PnCEnabled`|
+|additional_root_certificate_check|str|`AdditionalRootCertificateCheck`|
+|authorization_key|str|`AuthorizationKey`|
+|cpo_name|str|`CpoName`|
+|security_profile|str|`SecurityProfile`|
+
+### `enums.DataTransferStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|unknown_message_id|str|`UnknownMessageId`|
+|unknown_vendor_id|str|`UnknownVendorId`|
+
+### `enums.DeleteCertificateStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|failed|str|`Failed`|
+|not_found|str|`NotFound`|
+
+### `enums.DiagnosticsStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|idle|str|`Idle`|
+|uploaded|str|`Uploaded`|
+|upload_failed|str|`UploadFailed`|
+|uploading|str|`Uploading`|
+
+### `enums.FirmwareStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|downloaded|str|`Downloaded`|
+|download_failed|str|`DownloadFailed`|
+|downloading|str|`Downloading`|
+|idle|str|`Idle`|
+|installation_failed|str|`InstallationFailed`|
+|installing|str|`Installing`|
+|installed|str|`Installed`|
+|download_scheduled|str|`DownloadScheduled`|
+|download_paused|str|`DownloadPaused`|
+|install_rebooting|str|`InstallRebooting`|
+|install_scheduled|str|`InstallScheduled`|
+|install_verification_failed|str|`InstallVerificationFailed`|
+|invalid_signature|str|`InvalidSignature`|
+|signature_verified|str|`SignatureVerified`|
+
+### `enums.GenericStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.GetCompositeScheduleStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.GetInstalledCertificateStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|not_found|str|`NotFound`|
+
+### `enums.HashAlgorithm`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|sha256|str|`SHA256`|
+|sha384|str|`SHA384`|
+|sha512|str|`SHA512`|
+
+### `enums.Location`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|inlet|str|`Inlet`|
+|outlet|str|`Outlet`|
+|body|str|`Body`|
+|cable|str|`Cable`|
+|ev|str|`EV`|
+
+### `enums.Log`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|diagnostics_log|str|`DiagnosticsLog`|
+|security_log|str|`SecurityLog`|
+
+### `enums.LogStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|accepted_canceled|str|`AcceptedCanceled`|
+
+### `enums.Measurand`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|current_export|str|`Current.Export`|
+|current_import|str|`Current.Import`|
+|current_offered|str|`Current.Offered`|
+|energy_active_export_register|str|`Energy.Active.Export.Register`|
+|energy_active_import_register|str|`Energy.Active.Import.Register`|
+|energy_reactive_export_register|str|`Energy.Reactive.Export.Register`|
+|energy_reactive_import_register|str|`Energy.Reactive.Import.Register`|
+|energy_active_export_interval|str|`Energy.Active.Export.Interval`|
+|energy_active_import_interval|str|`Energy.Active.Import.Interval`|
+|energy_reactive_export_interval|str|`Energy.Reactive.Export.Interval`|
+|energy_reactive_import_interval|str|`Energy.Reactive.Import.Interval`|
+|frequency|str|`Frequency`|
+|power_active_export|str|`Power.Active.Export`|
+|power_active_import|str|`Power.Active.Import`|
+|power_factor|str|`Power.Factor`|
+|power_offered|str|`Power.Offered`|
+|power_reactive_export|str|`Power.Reactive.Export`|
+|power_reactive_import|str|`Power.Reactive.Import`|
+|rpm|str|`RPM`|
+|soc|str|`SoC`|
+|temperature|str|`Temperature`|
+|voltage|str|`Voltage`|
+
+### `enums.MessageTrigger`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|boot_notification|str|`BootNotification`|
+|firmware_status_notification|str|`FirmwareStatusNotification`|
+|heartbeat|str|`Heartbeat`|
+|meter_values|str|`MeterValues`|
+|status_notification|str|`StatusNotification`|
+|diagnostics_status_notification|str|`DiagnosticsStatusNotification`|
+|log_status_notification|str|`LogStatusNotification`|
+|sign_charge_point_certificate|str|`SignChargePointCertificate`|
+
+### `enums.Phase`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|l1|str|`L1`|
+|l2|str|`L2`|
+|l3|str|`L3`|
+|n|str|`N`|
+|l1_n|str|`L1-N`|
+|l2_n|str|`L2-N`|
+|l3_n|str|`L3-N`|
+|l1_l2|str|`L1-L2`|
+|l2_l3|str|`L2-L3`|
+|l3_l1|str|`L3-L1`|
+
+### `enums.ReadingContext`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|interruption_begin|str|`Interruption.Begin`|
+|interruption_end|str|`Interruption.End`|
+|other|str|`Other`|
+|sample_clock|str|`Sample.Clock`|
+|sample_periodic|str|`Sample.Periodic`|
+|transaction_begin|str|`Transaction.Begin`|
+|transaction_end|str|`Transaction.End`|
+|trigger|str|`Trigger`|
+
+### `enums.Reason`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|emergency_stop|str|`EmergencyStop`|
+|ev_disconnected|str|`EVDisconnected`|
+|hard_reset|str|`HardReset`|
+|local|str|`Local`|
+|other|str|`Other`|
+|power_loss|str|`PowerLoss`|
+|reboot|str|`Reboot`|
+|remote|str|`Remote`|
+|soft_reset|str|`SoftReset`|
+|unlock_command|str|`UnlockCommand`|
+|de_authorized|str|`DeAuthorized`|
+
+### `enums.RecurrencyKind`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|daily|str|`Daily`|
+|weekly|str|`Weekly`|
+
+### `enums.RegistrationStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|pending|str|`Pending`|
+|rejected|str|`Rejected`|
+
+### `enums.RemoteStartStopStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.ReservationStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|faulted|str|`Faulted`|
+|occupied|str|`Occupied`|
+|rejected|str|`Rejected`|
+|unavailable|str|`Unavailable`|
+
+### `enums.ResetStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.ResetType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|hard|str|`Hard`|
+|soft|str|`Soft`|
+
+### `enums.TriggerMessageStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|not_implemented|str|`NotImplemented`|
+
+### `enums.UnitOfMeasure`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|wh|str|`Wh`|
+|kwh|str|`kWh`|
+|varh|str|`varh`|
+|kvarh|str|`kvarh`|
+|w|str|`W`|
+|kw|str|`kW`|
+|va|str|`VA`|
+|kva|str|`kVA`|
+|var|str|`var`|
+|kvar|str|`kvar`|
+|a|str|`A`|
+|v|str|`V`|
+|celsius|str|`Celsius`|
+|fahrenheit|str|`Fahrenheit`|
+|k|str|`K`|
+|percent|str|`Percent`|
+|hertz|str|`Hertz`|
+
+### `enums.UnlockStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|unlocked|str|`Unlocked`|
+|unlock_failed|str|`UnlockFailed`|
+|not_supported|str|`NotSupported`|
+
+### `enums.UpdateFirmwareStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|accepted_canceled|str|`AcceptedCanceled`|
+|invalid_certificate|str|`InvalidCertificate`|
+|revoked_certificate|str|`RevokedCertificate`|
+
+### `enums.UploadLogStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|bad_message|str|`BadMessage`|
+|idle|str|`Idle`|
+|not_supported_operation|str|`NotSupportedOperation`|
+|permission_denied|str|`PermissionDenied`|
+|uploaded|str|`Uploaded`|
+|upload_failure|str|`UploadFailure`|
+|uploading|str|`Uploading`|
+
+### `enums.UpdateStatus`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|failed|str|`Failed`|
+|not_supported|str|`NotSupported`|
+|version_mismatch|str|`VersionMismatch`|
+
+### `enums.UpdateType`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|differential|str|`Differential`|
+|full|str|`Full`|
+
+### `enums.ValueFormat`
+
+|Enumeration Value|Data Type|Corresponding Value|
+|:---|:---|:---|
+|raw|str|`Raw`|
+|signed_data|str|`SignedData`|
diff --git "a/docs/zh/API\345\217\202\350\200\203\346\211\213\345\206\214.md" "b/docs/zh/API\345\217\202\350\200\203\346\211\213\345\206\214.md"
new file mode 100644
index 0000000..0f4671a
--- /dev/null
+++ "b/docs/zh/API\345\217\202\350\200\203\346\211\213\345\206\214.md"
@@ -0,0 +1,185 @@
+# OCPP API 参考手册
+
+中文 | [English](../en/API_Reference.md)
+
+本模块协议功能基于 websocket,使用 json 格式数据进行数据交互。
+
+本模块设计 `ocpp.charge_point.ChargePoint` 抽象类,用来做为基类,用户需要根据自己项目的实际情况进行二次开发,基于该抽象类封装自己项目需要用到的,对应版本的,发送和接收功能。
+
+目前项目只支持 OCPP v1.6 版本,后续会继续进行扩展支持。
+
+本文主要分为两个模块:
+
+1. `ChargePoint` 基类的相关接口与关联装饰器的介绍与使用说明。
+2. 基于 `ChargePoint` 基类实现数据发送和接收接口的二次开发示例。
+
+## 充电站/充电点抽象类
+
+### `ChargePoint`
+
+- `ocpp.charge_point.ChargePoint` 为一个充电站/充电点抽象。
+- 该抽象类封装了基于 websocket 协议的数据发送 [`call`](#cp-call) 接口和用于接收服务器消息并处理的 [`start`](#cp-start) 接口。
+- 该抽象类的二次开发,需要配合 [`ocpp.routing.on`](#routing-on) 和 [`ocpp.routing.atfer`](#routing-after) 装饰器封装接收消息处理函数。
+- 该抽象类通常在对应版本中进行了继承,如:`ocpp.v16.ChargePoint`,添加了 [`_call`](#cp-_call),[`_call_result`](#cp-_call_result),[`_ocpp_version`](#cp-_ocpp_version) 属性值。
+- 该模块基于 websocket 协议,需使用 [QuecPython uwebscoket](https://python.quectel.com/doc/API_reference/zh/networklib/uwebsocket.html "QuecPython uwebsocket 模块使用说明") 模块。
+
+#### 初始化
+
+```python
+from usr.tools import uwebsocket
+from usr.ocpp.v16 import ChargePoint as cp
+
+# 建议使用设备 IMEI 或设备 MAC 地址做为设备唯一标识。
+IMEI = "XXXX"
+# 对应服务器的 IP 地址。
+host = "xxx.xxx.xxx.xxx"
+# 对应服务器的端口号。
+port = "xxxx"
+# 实例化一个 uwebsocket 对象。
+ws = uwebsocket.Client.connect(
+ "ws://{host}:{port}/{IMEI}",
+ # 在 header 中添加对应的 OCPP 版本号用于服务端进行识别,不同的服务端有不同的要求,按实际的情况进行填写。
+ headers={"Sec-WebSocket-Protocol": "ocpp1.6.0"},
+ debug=False
+)
+
+# 实例化 ChargePoint 对象。
+cp = ChargePoint(IMEI, ws)
+```
+
+**参数说明:**
+
+|参数|类型|说明|
+|:---|:---|:---|
+|id|str|设备标识|
+|connection|obj|uwebsocket 实例对象|
+|response_timeout|int|请求应答超时时间,单位:秒,默认:30|
+
+**返回值说明:**
+
+|类型|说明|
+|:---|:---|
+|obj|ChargePoint 客户端实例对象|
+
+#### `ChargePoint.start`
+
+- 启动一个循环用于接收服务器数据,通常单独启动一个线程运行该方法。
+
+```python
+import _thread
+
+# 设置线程栈大小,根据实际使用情况设置。
+_thread.stack_size(0x4000)
+# 启动一个线程用于接收和解析服务器下发的数据。
+_thread.start_new_thread(cp.start, ())
+```
+
+#### `ChargePoint.call`
+
+- 向服务端发送 Call 消息并返回响应的有效负载。
+- 该方法通常在二次封装的函数中进行使用。
+
+```python
+class ChargePoint(cp):
+
+ # 客户端发送请求认证接口。
+ def send_authorize(self):
+ # 使用 AuthorizePayload 类生成客户端请求认证接口的数据结构体。
+ request = self._call.AuthorizePayload(
+ id_tag="xxx",
+ )
+ # 调用 call 方法发送消息并等待接收应答。
+ response = self.call(request)
+ logger.info("response %s" % response)
+
+ # 判断应答解析后是否为请求认证接口的应答数据结构体,是则进行应答数据的处理。
+ if isinstance(response, self._call_result.AuthorizePayload):
+ logger.info("id_tag_info %s." % response.id_tag_info)
+```
+
+**参数说明:**
+
+|参数|类型|说明|
+|:---|:---|:---|
+|payload|obj|`vxx.call.xxx` 请求消息数据结构体对象|
+|suppress|bool|当请求返回 CallError 时,是否会抛出异常
`True` - 跳过异常直接返回
`False` - 抛出异常
默认:`True`|
+|unique_id|str|消息唯一标识,当不传时,则自动生成一个 uuid4 的值做为唯一标识,默认:None|
+
+**返回值说明:**
+
+|类型|说明|
+|:---|:---|
+|obj|`vxx.call_result.xxx` 应答消息数据结构体对象|
+
+#### `ChargePoint._call`
+
+- 当从对应版本模块中导入该类时,则会有该属性,为对应版本的 `call` 模块,如:`ocpp.v16.ChargePoint._call` 等价于 `ocpp.v16.call`。
+- 该属性主要用于二次开发时,封装接口时方便使用。
+- [OCPP v1.6 请求消息数据结构](./请求与应答消息数据结构说明_V16.md#request-message-structure)
+
+#### `ChargePoint._call_result`
+
+- 当从对应版本模块中导入该类时,则会有该属性,为对应版本的 `call_result` 模块,如:`ocpp.v16.ChargePoint._call_result` 等价于 `ocpp.v16.call_result`。
+- 该属性主要用于二次开发时,封装接口时方便使用。
+- [OCPP v1.6 应答消息数据结构](./请求与应答消息数据结构说明_V16.md#response-message-structure)
+
+#### `ChargePoint._ocpp_version`
+
+- 当从对应版本模块中导入该类时,则会有该属性,为对应的 ocpp 协议版本号。
+
+## 处理服务器消息的函数的装饰器
+
+### `ocpp.routing.on`
+
+- 该装饰器用于处理对应服务器下发消息的封装函数。
+- 被装饰的函数入参为接收消息的数据结构信息,返回对应消息的应答的数据结构信息,用于发送给服务器进行消息应答。
+
+```python
+class ChargePoint(cp):
+
+ # 客户端接收取消预订消息处理接口,使用 ocpp.routing.on 装饰器注册对应接收消息的处理函数,
+ # 该函数用于接收对应消息的消息体数据,并需要返回对应消息的应答数据结构体。
+ @on(Action.CancelReservation)
+ def on_cancel_reservation(self, reservation_id):
+ logger.info("reservation_id %s" % (reservation_id))
+
+ # 当收到消息后,可以在此处进行业务功能的处理,
+ # 或者先进行应答,然后再在 ocpp.routing.after 装饰的函数内进行业务处理。
+
+ # 该函数必须返回对应消息的应答消息体,用于应答服务器消息。
+ return self._call_result.CancelReservationPayload(
+ status=CancelReservationStatus.accepted
+ )
+```
+
+**参数说明:**
+
+|参数|类型|说明|
+|:---|:---|:---|
+|action|str|对应的消息类型,可以直接使用 `ocpp.vxx.enums.Actions` 枚举值中的数据|
+|skip_schema_validation|bool|是否跳过请求或应答消息体数据校验
`True` - 跳过校验
`False` - 不跳过校验
默认:`False`|
+|call_unique_id_required|bool|是否将消息唯一标识做为参数传入被装饰的函数
`True` - 是
`False` - 否
默认:`False`|
+
+### `ocpp.routing.after`
+
+- 该装饰器用于处理对应服务器下发消息的封装函数,其在 `ocpp.routing.on` 装饰的函数调用之后进行调用。
+- 被装饰的函数入参为接收消息的数据结构信息,返回值无特殊要求。
+
+```python
+class ChargePoint(cp):
+
+ # 客户端在接收到取消预订消息后,在应答完成后或无需应答之后,需要进行的业务处理功能,
+ # 可以使用 ocpp.routing.after 装饰器注册对应接收消息的处理函数。
+ @after(Action.CancelReservation, call_unique_id_required=True)
+ def after_cancel_reservation(self, reservation_id, call_unique_id):
+ logger.info("reservation_id %s, call_unique_id %s" % (reservation_id, call_unique_id))
+ # 可以在此处处理对应的业务功能,该函数对返回值无特殊要求。
+ return
+```
+
+**参数说明:**
+
+|参数|类型|说明|
+|:---|:---|:---|
+|action|str|对应的消息类型,可以直接使用 `ocpp.vxx.enums.Actions` 枚举值中的数据|
+|call_unique_id_required|bool|是否将消息唯一标识做为参数传入被装饰的函数
`True` - 是
`False` - 否
默认:`False`|
diff --git "a/docs/zh/\347\224\250\346\210\267\344\275\277\347\224\250\346\211\213\345\206\214.md" "b/docs/zh/\347\224\250\346\210\267\344\275\277\347\224\250\346\211\213\345\206\214.md"
new file mode 100644
index 0000000..b6ddae8
--- /dev/null
+++ "b/docs/zh/\347\224\250\346\210\267\344\275\277\347\224\250\346\211\213\345\206\214.md"
@@ -0,0 +1,161 @@
+# 用户使用手册
+
+- 该库的目的是提供构建充电站/充电点的构建块。 **该库不提供完整的解决方案,因为任何实现都是特定于其预期用途的**。
+- 该库依赖项 [`uwebsocket`](../../code/tools/uwebsocket.py),[uwebsocket 相关说明](https://python.quectel.com/doc/API_reference/zh/networklib/uwebsocket.html)可点击跳转官网查看。
+- 本文档提供了有关如何最好地构建完整解决方案的指导。
+
+## 如何使用
+
+### 运行 OCPP 服务器
+
+> 如果您有自己的 OCPP 服务器,则可以跳过此说明。
+
+#### 1. 安装环境
+
+- 操作系统:Window or Linux.
+
+- 语言:Python (Python-3.11.2).
+
+- 依赖包:`pip install -r demo/requirements.txt`.
+
+#### 2. 配置服务器并运行演示
+
+- 在 [`v16_server_demo.py`](../../demo/v16_server_demo.py) 中更改服务器端口。
+
+```python
+async def main():
+ server = await websockets.serve(
+ on_connect,
+ '0.0.0.0',
+ 31499, # Change this port value for your own server port.
+ subprotocols=['ocpp1.6.0']
+ )
+ logging.info("WebSocket Server Started")
+ await server.wait_closed()
+```
+
+- 运行 `python v16_server_demo.py`。当输出 `INFO:root:WebSocket Server Started`,则服务端已启动。
+
+```python
+>>> python v16_server_demo.py
+
+INFO:websockets.server:server listening on 0.0.0.0:31499
+INFO:root:WebSocket Server Started
+```
+
+### 运行 OCPP 客户端
+
+#### 1. 运行环境
+
+您需要使用我们的 QuecPython 模块。
+
+#### 2. 配置客户端并运行示例
+
+- 在 [`v16_client_qpy_demo.py`](../../code/v16_client_qpy_demo.py) 中配置您的服务器主机和端口
+
+```python
+if __name__ == "__main__":
+ ws = uwebsocket.Client.connect(
+ "ws://xxx.xxx.xxx.xxx:xxxx/%s" % IMEI, # Use your own server host and port to replace `xxx.xxx.xxx.xxx:xxxx`.
+ headers={"Sec-WebSocket-Protocol": "ocpp1.6.0"},
+ debug=True
+ )
+ cp = ChargePoint(IMEI, ws)
+
+ _thread.stack_size(0x2000)
+ tid = _thread.start_new_thread(cp.start, ())
+ utime.sleep_ms(200)
+```
+
+- 将代码下载到 QuecPython 模块
+
+**注意:**
+
+- 您可以在 [QuecPython文档中心](https://python.quectel.com/doc/Getting_started/en/index.html) 找到文档,了解如何下载 Python 代码并在我们的 QuecPython 模块中运行 Python 示例
+- 您可以将完整的 `code` 路径下的代码下载到我们的 QuecPython 模块并运行 [`v16_client_qpy_demo.py`](../../code/v16_client_qpy_demo.py) 来测试 OCPP 充电站/充电点。
+- 您可以在我们的 QPYcom REPL 中看到日志 `Connected to central system.`,则 `BootNotification` 消息已发送到服务器。
+- 您可以参考 [`v16_client_qpy_demo.py`](../../code/v16_client_qpy_demo.py) 编写符合业务逻辑的客户端请求。
+
+## 基于 `ChargePoint` 二次开发示例
+
+- 该抽象类封装了基于 websocket 协议,需要实例化 `uwebsocket` 对象做为参数,进行 `ChargePoint` 模块的初始化。
+- 使用时,从对应的版本中导入 `ChargePoint` 类,如:`from usr.ocpp.v16 import ChargePoint as cp`。
+
+**注意:**
+
+以下只分别列出了一个客户端发送消息和一个客户端接收消息的处理函数的示例做为参考,实际项目需要使用哪些请求消息和接收消息,需要根据项目的实际要求进行开发。
+
+```python
+import utime
+import _thread
+# 导入 uwebsocket 模块,实例化对象,用于 ChargePoint 类。
+from usr.tools import uwebsocket, logging
+# 导入 v16 版本的 ChargePoint 做为项目基类。
+from usr.ocpp.v16 import ChargePoint as cp
+
+
+# 基于 v16 版本的项目基类进行二次开发,封装需要用到的客户端发送接口和消息接收的接口。
+class ChargePoint(cp):
+
+ # 客户端发送请求认证接口。
+ def send_authorize(self):
+ # 使用 AuthorizePayload 类生成客户端请求认证接口的数据结构体。
+ request = self._call.AuthorizePayload(
+ id_tag="xxx",
+ )
+ # 调用 call 方法发送消息并等待接收应答。
+ response = self.call(request)
+ logger.info("response %s" % response)
+
+ # 判断应答解析后是否为请求认证接口的应答数据结构体,是则进行应答数据的处理。
+ if isinstance(response, self._call_result.AuthorizePayload):
+ logger.info("id_tag_info %s." % response.id_tag_info)
+
+ # 客户端接收取消预订消息处理接口,使用 ocpp.routing.on 装饰器注册对应接收消息的处理函数,
+ # 该函数用于接收对应消息的消息体数据,并需要返回对应消息的应答数据结构体。
+ @on(Action.CancelReservation)
+ def on_cancel_reservation(self, reservation_id):
+ logger.info("reservation_id %s" % (reservation_id))
+
+ # 当收到消息后,可以在此处进行业务功能的处理,
+ # 或者先进行应答,然后再在 ocpp.routing.after 装饰的函数内进行业务处理。
+
+ # 该函数必须返回对应消息的应答消息体,用于应答服务器消息。
+ return self._call_result.CancelReservationPayload(
+ status=CancelReservationStatus.accepted
+ )
+
+ # 客户端在接收到取消预订消息后,在应答完成后或无需应答之后,需要进行的业务处理功能,
+ # 可以使用 ocpp.routing.after 装饰器注册对应接收消息的处理函数。
+ @after(Action.CancelReservation)
+ def after_cancel_reservation(self, reservation_id):
+ logger.info("reservation_id %s" % (reservation_id))
+ # 可以在此处处理对应的业务功能,该函数对返回值无特殊要求。
+ return
+
+# 建议使用设备 IMEI 或设备 MAC 地址做为设备标识。
+IMEI = "XXXX"
+# 对应服务器的 IP 地址。
+host = "xxx.xxx.xxx.xxx"
+# 对应服务器的端口号。
+port = "xxxx"
+# 实例化一个 uwebsocket 对象。
+ws = uwebsocket.Client.connect(
+ "ws://{host}:{port}/{IMEI}",
+ # 在 header 中添加对应的 OCPP 版本号用于服务端进行识别,不同的服务端有不同的要求,按实际的情况进行填写。
+ headers={"Sec-WebSocket-Protocol": "ocpp1.6.0"},
+ debug=False
+)
+
+# 实例化二次开发的包含具体业务功能的 ChargePoint 对象。
+cp = ChargePoint(IMEI, ws)
+
+# 启动一个线程用于接收服务器下发的数据。
+_thread.start_new_thread(cp.start, ())
+
+# 发送请求认证消息。
+cp.send_authorize()
+
+# 等待接收服务器数据。
+utime.sleep(10)
+```
diff --git "a/docs/zh/\350\257\267\346\261\202\344\270\216\345\272\224\347\255\224\346\266\210\346\201\257\346\225\260\346\215\256\347\273\223\346\236\204\350\257\264\346\230\216_V16.md" "b/docs/zh/\350\257\267\346\261\202\344\270\216\345\272\224\347\255\224\346\266\210\346\201\257\346\225\260\346\215\256\347\273\223\346\236\204\350\257\264\346\230\216_V16.md"
new file mode 100644
index 0000000..daa44ac
--- /dev/null
+++ "b/docs/zh/\350\257\267\346\261\202\344\270\216\345\272\224\347\255\224\346\266\210\346\201\257\346\225\260\346\215\256\347\273\223\346\236\204\350\257\264\346\230\216_V16.md"
@@ -0,0 +1,1417 @@
+# OCPP v1.6 版本请求与应答消息数据结构说明
+
+中文 | [English](../en/Request_and_Response_Message_Data_Structure_Description_V16.md)
+
+- OCPP v1.6 版本的相关数据模块在 `ocpp.v16` 路径下
+- 所有消息数据结构都抽象为对应消息名称的类,类实例化的参数即为消息体中需要包含的参数,实例化对应的请求消息类对象或应答消息类对象即可
+
+**示例:**
+
+```python
+call.CancelReservationPayload(
+ reservation_id=123
+)
+
+call_result.CancelReservationPayload(
+ status=CancelReservationStatus.accepted
+)
+```
+
+## 请求消息结构体
+
+- 请求消息结构体文件为 `ocpp.v16.call`。
+
+### 服务端请求消息结构体
+
+- 对应客户端接收消息结构体。
+
+#### `call.CancelReservationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|reservation_id|int||是|
+
+#### `call.CertificateSignedPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|certificate_chain|str|最大长度:10000|是|
+
+#### `call.ChangeAvailabilityPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|type|str|[`AvailabilityType`](#enums-availabilitytype "AvailabilityType 枚举值")|是|
+
+#### `call.ChangeConfigurationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|key|str|最大长度:50|是|
+|value|str|最大长度:500|是|
+
+#### `call.ClearCachePayload`
+
+**参数说明:**
+
+- 无
+
+#### `call.ClearChargingProfilePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|id|int||否|
+|connector_id|int||否|
+|charging_profile_purpose|str|[`ChargingProfilePurposeType`](#enums-chargingprofilepurposetype "ChargingProfilePurposeType 枚举值")|否|
+|stack_level|int||否|
+
+#### `call.DeleteCertificatePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|certificate_hash_data|obj|[`CertificateHashData`](#datatypes-certificatehashdata "CertificateHashData 结构数据")|是|
+
+#### `call.ExtendedTriggerMessagePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|requested_message|str|[`MessageTrigger`](#enums-messagetrigger "MessageTrigger 枚举值")|是|
+|connector_id|int||否|
+
+#### `call.GetCompositeSchedulePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|duration|int||是|
+|charging_rate_unit|str|[`ChargingRateUnitType`](#enums-chargingrateunittype "ChargingRateUnitType 枚举值")|是|
+
+#### `call.GetConfigurationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|key|list|列表元素 `str`,单个字符串最大长度:50|否|
+
+#### `call.GetDiagnosticsPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|location|str|uri 数据|是|
+|retries|int||否|
+|retry_interval|int||否|
+|start_time|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+|stop_time|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+
+#### `call.GetInstalledCertificateIdsPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|certificate_type|str|[`CertificateUse`](#enums-certificateuse "CertificateUse 枚举值")|是|
+
+#### `call.GetLocalListVersionPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call.GetLogPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|log|obj|[`LogParameters`](#datatypes-logparameters "LogParameters 结构数据")|是|
+|log_type|str|[`Log`](#enums-log "Log 枚举值")|是|
+|request_id|int||是|
+|retries|int||否|
+|retry_interval|int||否|
+
+#### `call.InstallCertificatePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|certificate_type|str|[`CertificateUse`](#enums-certificateuse "CertificateUse 枚举值")|是|
+|certificate|str|最大长度:5500|是|
+
+#### `call.RemoteStartTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|id_tag|str|最大长度:20|是|
+|connector_id|int||否|
+|charging_profile|obj|[`ChargingProfile`](#datatypes-chargingprofile "ChargingProfile 结构数据")|否|
+
+#### `call.RemoteStopTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|transaction_id|int||是|
+
+#### `call.ReserveNowPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|expiry_date|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|id_tag|str|最大长度:20|是|
+|reservation_id|int||是|
+|parent_id_tag|str|最大长度:20|否|
+
+#### `call.ResetPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|type|str|[`ResetType`](#enums-resettype "ResetType 枚举值")|是|
+
+#### `call.SendLocalListPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|list_version|int||是|
+|update_type|str|[`UpdateType`](#enums-updatetype "UpdateType 枚举值")|是|
+|local_authorization_list|list|列表元素 [`AuthorizationData`](#datatypes-authorizationdata "AuthorizationData 结构数据")|否|
+
+#### `call.SetChargingProfilePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|cs_charging_profiles|obj|[`ChargingProfile`](#datatypes-chargingprofile "ChargingProfile 结构数据")|是|
+
+#### `call.SignedUpdateFirmwarePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|request_id|int||是|
+|firmware|obj|[`Firmware`](#datatypes-firmware "Firmware 结构数据")|是|
+|retries|int||否|
+|retry_interval|int||否|
+
+#### `call.TriggerMessagePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|requested_message|str|[`MessageTrigger`](#enums-messagetrigger "MessageTrigger 枚举值")|是|
+|connector_id|int||否|
+
+#### `call.UnlockConnectorPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+
+#### `call.UpdateFirmwarePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|location|str|uri 数据|是|
+|retrieve_date|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|retries|int||否|
+|retry_interval|int||否|
+
+### 客户端请求消息结构体
+
+- 对应服务端接收消息结构体。
+
+#### `call.AuthorizePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|id_tag|str|最大长度:20|是|
+
+#### `call.BootNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|charge_point_model|str|最大长度:20|是|
+|charge_point_vendor|str|最大长度:20|是|
+|charge_box_serial_number|str|最大长度:25|否|
+|charge_point_serial_number|str|最大长度:25|否|
+|firmware_version|str|最大长度:50|否|
+|iccid|str|最大长度:20|否|
+|imsi|str|最大长度:20|否|
+|meter_serial_number|str|最大长度:25|否|
+|meter_type|str|最大长度:25|否|
+
+#### `call.DiagnosticsStatusNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`DiagnosticsStatus`](#enums-diagnosticsstatus "DiagnosticsStatus 枚举值")|是|
+
+#### `call.FirmwareStatusNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`FirmwareStatus`](#enums-firmwarestatus "FirmwareStatus 枚举值")|是|
+
+#### `call.HeartbeatPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call.LogStatusNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`UploadLogStatus`](#enums-uploadlogstatus "UploadLogStatus 枚举值")|是|
+|request_id|int||是|
+
+#### `call.MeterValuesPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|meter_value|list|列表元素 [`MeterValue`](#datatypes-metervalue "MeterValue 结构数据")|是|
+|transaction_id|int||否|
+
+#### `call.SecurityEventNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|type|str|最大长度:50|是|
+|timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|tech_info|str|最大长度:255|否|
+
+#### `call.SignCertificatePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|csr|str|最大长度:5500|是|
+
+#### `call.SignedFirmwareStatusNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`FirmwareStatus`](#enums-firmwarestatus "FirmwareStatus 枚举值")|是|
+|request_id|int||是|
+
+#### `call.StartTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|id_tag|str|最大长度:20|是|
+|meter_start|int||是|
+|timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|reservation_id|int||否|
+
+#### `call.StopTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|meter_stop|int||是|
+|timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|transaction_id|int||是|
+|reason|str|[`Reason`](#enums-reason "Reason 枚举值")|否|
+|id_tag|str|最大长度:20|否|
+|transaction_data|list|列表元素 [`MeterValue`](#datatypes-metervalue "MeterValue 结构数据")|否|
+
+#### `call.StatusNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|connector_id|int||是|
+|error_code|str|[`ChargePointErrorCode`](#enums-chargepointerrorcode "ChargePointErrorCode 枚举值")|是|
+|status|str|[`ChargePointStatus`](#enums-chargepointstatus "ChargePointStatus 枚举值")|是|
+|timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|info|str|最大长度:50|否|
+|vendor_id|str|最大长度:255|否|
+|vendor_error_code|str|最大长度:50|否|
+
+### 服务器和客户端都可进行请求的消息结构体
+
+#### `call.DataTransferPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|vendor_id|str|最大长度:255|是|
+|message_id|str|最大长度:50|否|
+|data|str||否|
+
+## 应答消息结构体
+
+- 应答消息结构体文件为 `ocpp.v16.call_result`。
+
+### 服务端应答客户端请求消息结构体
+
+#### `call_result.AuthorizePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo 结构数据")|是|
+
+#### `call_result.BootNotificationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|current_time|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|interval|int||是|
+|status|str|[`RegistrationStatus`](#enums-registrationstatus "RegistrationStatus 枚举值")|是|
+
+#### `call_result.DiagnosticsStatusNotificationPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.FirmwareStatusNotificationPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.HeartbeatPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|current_time|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+
+#### `call_result.LogStatusNotificationPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.SecurityEventNotificationPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.SignCertificatePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`GenericStatus`](#enums-genericstatus "GenericStatus 枚举值")|是|
+
+#### `call_result.MeterValuesPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.StartTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|transaction_id|int||是|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo 结构数据")|是|
+
+#### `call_result.StatusNotificationPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.StopTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo 结构数据")|是|
+
+### 客户端应答服务端请求消息结构体
+
+#### `call_result.CancelReservationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`CancelReservationStatus`](#enums-cancelreservationstatus "CancelReservationStatus 枚举值")|是|
+
+#### `call_result.CertificateSignedPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`CertificateSignedStatus`](#enums-certificatesignedstatus "CertificateSignedStatus 枚举值")|是|
+
+#### `call_result.ChangeAvailabilityPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`AvailabilityStatus`](#enums-availabilitystatus "AvailabilityStatus 枚举值")|是|
+
+#### `call_result.ChangeConfigurationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`ConfigurationStatus`](#enums-configurationstatus "ConfigurationStatus 枚举值")|是|
+
+#### `call_result.ClearCachePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`ClearCacheStatus`](#enums-clearcachestatus "ClearCacheStatus 枚举值")|是|
+
+#### `call_result.ClearChargingProfilePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`ClearChargingProfileStatus`](#enums-clearchargingprofilestatus "ClearChargingProfileStatus 枚举值")|是|
+
+#### `call_result.DeleteCertificatePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`DeleteCertificateStatus`](#enums-deletecertificatestatus "DeleteCertificateStatus 枚举值")|是|
+
+#### `call_result.ExtendedTriggerMessagePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`TriggerMessageStatus`](#enums-triggermessagestatus "TriggerMessageStatus 枚举值")|是|
+
+#### `call_result.GetInstalledCertificateIdsPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`GetInstalledCertificateStatus`](#enums-getinstalledcertificatestatus "GetInstalledCertificateStatus 枚举值")|是|
+|certificate_hash_data|list|列表元素 [`CertificateHashData`](#datatypes-certificatehashdata "CertificateHashData 数据结构")|否|
+
+#### `call_result.GetCompositeSchedulePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`GetCompositeScheduleStatus`](#enums-getcompositeschedulestatus "GetCompositeScheduleStatus 枚举值")|是|
+|connector_id|int||否|
+|schedule_start|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+|charging_schedule|obj|[`ChargingSchedule`](#datatypes-chargingschedule "ChargingSchedule 结构数据")|否|
+
+#### `call_result.GetConfigurationPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|configuration_key|list|列表元素 [`KeyValue`](#datatypes-keyvalue "KeyValue 结构数据")|否|
+|unknown_key|list|列表元素 `str`,单个字符串最大长度:50|否|
+
+#### `call_result.GetDiagnosticsPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|file_name|str|最大长度:255|否|
+
+#### `call_result.GetLocalListVersionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|list_version|int||是|
+
+#### `call_result.GetLogPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`LogStatus`](#enums-logstatus "LogStatus 枚举值")|是|
+|file_name|str|最大长度:255|否|
+
+#### `call_result.InstallCertificatePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`CertificateStatus`](#enums-certificatestatus "CertificateStatus 枚举值")|是|
+
+#### `call_result.RemoteStartTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`RemoteStartStopStatus`](#enums-remotestartstopstatus "RemoteStartStopStatus 枚举值")|是|
+
+#### `call_result.RemoteStopTransactionPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`RemoteStartStopStatus`](#enums-remotestartstopstatus "RemoteStartStopStatus 枚举值")|是|
+
+#### `call_result.ReserveNowPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`ReservationStatus`](#enums-reservationstatus "ReservationStatus 枚举值")|是|
+
+#### `call_result.ResetPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`ResetStatus`](#enums-resetstatus "ResetStatus 枚举值")|是|
+
+#### `call_result.SendLocalListPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`UpdateStatus`](#enums-updatestatus "UpdateStatus 枚举值")|是|
+
+#### `call_result.SetChargingProfilePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`ChargingProfileStatus`](#enums-chargingprofilestatus "ChargingProfileStatus 枚举值")|是|
+
+#### `call_result.SignedFirmwareStatusNotificationPayload`
+
+**参数说明:**
+
+- 无
+
+#### `call_result.SignedUpdateFirmwarePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`UpdateFirmwareStatus`](#enums-updatefirmwarestatus "UpdateFirmwareStatus 枚举值")|是|
+
+#### `call_result.TriggerMessagePayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`TriggerMessageStatus`](#enums-triggermessagestatus "TriggerMessageStatus 枚举值")|是|
+
+#### `call_result.UnlockConnectorPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`UnlockStatus`](#enums-unlockstatus "UnlockStatus 枚举值")|是|
+
+#### `call_result.UpdateFirmwarePayload`
+
+**参数说明:**
+
+- 无
+
+### 服务器和客户端都可进行请求的应答消息结构体
+
+#### `call_result.DataTransferPayload`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`DataTransferStatus`](#enums-datatransferstatus "DataTransferStatus 枚举值")|是|
+|data|str||否|
+
+## 消息体中的数据结构
+
+- 其他数据结构对应文件 `ocpp.v16.datatypes`。
+
+### `datatypes.IdTagInfo`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|status|str|[`AuthorizationStatus`](#enums-authorizationstatus "AuthorizationStatus 枚举值")|是|
+|parent_id_tag|str|最大长度:20|否|
+|expiry_date|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+
+### `datatypes.AuthorizationData`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|id_tag|str||是|
+|id_tag_info|obj|[`IdTagInfo`](#datatypes-idtaginfo "IdTagInfo 结构数据")|否|
+
+### `datatypes.ChargingSchedulePeriod`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|start_period|int||是|
+|limit|float||是|
+|number_phases|int||否|
+
+### `datatypes.ChargingSchedule`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|charging_rate_unit|str|[`ChargingRateUnitType`](#enums-chargingrateunittype "ChargingRateUnitType 枚举值")|是|
+|charging_schedule_period|list|列表元素 [`ChargingSchedulePeriod`](#datatypes-chargingscheduleperiod "ChargingSchedulePeriod 结构数据")|是|
+|duration|int||否|
+|start_schedule|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+|min_charging_rate|float||否|
+
+### `datatypes.ChargingProfile`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|charging_profile_id|int||是|
+|stack_level|int||是|
+|charging_profile_purpose|obj|[`ChargingProfilePurposeType`](#enums-chargingprofilepurposetype "ChargingProfilePurposeType 枚举值")|是|
+|charging_profile_kind|obj|[`ChargingProfileKindType`](#enums-chargingprofilekindtype "ChargingProfileKindType 枚举值")|是|
+|charging_schedule|obj|[`ChargingSchedule`](#datatypes-chargingschedule "ChargingSchedule 结构数据")|是|
+|transaction_id|int||否|
+|recurrency_kind|str|[`RecurrencyKind`](#enums-recurrencykind "RecurrencyKind 枚举值")|否|
+|valid_from|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+|valid_to|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+
+### `datatypes.KeyValue`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|key|str||是|
+|readonly|bool||是|
+|value|str||否|
+
+### `datatypes.SampledValue`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|value|str||是|
+|context|str|[`ReadingContext`](#enums-readingcontext "ReadingContext 枚举值")|否|
+|format|str|[`ValueFormat`](#enums-valueformat "ValueFormat 枚举值")|否|
+|measurand|str|[`Measurand`](#enums-measurand "Measurand 枚举值")|否|
+|phase|str|[`Phase`](#enums-phase "Phase 枚举值")|否|
+|location|str|[`Location`](#enums-location "Location 枚举值")|否|
+|unit|str|[`UnitOfMeasure`](#enums-unitofmeasure "UnitOfMeasure 枚举值")|否|
+
+### `datatypes.MeterValue`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|sampled_value|list|列表元素 [`SampledValue`](#datatypes-sampledvalue "SampledValue 结构数据")|否|
+
+### `datatypes.CertificateHashData`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|hash_algorithm|str|[`HashAlgorithm`](#enums-hashalgorithm "HashAlgorithm 枚举值")|是|
+|issuer_name_hash|str|最大长度:128|是|
+|issuer_key_hash|str|最大长度:128|是|
+|serial_number|str|最大长度:40|是|
+
+### `datatypes.Firmware`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|location|str|最大长度:512|是|
+|retrieve_date_time|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|是|
+|signing_certificate|str|最大长度:5500|是|
+|signature|str|最大长度:800|是|
+|install_date_time|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+
+### `datatypes.LogParameters`
+
+**参数说明:**
+
+|参数|类型|说明|是否必须|
+|:---|:---|:---|:---|
+|remote_location|str|最大长度:512|是|
+|oldest_timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+|latest_timestamp|str|UTC 时间(YYYY-MM-DDTHH:mm:SS.000000)|否|
+
+## 消息体中的枚举值
+
+- 枚举值对应文件 `ocpp.v16.enums`。
+
+### `enums.Action`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|Authorize|str|`Authorize`|
+|BootNotification|str|`BootNotification`|
+|CancelReservation|str|`CancelReservation`|
+|CertificateSigned|str|`CertificateSigned`|
+|ChangeAvailability|str|`ChangeAvailability`|
+|ChangeConfiguration|str|`ChangeConfiguration`|
+|ClearCache|str|`ClearCache`|
+|ClearChargingProfile|str|`ClearChargingProfile`|
+|DataTransfer|str|`DataTransfer`|
+|DeleteCertificate|str|`DeleteCertificate`|
+|DiagnosticsStatusNotification|str|`DiagnosticsStatusNotification`|
+|ExtendedTriggerMessage|str|`ExtendedTriggerMessage`|
+|FirmwareStatusNotification|str|`FirmwareStatusNotification`|
+|GetCompositeSchedule|str|`GetCompositeSchedule`|
+|GetConfiguration|str|`GetConfiguration`|
+|GetDiagnostics|str|`GetDiagnostics`|
+|GetInstalledCertificateIds|str|`GetInstalledCertificateIds`|
+|GetLocalListVersion|str|`GetLocalListVersion`|
+|GetLog|str|`GetLog`|
+|Heartbeat|str|`Heartbeat`|
+|InstallCertificate|str|`InstallCertificate`|
+|LogStatusNotification|str|`LogStatusNotification`|
+|MeterValues|str|`MeterValues`|
+|RemoteStartTransaction|str|`RemoteStartTransaction`|
+|RemoteStopTransaction|str|`RemoteStopTransaction`|
+|ReserveNow|str|`ReserveNow`|
+|Reset|str|`Reset`|
+|SecurityEventNotification|str|`SecurityEventNotification`|
+|SendLocalList|str|`SendLocalList`|
+|SetChargingProfile|str|`SetChargingProfile`|
+|SignCertificate|str|`SignCertificate`|
+|SignedFirmwareStatusNotification|str|`SignedFirmwareStatusNotification`|
+|SignedUpdateFirmware|str|`SignedUpdateFirmware`|
+|StartTransaction|str|`StartTransaction`|
+|StatusNotification|str|`StatusNotification`|
+|StopTransaction|str|`StopTransaction`|
+|TriggerMessage|str|`TriggerMessage`|
+|UnlockConnector|str|`UnlockConnector`|
+|UpdateFirmware|str|`UpdateFirmware`|
+
+### `enums.AuthorizationStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|blocked|str|`Blocked`|
+|expired|str|`Expired`|
+|invalid|str|`Invalid`|
+|concurrent_tx|str|`ConcurrentTx`|
+
+### `enums.AvailabilityStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|scheduled|str|`Scheduled`|
+
+### `enums.AvailabilityType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|inoperative|str|`Inoperative`|
+|operative|str|`Operative`|
+
+### `enums.CancelReservationStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.CertificateSignedStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.CertificateStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|failed|str|`Failed`|
+
+### `enums.CertificateUse`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|central_system_root_certificate|str|`CentralSystemRootCertificate`|
+|manufacturer_root_certificate|str|`ManufacturerRootCertificate`|
+
+### `enums.ChargePointErrorCode`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|connector_lock_failure|str|`ConnectorLockFailure`|
+|ev_communication_error|str|`EVCommunicationError`|
+|ground_failure|str|`GroundFailure`|
+|high_temperature|str|`HighTemperature`|
+|internal_error|str|`InternalError`|
+|local_list_conflict|str|`LocalListConflict`|
+|no_error|str|`NoError`|
+|other_error|str|`OtherError`|
+|over_current_failure|str|`OverCurrentFailure`|
+|over_voltage|str|`OverVoltage`|
+|power_meter_failure|str|`PowerMeterFailure`|
+|power_switch_failure|str|`PowerSwitchFailure`|
+|reader_failure|str|`ReaderFailure`|
+|reset_failure|str|`ResetFailure`|
+|under_voltage|str|`UnderVoltage`|
+|weak_signal|str|`WeakSignal`|
+
+### `enums.ChargePointStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|available|str|`Available`|
+|preparing|str|`Preparing`|
+|charging|str|`Charging`|
+|suspended_evse|str|`SuspendedEVSE`|
+|suspended_ev|str|`SuspendedEV`|
+|finishing|str|`Finishing`|
+|reserved|str|`Reserved`|
+|unavailable|str|`Unavailable`|
+|faulted|str|`Faulted`|
+
+### `enums.ChargingProfileKindType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|absolute|str|`Absolute`|
+|recurring|str|`Recurring`|
+|relative|str|`Relative`|
+
+### `enums.ChargingProfilePurposeType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|charge_point_max_profile|str|`ChargePointMaxProfile`|
+|tx_default_profile|str|`TxDefaultProfile`|
+|tx_profile|str|`TxProfile`|
+
+### `enums.ChargingProfileStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|not_supported|str|`NotSupported`|
+
+### `enums.ChargingRateUnitType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|watts|str|`W`|
+|amps|str|`A`|
+
+### `enums.CiStringType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|ci_string_20|int|`20`|
+|ci_string_25|int|`25`|
+|ci_string_50|int|`50`|
+|ci_string_255|int|`255`|
+|ci_string_500|int|`500`|
+
+### `enums.ClearCacheStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.ClearChargingProfileStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|unknown|str|`Unknown`|
+
+### `enums.ConfigurationStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|reboot_required|str|`RebootRequired`|
+|not_supported|str|`NotSupported`|
+
+### `enums.ConfigurationKey`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|allow_offline_tx_for_unknown_id|str|`AllowOfflineTxForUnknownId`|
+|authorization_cache_enabled|str|`AuthorizationCacheEnabled`|
+|authorize_remote_tx_requests|str|`AuthorizeRemoteTxRequests`|
+|blink_repeat|str|`BlinkRepeat`|
+|clock_aligned_data_interval|str|`ClockAlignedDataInterval`|
+|connection_time_out|str|`ConnectionTimeOut`|
+|connector_phase_rotation|str|`ConnectorPhaseRotation`|
+|connector_phase_rotation_max_length|str|`ConnectorPhaseRotationMaxLength`|
+|get_configuration_max_keys|str|`GetConfigurationMaxKeys`|
+|heartbeat_interval|str|`HeartbeatInterval`|
+|light_intensity|str|`LightIntensity`|
+|local_authorize_offline|str|`LocalAuthorizeOffline`|
+|local_pre_authorize|str|`LocalPreAuthorize`|
+|max_energy_on_invalid_id|str|`MaxEnergyOnInvalidId`|
+|meter_values_aligned_data|str|`MeterValuesAlignedData`|
+|meter_values_aligned_data_max_length|str|`MeterValuesAlignedDataMaxLength`|
+|meter_values_sampled_data|str|`MeterValuesSampledData`|
+|meter_values_sampled_data_max_length|str|`MeterValuesSampledDataMaxLength`|
+|meter_value_sample_interval|str|`MeterValueSampleInterval`|
+|minimum_status_duration|str|`MinimumStatusDuration`|
+|number_of_connectors|str|`NumberOfConnectors`|
+|reset_retries|str|`ResetRetries`|
+|stop_transaction_on_ev_side_disconnect|str|`StopTransactionOnEVSideDisconnect`|
+|stop_transaction_on_invalid_id|str|`StopTransactionOnInvalidId`|
+|stop_txn_aligned_data|str|`StopTxnAlignedData`|
+|stop_txn_aligned_data_max_length|str|`StopTxnAlignedDataMaxLength`|
+|stop_txn_sampled_data|str|`StopTxnSampledData`|
+|stop_txn_sampled_data_max_length|str|`StopTxnSampledDataMaxLength`|
+|supported_feature_profiles|str|`SupportedFeatureProfiles`|
+|supported_feature_profiles_max_length|str|`SupportedFeatureProfilesMaxLength`|
+|transaction_message_attempts|str|`TransactionMessageAttempts`|
+|transaction_message_retry_interval|str|`TransactionMessageRetryInterval`|
+|unlock_connector_on_ev_side_disconnect|str|`UnlockConnectorOnEVSideDisconnect`|
+|web_socket_ping_interval|str|`WebSocketPingInterval`|
+|local_auth_list_enabled|str|`LocalAuthListEnabled`|
+|local_auth_list_max_length|str|`LocalAuthListMaxLength`|
+|send_local_list_max_length|str|`SendLocalListMaxLength`|
+|reserve_connector_zero_supported|str|`ReserveConnectorZeroSupported`|
+|charge_profile_max_stack_level|str|`ChargeProfileMaxStackLevel`|
+|charging_schedule_allowed_charging_rate_unit|str|`ChargingScheduleAllowedChargingRateUnit`|
+|charging_schedule_max_periods|str|`ChargingScheduleMaxPeriods`|
+|connector_switch_3to1_phase_supported|str|`ConnectorSwitch3to1PhaseSupported`|
+|max_charging_profiles_installed|str|`MaxChargingProfilesInstalled`|
+|central_contract_validation_allowed|str|`CentralContractValidationAllowed`|
+|certificate_signed_max_chain_size|str|`CertificateSignedMaxChainSize`|
+|cert_signing_wait_minimum|str|`CertSigningWaitMinimum`|
+|cert_signing_repeat_times|str|`CertSigningRepeatTimes`|
+|certificate_store_max_length|str|`CertificateStoreMaxLength`|
+|contract_validation_offline|str|`ContractValidationOffline`|
+|iso_15118_pnc_enabled|str|`ISO15118PnCEnabled`|
+|additional_root_certificate_check|str|`AdditionalRootCertificateCheck`|
+|authorization_key|str|`AuthorizationKey`|
+|cpo_name|str|`CpoName`|
+|security_profile|str|`SecurityProfile`|
+
+### `enums.DataTransferStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|unknown_message_id|str|`UnknownMessageId`|
+|unknown_vendor_id|str|`UnknownVendorId`|
+
+### `enums.DeleteCertificateStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|failed|str|`Failed`|
+|not_found|str|`NotFound`|
+
+### `enums.DiagnosticsStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|idle|str|`Idle`|
+|uploaded|str|`Uploaded`|
+|upload_failed|str|`UploadFailed`|
+|uploading|str|`Uploading`|
+
+### `enums.FirmwareStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|downloaded|str|`Downloaded`|
+|download_failed|str|`DownloadFailed`|
+|downloading|str|`Downloading`|
+|idle|str|`Idle`|
+|installation_failed|str|`InstallationFailed`|
+|installing|str|`Installing`|
+|installed|str|`Installed`|
+|download_scheduled|str|`DownloadScheduled`|
+|download_paused|str|`DownloadPaused`|
+|install_rebooting|str|`InstallRebooting`|
+|install_scheduled|str|`InstallScheduled`|
+|install_verification_failed|str|`InstallVerificationFailed`|
+|invalid_signature|str|`InvalidSignature`|
+|signature_verified|str|`SignatureVerified`|
+
+### `enums.GenericStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.GetCompositeScheduleStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.GetInstalledCertificateStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|not_found|str|`NotFound`|
+
+### `enums.HashAlgorithm`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|sha256|str|`SHA256`|
+|sha384|str|`SHA384`|
+|sha512|str|`SHA512`|
+
+### `enums.Location`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|inlet|str|`Inlet`|
+|outlet|str|`Outlet`|
+|body|str|`Body`|
+|cable|str|`Cable`|
+|ev|str|`EV`|
+
+### `enums.Log`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|diagnostics_log|str|`DiagnosticsLog`|
+|security_log|str|`SecurityLog`|
+
+### `enums.LogStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|accepted_canceled|str|`AcceptedCanceled`|
+
+### `enums.Measurand`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|current_export|str|`Current.Export`|
+|current_import|str|`Current.Import`|
+|current_offered|str|`Current.Offered`|
+|energy_active_export_register|str|`Energy.Active.Export.Register`|
+|energy_active_import_register|str|`Energy.Active.Import.Register`|
+|energy_reactive_export_register|str|`Energy.Reactive.Export.Register`|
+|energy_reactive_import_register|str|`Energy.Reactive.Import.Register`|
+|energy_active_export_interval|str|`Energy.Active.Export.Interval`|
+|energy_active_import_interval|str|`Energy.Active.Import.Interval`|
+|energy_reactive_export_interval|str|`Energy.Reactive.Export.Interval`|
+|energy_reactive_import_interval|str|`Energy.Reactive.Import.Interval`|
+|frequency|str|`Frequency`|
+|power_active_export|str|`Power.Active.Export`|
+|power_active_import|str|`Power.Active.Import`|
+|power_factor|str|`Power.Factor`|
+|power_offered|str|`Power.Offered`|
+|power_reactive_export|str|`Power.Reactive.Export`|
+|power_reactive_import|str|`Power.Reactive.Import`|
+|rpm|str|`RPM`|
+|soc|str|`SoC`|
+|temperature|str|`Temperature`|
+|voltage|str|`Voltage`|
+
+### `enums.MessageTrigger`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|boot_notification|str|`BootNotification`|
+|firmware_status_notification|str|`FirmwareStatusNotification`|
+|heartbeat|str|`Heartbeat`|
+|meter_values|str|`MeterValues`|
+|status_notification|str|`StatusNotification`|
+|diagnostics_status_notification|str|`DiagnosticsStatusNotification`|
+|log_status_notification|str|`LogStatusNotification`|
+|sign_charge_point_certificate|str|`SignChargePointCertificate`|
+
+### `enums.Phase`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|l1|str|`L1`|
+|l2|str|`L2`|
+|l3|str|`L3`|
+|n|str|`N`|
+|l1_n|str|`L1-N`|
+|l2_n|str|`L2-N`|
+|l3_n|str|`L3-N`|
+|l1_l2|str|`L1-L2`|
+|l2_l3|str|`L2-L3`|
+|l3_l1|str|`L3-L1`|
+
+### `enums.ReadingContext`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|interruption_begin|str|`Interruption.Begin`|
+|interruption_end|str|`Interruption.End`|
+|other|str|`Other`|
+|sample_clock|str|`Sample.Clock`|
+|sample_periodic|str|`Sample.Periodic`|
+|transaction_begin|str|`Transaction.Begin`|
+|transaction_end|str|`Transaction.End`|
+|trigger|str|`Trigger`|
+
+### `enums.Reason`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|emergency_stop|str|`EmergencyStop`|
+|ev_disconnected|str|`EVDisconnected`|
+|hard_reset|str|`HardReset`|
+|local|str|`Local`|
+|other|str|`Other`|
+|power_loss|str|`PowerLoss`|
+|reboot|str|`Reboot`|
+|remote|str|`Remote`|
+|soft_reset|str|`SoftReset`|
+|unlock_command|str|`UnlockCommand`|
+|de_authorized|str|`DeAuthorized`|
+
+### `enums.RecurrencyKind`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|daily|str|`Daily`|
+|weekly|str|`Weekly`|
+
+### `enums.RegistrationStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|pending|str|`Pending`|
+|rejected|str|`Rejected`|
+
+### `enums.RemoteStartStopStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.ReservationStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|faulted|str|`Faulted`|
+|occupied|str|`Occupied`|
+|rejected|str|`Rejected`|
+|unavailable|str|`Unavailable`|
+
+### `enums.ResetStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+
+### `enums.ResetType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|hard|str|`Hard`|
+|soft|str|`Soft`|
+
+### `enums.TriggerMessageStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|not_implemented|str|`NotImplemented`|
+
+### `enums.UnitOfMeasure`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|wh|str|`Wh`|
+|kwh|str|`kWh`|
+|varh|str|`varh`|
+|kvarh|str|`kvarh`|
+|w|str|`W`|
+|kw|str|`kW`|
+|va|str|`VA`|
+|kva|str|`kVA`|
+|var|str|`var`|
+|kvar|str|`kvar`|
+|a|str|`A`|
+|v|str|`V`|
+|celsius|str|`Celsius`|
+|fahrenheit|str|`Fahrenheit`|
+|k|str|`K`|
+|percent|str|`Percent`|
+|hertz|str|`Hertz`|
+
+### `enums.UnlockStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|unlocked|str|`Unlocked`|
+|unlock_failed|str|`UnlockFailed`|
+|not_supported|str|`NotSupported`|
+
+### `enums.UpdateFirmwareStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|rejected|str|`Rejected`|
+|accepted_canceled|str|`AcceptedCanceled`|
+|invalid_certificate|str|`InvalidCertificate`|
+|revoked_certificate|str|`RevokedCertificate`|
+
+### `enums.UploadLogStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|bad_message|str|`BadMessage`|
+|idle|str|`Idle`|
+|not_supported_operation|str|`NotSupportedOperation`|
+|permission_denied|str|`PermissionDenied`|
+|uploaded|str|`Uploaded`|
+|upload_failure|str|`UploadFailure`|
+|uploading|str|`Uploading`|
+
+### `enums.UpdateStatus`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|accepted|str|`Accepted`|
+|failed|str|`Failed`|
+|not_supported|str|`NotSupported`|
+|version_mismatch|str|`VersionMismatch`|
+
+### `enums.UpdateType`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|differential|str|`Differential`|
+|full|str|`Full`|
+
+### `enums.ValueFormat`
+
+|枚举值|数据类型|对应数值|
+|:---|:---|:---|
+|raw|str|`Raw`|
+|signed_data|str|`SignedData`|