시리즈: ocpp
python
119 줄
· 업데이트 2025-10-10
schema_to_enums_v201.py
ocpp/homework/ocpp_many/scripts/schema_to_enums_v201.py
#!/usr/bin/env python
import json
import re
import sys
from pathlib import Path
enum_types = []
enum_types_names = []
def create_attribute(name):
"""
Gets an attribute name from the enum and convert it to snake_case
"""
# Removes any hyphens or dots from the name, substituting by an underscore
name_normalized = re.sub("[.]", "", name)
name_normalized = re.sub("[-]", "_", name_normalized)
# The following substitution will add an underscore between
# any character and a word starting with a capital letter, followed by
# a lowercase letters. For example:
# 1) "EVConnected" -> EV_Connected
# 2) "SuspendedEVSE" -> SuspendedEVSE
# 3) "CSMSRootCertificate" -> CSMS_RootCertificate
# For names with numbers within, this conversion does not work so well
# 4) "Other1PhMax16A" -> Other1_PhMax16A
name_normalized = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name_normalized)
# This one will add an underscore between a word ending with non-capital
# letter and one starting with a capital. It will also lowercase it.
# For example:
# 1) "EV_Connected" -> ev_connected
# 2) "SuspendedEVSE" -> suspended_evse
# 3) "CSMS_RootCertificate" -> csms_root_certificate
# 4) "Other1_PhMax16A" -> other1_ph_max16a (ideally should be
# other_1ph_max_16a or similar.
name_converted = re.sub("([a-z])([A-Z])", r"\1_\2", name_normalized).lower()
return Attribute(name, name_converted)
class NormalClass:
def __init__(self, name):
self.name = name
self.attrs = []
def add_attr(self, attr):
self.attrs.append(attr)
def __str__(self):
output = f"class {self.name}(str, Enum):\n"
if len(self.attrs) == 0:
return output + " pass\n"
for attr in self.attrs:
output += str(attr)
return output
class Attribute:
def __init__(self, name, name_converted):
self.name = name
self.name_converted = name_converted
def __str__(self):
name = self.name
if not re.match("^[a-zA-Z_]", self.name):
name = "_" + self.name
# The 4 spaces after the start of the string is to guarantee the proper
# indentation
return f' {self.name_converted} = "{name}"\n'
def __repr__(self):
return f"<{self.name}, {self.name_converted}> "
def parse_schema(schema):
with open(schema, "r") as f:
schema = json.loads(f.read())
try:
definitions = schema["definitions"]
except KeyError:
print("Error: No definitions field found on the schema")
return
for enum_type, value in definitions.items():
if "Enum" in enum_type:
type_name = enum_type.replace("Enum", "")
if type_name not in enum_types_names:
nc = NormalClass(type_name)
for enum_attr in value["enum"]:
attr = create_attribute(enum_attr)
nc.add_attr(attr)
enum_types.append(nc)
enum_types_names.append(nc.name)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Pass path to folder with schemas")
sys.exit(-1)
# The second argument of argv is the path for the schemas
p = Path(sys.argv[1])
schemas = list(p.glob("*.json"))
# This loop will update the lists enum_types and enum_types_names:
# The former contains the enum objects that are later parsed to the
# enum.py, using the str representation. And the latter, is used to keep
# track of the already processed Enums, avoiding data duplication
for schema in schemas:
parse_schema(schema)
with open("enums.py", "wb+") as f:
f.write(b"from enum import Enum\n")
for enum_type_ in sorted(enum_types, key=lambda enum_type: enum_type.name):
f.write(b"\n\n")
f.write(str(enum_type_).encode("utf-8"))
관련 글
ocpp
python
업데이트 2026-02-03
central_system.py
central_system.py — python source code from the ocpp learning materials (ocpp/homework/central_system.py).
글 읽기 →
ocpp
python
업데이트 2026-02-03
charge_point.py
charge_point.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/charge_point.py).
글 읽기 →
ocpp
python
업데이트 2026-02-03
exceptions.py
exceptions.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/exceptions.py).
글 읽기 →
ocpp
python
업데이트 2026-02-03
messages.py
messages.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/messages.py).
글 읽기 →
ocpp
python
업데이트 2026-02-03
routing.py
routing.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/routing.py).
글 읽기 →
ocpp
python
업데이트 2026-02-03
__init__.py
__init__.py — python source code from the ocpp learning materials (ocpp/homework/ocpp/v16/__init__.py).
글 읽기 →