anderes Errorhandling mit Claude implementiert.
This commit is contained in:
+102
-33
@@ -22,6 +22,58 @@ Dieses Programm:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorCollector:
|
||||||
|
"""Sammelt alle Fehler und Warnungen während der Verarbeitung."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.errors = {}
|
||||||
|
self.warnings = {}
|
||||||
|
|
||||||
|
def add_errors(self, error_dict):
|
||||||
|
"""Fügt Fehler aus einem Dictionary hinzu."""
|
||||||
|
for key, value in error_dict.items():
|
||||||
|
if key in self.errors:
|
||||||
|
if isinstance(self.errors[key], list) and isinstance(value, list):
|
||||||
|
self.errors[key].extend(value)
|
||||||
|
else:
|
||||||
|
self.errors[key] = [self.errors[key], value]
|
||||||
|
else:
|
||||||
|
self.errors[key] = value
|
||||||
|
|
||||||
|
def add_warnings(self, warning_dict):
|
||||||
|
"""Fügt Warnungen aus einem Dictionary hinzu."""
|
||||||
|
for key, value in warning_dict.items():
|
||||||
|
if key in self.warnings:
|
||||||
|
if isinstance(self.warnings[key], list) and isinstance(value, list):
|
||||||
|
self.warnings[key].extend(value)
|
||||||
|
else:
|
||||||
|
self.warnings[key] = [self.warnings[key], value]
|
||||||
|
else:
|
||||||
|
self.warnings[key] = value
|
||||||
|
|
||||||
|
def has_errors_or_warnings(self):
|
||||||
|
"""Prüft ob Fehler oder Warnungen vorhanden sind."""
|
||||||
|
return bool(self.errors) or bool(self.warnings)
|
||||||
|
|
||||||
|
def get_all_issues(self):
|
||||||
|
"""Gibt alle Fehler und Warnungen als Dictionary zurück."""
|
||||||
|
result = {}
|
||||||
|
if self.errors:
|
||||||
|
result["errors"] = self.errors
|
||||||
|
if self.warnings:
|
||||||
|
result["warnings"] = self.warnings
|
||||||
|
return result
|
||||||
|
|
||||||
|
def write_errorfile(self, work_dir: Path, filename: str):
|
||||||
|
"""Schreibt Fehlerdatei nur wenn Fehler oder Warnungen vorhanden sind."""
|
||||||
|
if self.has_errors_or_warnings():
|
||||||
|
print("Fehler oder Warnungen gefunden. Schreibe Error-Datei.")
|
||||||
|
all_issues = self.get_all_issues()
|
||||||
|
write_results(to_json(all_issues), work_dir, filename)
|
||||||
|
else:
|
||||||
|
print("Keine Fehler oder Warnungen gefunden. Keine Error-Datei geschrieben.")
|
||||||
|
|
||||||
|
|
||||||
def write_results(jsn_results: str, out_dir: Path, filename: str) -> None:
|
def write_results(jsn_results: str, out_dir: Path, filename: str) -> None:
|
||||||
"""Write results to a JSON file."""
|
"""Write results to a JSON file."""
|
||||||
print("writing results to a json file ...")
|
print("writing results to a json file ...")
|
||||||
@@ -225,7 +277,7 @@ class CompareBuffer:
|
|||||||
l.append(b)
|
l.append(b)
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def extract_input_positions(all_inserts, all_positions) -> tuple[dict, dict, dict, dict]:
|
def extract_input_positions(all_inserts, all_positions, error_collector: ErrorCollector = None) -> tuple[dict, dict]:
|
||||||
"""
|
"""
|
||||||
Extracts and organizes input positions from an iterable of inserts.
|
Extracts and organizes input positions from an iterable of inserts.
|
||||||
|
|
||||||
@@ -236,14 +288,14 @@ def extract_input_positions(all_inserts, all_positions) -> tuple[dict, dict, dic
|
|||||||
attributes and duplicate IDs for further error handling.
|
attributes and duplicate IDs for further error handling.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
insert_iterable: An iterable of insert objects to process.
|
all_inserts: List of insert objects to process.
|
||||||
|
all_positions: List of position objects corresponding to inserts.
|
||||||
|
error_collector: ErrorCollector instance to collect errors and warnings.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A tuple containing:
|
A tuple containing:
|
||||||
- all_sensors: dict of sensor IDs to sensor attribute dicts
|
- all_sensors: dict of sensor IDs to sensor attribute dicts
|
||||||
- all_schaltschrank: dict of Schaltschrankelement IDs to their attribute dicts
|
- all_schaltschrank: dict of Schaltschrankelement IDs to their attribute dicts
|
||||||
- double_ids: dict of IDs with multiple associated blocks (potential duplicates)
|
|
||||||
- missing_attribs: dict of IDs with missing or incomplete attributes
|
|
||||||
"""
|
"""
|
||||||
all_sensors = dict()
|
all_sensors = dict()
|
||||||
all_cables = dict()
|
all_cables = dict()
|
||||||
@@ -275,16 +327,16 @@ def extract_input_positions(all_inserts, all_positions) -> tuple[dict, dict, dic
|
|||||||
|
|
||||||
# spezialbehandlung der Sensoren, da diese in IO und A,B,C Blöcke geteilt sind
|
# spezialbehandlung der Sensoren, da diese in IO und A,B,C Blöcke geteilt sind
|
||||||
# Die Funktion sucht die übereinanderliegenen Elemente und baut ein Dict daraus
|
# Die Funktion sucht die übereinanderliegenen Elemente und baut ein Dict daraus
|
||||||
allocate_blocks_together(all_sensors, wp)
|
allocate_blocks_together(all_sensors, wp, error_collector)
|
||||||
|
|
||||||
set_single_frames_with_unique_sps(all_schaltschrank, wp)
|
set_single_frames_with_unique_sps(all_schaltschrank, wp)
|
||||||
|
|
||||||
# die noch übrigen Blöcke melden
|
# die noch übrigen Blöcke melden
|
||||||
missing_attribs, double_ids = get_errors_double_and_attributes(wp)
|
get_errors_double_and_attributes(wp, error_collector)
|
||||||
|
|
||||||
return all_sensors, all_schaltschrank, double_ids, missing_attribs
|
return all_sensors, all_schaltschrank
|
||||||
|
|
||||||
def get_errors_double_and_attributes(wp: CompareBuffer) -> tuple[dict, dict]:
|
def get_errors_double_and_attributes(wp: CompareBuffer, error_collector: ErrorCollector = None):
|
||||||
"""
|
"""
|
||||||
Analyze the CompareBuffer for blocks that could not be merged or assigned.
|
Analyze the CompareBuffer for blocks that could not be merged or assigned.
|
||||||
|
|
||||||
@@ -292,9 +344,9 @@ def get_errors_double_and_attributes(wp: CompareBuffer) -> tuple[dict, dict]:
|
|||||||
- IDs with only a single associated block, which likely indicates missing or incomplete attributes.
|
- IDs with only a single associated block, which likely indicates missing or incomplete attributes.
|
||||||
- IDs with multiple associated blocks, which may indicate duplicate or ambiguous entries.
|
- IDs with multiple associated blocks, which may indicate duplicate or ambiguous entries.
|
||||||
|
|
||||||
Returns:
|
Args:
|
||||||
missing_attribs: dict mapping IDs to a message about missing or incomplete attributes.
|
wp: CompareBuffer to analyze
|
||||||
double_ids: dict mapping IDs to a list of positions for blocks with duplicate IDs.
|
error_collector: ErrorCollector instance to collect errors and warnings
|
||||||
"""
|
"""
|
||||||
missing_attribs = dict()
|
missing_attribs = dict()
|
||||||
double_ids = dict()
|
double_ids = dict()
|
||||||
@@ -311,7 +363,13 @@ def get_errors_double_and_attributes(wp: CompareBuffer) -> tuple[dict, dict]:
|
|||||||
if id_ not in double_ids:
|
if id_ not in double_ids:
|
||||||
double_ids[id_] = []
|
double_ids[id_] = []
|
||||||
double_ids[id_].append(block['pos'])
|
double_ids[id_].append(block['pos'])
|
||||||
return missing_attribs, double_ids
|
|
||||||
|
# Füge Fehler und Warnungen zum ErrorCollector hinzu, falls vorhanden
|
||||||
|
if error_collector:
|
||||||
|
if double_ids:
|
||||||
|
error_collector.add_errors({"double_ids": double_ids})
|
||||||
|
if missing_attribs:
|
||||||
|
error_collector.add_warnings({"missing_attributes": missing_attribs})
|
||||||
|
|
||||||
def set_single_frames_with_unique_sps(all_sensors: dict, wp: CompareBuffer):
|
def set_single_frames_with_unique_sps(all_sensors: dict, wp: CompareBuffer):
|
||||||
all_sensors_ids = wp.get_block_ids()
|
all_sensors_ids = wp.get_block_ids()
|
||||||
@@ -327,7 +385,7 @@ def set_single_frames_with_unique_sps(all_sensors: dict, wp: CompareBuffer):
|
|||||||
all_sensors[new_id] = block_with_sps
|
all_sensors[new_id] = block_with_sps
|
||||||
wp.remove_block(id_, block_with_sps)
|
wp.remove_block(id_, block_with_sps)
|
||||||
|
|
||||||
def allocate_blocks_together(all_sensors: dict, wp: CompareBuffer) -> None:
|
def allocate_blocks_together(all_sensors: dict, wp: CompareBuffer, error_collector: ErrorCollector = None) -> None:
|
||||||
"""
|
"""
|
||||||
Merge sensor blocks with the same ID that are split across multiple DXF blocks.
|
Merge sensor blocks with the same ID that are split across multiple DXF blocks.
|
||||||
|
|
||||||
@@ -352,19 +410,21 @@ def allocate_blocks_together(all_sensors: dict, wp: CompareBuffer) -> None:
|
|||||||
for block_without_sps in blks_other:
|
for block_without_sps in blks_other:
|
||||||
# Vergleiche alle Blöcke mit SPS und denen ohne auf die gleiche Position
|
# Vergleiche alle Blöcke mit SPS und denen ohne auf die gleiche Position
|
||||||
if wp.positions_are_close(block_with_sps, block_without_sps, 1000):
|
if wp.positions_are_close(block_with_sps, block_without_sps, 1000):
|
||||||
new_id = create_new_id(id_, block_with_sps, block_without_sps) # hier das Präfix davor
|
new_id = create_new_id(id_, block_with_sps, block_without_sps, error_collector) # hier das Präfix davor
|
||||||
all_sensors[new_id] = merge_two_dicts(block_without_sps, block_with_sps) #Kombiniert alle infos aus dxf und "pos"
|
all_sensors[new_id] = merge_two_dicts(block_without_sps, block_with_sps) #Kombiniert alle infos aus dxf und "pos"
|
||||||
wp.remove_block(id_, block_with_sps)
|
wp.remove_block(id_, block_with_sps)
|
||||||
wp.remove_block(id_, block_without_sps)
|
wp.remove_block(id_, block_without_sps)
|
||||||
|
|
||||||
def create_new_id(id_: str, dict1: dict, dict2: dict) -> str:
|
def create_new_id(id_: str, dict1: dict, dict2: dict, error_collector: ErrorCollector = None) -> str:
|
||||||
sps_praefix = None
|
sps_praefix = None
|
||||||
if "SPS" in dict1:
|
if "SPS" in dict1:
|
||||||
sps_praefix = dict1["SPS"]
|
sps_praefix = dict1["SPS"]
|
||||||
if "SPS" in dict2:
|
if "SPS" in dict2:
|
||||||
sps_praefix = dict2["SPS"]
|
sps_praefix = dict2["SPS"]
|
||||||
if not sps_praefix:
|
if not sps_praefix:
|
||||||
raise Exception
|
if error_collector:
|
||||||
|
error_collector.add_errors({"missing_sps_prefix": {id_: "SPS Präfix fehlt für Block-ID"}})
|
||||||
|
return f"{id_}@UNKNOWN" # Fallback für fehlenden SPS-Präfix
|
||||||
return f"{id_}@{sps_praefix}"
|
return f"{id_}@{sps_praefix}"
|
||||||
|
|
||||||
def attribs_to_dicts(insert_iterable) -> tuple[list, list]:
|
def attribs_to_dicts(insert_iterable) -> tuple[list, list]:
|
||||||
@@ -514,7 +574,7 @@ def get_subdistributor_positions_from_symbols(all_inserts:list, all_positions:li
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if res in dist2sensors:
|
if res in dist2sensors:
|
||||||
ret[id_] = ld["pos"]
|
ret[res] = ld["pos"]
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -877,19 +937,17 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
output_results = dict()
|
output_results = dict()
|
||||||
|
|
||||||
|
# ErrorCollector für alle Fehler und Warnungen initialisieren
|
||||||
|
error_collector = ErrorCollector()
|
||||||
|
|
||||||
if args.sensors:
|
if args.sensors:
|
||||||
# Sensoren auslesen aus den Symbolen
|
# Sensoren auslesen aus den Symbolen
|
||||||
|
|
||||||
if use_iter:
|
if use_iter:
|
||||||
all_inserts, all_positions = attribs_to_dicts(iterdxf.modelspace(dxf_path))
|
all_inserts, all_positions = attribs_to_dicts(iterdxf.modelspace(dxf_path))
|
||||||
else:
|
else:
|
||||||
all_inserts, all_positions = attribs_to_dicts(msp)
|
all_inserts, all_positions = attribs_to_dicts(msp)
|
||||||
res_sens, res_schaltschrank_elemente, res_double, missing_attribs = extract_input_positions(all_inserts, all_positions)
|
res_sens, res_schaltschrank_elemente = extract_input_positions(all_inserts, all_positions, error_collector)
|
||||||
|
|
||||||
if args.errors and len(res_double) > 0:
|
|
||||||
print("Duplicate blocks found. Writing errors-file.")
|
|
||||||
err_ids = list(res_double.keys())
|
|
||||||
write_results(to_json(list(err_ids)), work_dir, args.errors)
|
|
||||||
|
|
||||||
|
|
||||||
output_results['sensors'] = res_sens
|
output_results['sensors'] = res_sens
|
||||||
output_results['schaltschrank_elemente'] = res_schaltschrank_elemente
|
output_results['schaltschrank_elemente'] = res_schaltschrank_elemente
|
||||||
@@ -901,6 +959,9 @@ if __name__ == '__main__':
|
|||||||
# Mapping zu Sensoren auslesen
|
# Mapping zu Sensoren auslesen
|
||||||
(res_mappings, warnings) = create_mappings(res_sens)
|
(res_mappings, warnings) = create_mappings(res_sens)
|
||||||
output_results['mappings'] = res_mappings
|
output_results['mappings'] = res_mappings
|
||||||
|
# Mapping-Warnungen zum ErrorCollector hinzufügen
|
||||||
|
if warnings:
|
||||||
|
error_collector.add_warnings({"mapping_warnings": warnings})
|
||||||
if args.console:
|
if args.console:
|
||||||
print(to_json(res_mappings))
|
print(to_json(res_mappings))
|
||||||
|
|
||||||
@@ -946,16 +1007,24 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
if args.write:
|
if args.write:
|
||||||
basename = os.path.splitext(args.write)[0]
|
basename = os.path.splitext(args.write)[0]
|
||||||
res_not_found = check_existance(res_mappings, res_dist, res_sens, res_tunnel)
|
|
||||||
if args.errors and "overdefined_tunnel" in res_not_found:
|
|
||||||
print("unorrect tunnels found. Writing errors-file.")
|
|
||||||
err_ids = list(res_not_found["overdefined_tunnel"])
|
|
||||||
write_results(to_json(list(err_ids)), work_dir, args.errors)
|
|
||||||
|
|
||||||
added_warnings = merge_two_dicts(warnings, missing_attribs)
|
res_not_found = check_existance(res_mappings, res_dist, res_sens, res_tunnel)
|
||||||
res_not_found["missing_attributes"] = added_warnings
|
|
||||||
output_results["not_found"] = res_not_found
|
# Alle weiteren Fehler zum ErrorCollector hinzufügen
|
||||||
output_results["double_ids"] = res_double
|
error_collector.add_errors(res_not_found)
|
||||||
|
|
||||||
|
# ErrorCollector schreibt Datei nur wenn Fehler/Warnungen vorhanden
|
||||||
|
if args.errors:
|
||||||
|
error_collector.write_errorfile(work_dir, args.errors)
|
||||||
|
|
||||||
|
# Für Kompatibilität mit Ausgabe-JSON: Fehler und Warnungen aus ErrorCollector holen
|
||||||
|
all_issues = error_collector.get_all_issues()
|
||||||
|
if "errors" in all_issues:
|
||||||
|
output_results["not_found"] = all_issues["errors"].get("not_found", {})
|
||||||
|
if "double_ids" in all_issues["errors"]:
|
||||||
|
output_results["double_ids"] = all_issues["errors"]["double_ids"]
|
||||||
|
if "missing_attributes" in all_issues.get("warnings", {}):
|
||||||
|
output_results["not_found"]["missing_attributes"] = all_issues["warnings"]["missing_attributes"]
|
||||||
|
|
||||||
|
|
||||||
write_results(to_json(output_results), work_dir, f"{basename}.json")
|
write_results(to_json(output_results), work_dir, f"{basename}.json")
|
||||||
|
|||||||
Reference in New Issue
Block a user