|
|
|
|
@ -1,3 +1,4 @@
|
|
|
|
|
import json
|
|
|
|
|
import os
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
import uuid
|
|
|
|
|
@ -559,6 +560,26 @@ def _payload_terminal_uuid_set(device):
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _terminal_signature_token(element_uuid, terminal_uuid):
|
|
|
|
|
return "{0}|{1}".format((element_uuid or "").strip(), (terminal_uuid or "").strip())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _payload_terminal_signature_counts(device):
|
|
|
|
|
result = {}
|
|
|
|
|
if not isinstance(device, dict):
|
|
|
|
|
return result
|
|
|
|
|
for terminal in device.get("terminals", []) or []:
|
|
|
|
|
if not isinstance(terminal, dict):
|
|
|
|
|
continue
|
|
|
|
|
terminal_uuid = (terminal.get("terminal_uuid") or "").strip()
|
|
|
|
|
element_uuid = (terminal.get("element_uuid") or "").strip()
|
|
|
|
|
if not terminal_uuid:
|
|
|
|
|
continue
|
|
|
|
|
token = _terminal_signature_token(element_uuid, terminal_uuid)
|
|
|
|
|
result[token] = result.get(token, 0) + 1
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _existing_qet_terminal_uuids(device_group):
|
|
|
|
|
terminal_group = TerminalObjects.find_child_group_by_kind(
|
|
|
|
|
device_group,
|
|
|
|
|
@ -573,6 +594,64 @@ def _existing_qet_terminal_uuids(device_group):
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _existing_qet_terminal_signature_counts(device_group):
|
|
|
|
|
raw_json = (getattr(device_group, "QetPayloadTerminalSignaturesJson", "") or "").strip()
|
|
|
|
|
if raw_json:
|
|
|
|
|
try:
|
|
|
|
|
parsed = json.loads(raw_json)
|
|
|
|
|
if isinstance(parsed, dict):
|
|
|
|
|
result = {}
|
|
|
|
|
for key, value in parsed.items():
|
|
|
|
|
key_text = str(key or "").strip()
|
|
|
|
|
if not key_text:
|
|
|
|
|
continue
|
|
|
|
|
try:
|
|
|
|
|
count_value = int(value)
|
|
|
|
|
except Exception:
|
|
|
|
|
count_value = 0
|
|
|
|
|
if count_value > 0:
|
|
|
|
|
result[key_text] = count_value
|
|
|
|
|
if result:
|
|
|
|
|
return result
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
terminal_group = TerminalObjects.find_child_group_by_kind(
|
|
|
|
|
device_group,
|
|
|
|
|
TerminalObjects.TERMINAL_GROUP_KIND,
|
|
|
|
|
)
|
|
|
|
|
result = {}
|
|
|
|
|
for terminal_obj in TerminalObjects.collect_terminal_objects(terminal_group):
|
|
|
|
|
terminal_uuid = (getattr(terminal_obj, "QetTerminalUuid", "") or "").strip()
|
|
|
|
|
element_uuid = (getattr(terminal_obj, "QetElementUuid", "") or "").strip()
|
|
|
|
|
if not terminal_uuid or TerminalObjects.is_local_terminal_uuid(terminal_uuid):
|
|
|
|
|
continue
|
|
|
|
|
token = _terminal_signature_token(element_uuid, terminal_uuid)
|
|
|
|
|
result[token] = result.get(token, 0) + 1
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _store_device_payload_terminal_signatures(device_group, signature_counts):
|
|
|
|
|
normalized = {}
|
|
|
|
|
for key, value in (signature_counts or {}).items():
|
|
|
|
|
key_text = str(key or "").strip()
|
|
|
|
|
if not key_text:
|
|
|
|
|
continue
|
|
|
|
|
try:
|
|
|
|
|
count_value = int(value)
|
|
|
|
|
except Exception:
|
|
|
|
|
count_value = 0
|
|
|
|
|
if count_value > 0:
|
|
|
|
|
normalized[key_text] = count_value
|
|
|
|
|
_ensure_string_property(
|
|
|
|
|
device_group,
|
|
|
|
|
"QetPayloadTerminalSignaturesJson",
|
|
|
|
|
"QET Exchange",
|
|
|
|
|
"Serialized terminal-entry signatures from the last QET payload",
|
|
|
|
|
json.dumps(normalized, ensure_ascii=False, sort_keys=True),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _device_change_detail(
|
|
|
|
|
display_tag,
|
|
|
|
|
instance_id,
|
|
|
|
|
@ -580,6 +659,8 @@ def _device_change_detail(
|
|
|
|
|
change_types=None,
|
|
|
|
|
added_terminal_uuids=None,
|
|
|
|
|
removed_terminal_uuids=None,
|
|
|
|
|
previous_terminal_entry_count=0,
|
|
|
|
|
current_terminal_entry_count=0,
|
|
|
|
|
previous_display_tag="",
|
|
|
|
|
previous_model_path="",
|
|
|
|
|
resolved_model_path="",
|
|
|
|
|
@ -592,6 +673,8 @@ def _device_change_detail(
|
|
|
|
|
"change_types": list(change_types or []),
|
|
|
|
|
"added_terminal_uuids": list(added_terminal_uuids or []),
|
|
|
|
|
"removed_terminal_uuids": list(removed_terminal_uuids or []),
|
|
|
|
|
"previous_terminal_entry_count": int(previous_terminal_entry_count or 0),
|
|
|
|
|
"current_terminal_entry_count": int(current_terminal_entry_count or 0),
|
|
|
|
|
"previous_display_tag": (previous_display_tag or "").strip(),
|
|
|
|
|
"previous_model_path": (previous_model_path or "").strip(),
|
|
|
|
|
"resolved_model_path": (resolved_model_path or "").strip(),
|
|
|
|
|
@ -1365,12 +1448,16 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
element_uuid = _payload_device_element_uuid(device)
|
|
|
|
|
display_tag = (device.get("display_tag") or "").strip()
|
|
|
|
|
payload_terminal_uuids = _payload_terminal_uuid_set(device)
|
|
|
|
|
payload_terminal_signature_counts = _payload_terminal_signature_counts(device)
|
|
|
|
|
payload_terminal_entry_count = sum(payload_terminal_signature_counts.values())
|
|
|
|
|
existing_device_group = _find_device_group_by_instance_id(doc, instance_id)
|
|
|
|
|
if existing_device_group is None:
|
|
|
|
|
existing_device_group = _find_device_group(doc, element_uuid)
|
|
|
|
|
previous_display_tag = ""
|
|
|
|
|
previous_path = ""
|
|
|
|
|
existing_terminal_uuids = set()
|
|
|
|
|
existing_terminal_signature_counts = {}
|
|
|
|
|
existing_terminal_entry_count = 0
|
|
|
|
|
existing_model_objects = []
|
|
|
|
|
if existing_device_group is not None:
|
|
|
|
|
previous_display_tag = getattr(
|
|
|
|
|
@ -1386,6 +1473,12 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
existing_terminal_uuids = _existing_qet_terminal_uuids(
|
|
|
|
|
existing_device_group
|
|
|
|
|
)
|
|
|
|
|
existing_terminal_signature_counts = _existing_qet_terminal_signature_counts(
|
|
|
|
|
existing_device_group
|
|
|
|
|
)
|
|
|
|
|
existing_terminal_entry_count = sum(
|
|
|
|
|
existing_terminal_signature_counts.values()
|
|
|
|
|
)
|
|
|
|
|
existing_model_objects = _existing_model_objects(
|
|
|
|
|
doc, existing_device_group
|
|
|
|
|
)
|
|
|
|
|
@ -1404,6 +1497,10 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
existing_device_group is not None
|
|
|
|
|
and previous_display_tag != display_tag
|
|
|
|
|
)
|
|
|
|
|
terminals_changed = bool(
|
|
|
|
|
existing_device_group is not None
|
|
|
|
|
and payload_terminal_signature_counts != existing_terminal_signature_counts
|
|
|
|
|
)
|
|
|
|
|
if existing_device_group is not None:
|
|
|
|
|
_update_device_group_metadata(
|
|
|
|
|
existing_device_group,
|
|
|
|
|
@ -1413,14 +1510,44 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
previous_path,
|
|
|
|
|
display_tag,
|
|
|
|
|
)
|
|
|
|
|
_store_device_payload_terminal_signatures(
|
|
|
|
|
existing_device_group,
|
|
|
|
|
payload_terminal_signature_counts,
|
|
|
|
|
)
|
|
|
|
|
if display_tag_changed:
|
|
|
|
|
change_types = ["标注"]
|
|
|
|
|
if terminals_changed:
|
|
|
|
|
change_types.append("端子")
|
|
|
|
|
report["updated_devices"] += 1
|
|
|
|
|
report["updated_device_details"].append(
|
|
|
|
|
_device_change_detail(
|
|
|
|
|
display_tag,
|
|
|
|
|
(instance_id or getattr(existing_device_group, "QetInstanceId", "")).strip(),
|
|
|
|
|
element_uuid=element_uuid,
|
|
|
|
|
change_types=change_types,
|
|
|
|
|
previous_terminal_entry_count=existing_terminal_entry_count,
|
|
|
|
|
current_terminal_entry_count=payload_terminal_entry_count,
|
|
|
|
|
previous_display_tag=previous_display_tag,
|
|
|
|
|
previous_model_path=previous_path,
|
|
|
|
|
resolved_model_path=previous_path,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
elif terminals_changed:
|
|
|
|
|
report["updated_devices"] += 1
|
|
|
|
|
report["updated_device_details"].append(
|
|
|
|
|
_device_change_detail(
|
|
|
|
|
display_tag,
|
|
|
|
|
(instance_id or getattr(existing_device_group, "QetInstanceId", "")).strip(),
|
|
|
|
|
element_uuid=element_uuid,
|
|
|
|
|
change_types=["标注"],
|
|
|
|
|
change_types=["端子"],
|
|
|
|
|
added_terminal_uuids=sorted(
|
|
|
|
|
payload_terminal_uuids - existing_terminal_uuids
|
|
|
|
|
),
|
|
|
|
|
removed_terminal_uuids=sorted(
|
|
|
|
|
existing_terminal_uuids - payload_terminal_uuids
|
|
|
|
|
),
|
|
|
|
|
previous_terminal_entry_count=existing_terminal_entry_count,
|
|
|
|
|
current_terminal_entry_count=payload_terminal_entry_count,
|
|
|
|
|
previous_display_tag=previous_display_tag,
|
|
|
|
|
previous_model_path=previous_path,
|
|
|
|
|
resolved_model_path=previous_path,
|
|
|
|
|
@ -1481,7 +1608,9 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
existing_terminal_uuids - payload_terminal_uuids
|
|
|
|
|
)
|
|
|
|
|
terminals_changed = bool(
|
|
|
|
|
added_terminal_uuids or removed_terminal_uuids
|
|
|
|
|
added_terminal_uuids
|
|
|
|
|
or removed_terminal_uuids
|
|
|
|
|
or payload_terminal_signature_counts != existing_terminal_signature_counts
|
|
|
|
|
)
|
|
|
|
|
display_tag_changed = (
|
|
|
|
|
not created_now and previous_display_tag != display_tag
|
|
|
|
|
@ -1506,6 +1635,8 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
change_types=change_types,
|
|
|
|
|
added_terminal_uuids=added_terminal_uuids,
|
|
|
|
|
removed_terminal_uuids=removed_terminal_uuids,
|
|
|
|
|
previous_terminal_entry_count=existing_terminal_entry_count,
|
|
|
|
|
current_terminal_entry_count=payload_terminal_entry_count,
|
|
|
|
|
previous_display_tag=previous_display_tag,
|
|
|
|
|
previous_model_path=previous_path,
|
|
|
|
|
resolved_model_path=resolved_model_path,
|
|
|
|
|
@ -1519,6 +1650,10 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
len(removed_terminal_uuids),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
_store_device_payload_terminal_signatures(
|
|
|
|
|
device_group,
|
|
|
|
|
payload_terminal_signature_counts,
|
|
|
|
|
)
|
|
|
|
|
continue
|
|
|
|
|
report["reused_devices"] += 1
|
|
|
|
|
report["reused_device_details"].append(
|
|
|
|
|
@ -1526,6 +1661,8 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
display_tag,
|
|
|
|
|
instance_id,
|
|
|
|
|
element_uuid=element_uuid,
|
|
|
|
|
previous_terminal_entry_count=existing_terminal_entry_count,
|
|
|
|
|
current_terminal_entry_count=payload_terminal_entry_count,
|
|
|
|
|
previous_display_tag=previous_display_tag,
|
|
|
|
|
previous_model_path=previous_path,
|
|
|
|
|
resolved_model_path=resolved_model_path,
|
|
|
|
|
@ -1538,6 +1675,10 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
len(existing_model_objects),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
_store_device_payload_terminal_signatures(
|
|
|
|
|
device_group,
|
|
|
|
|
payload_terminal_signature_counts,
|
|
|
|
|
)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
if created_now or not existing_model_objects:
|
|
|
|
|
@ -1592,6 +1733,8 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
display_tag,
|
|
|
|
|
instance_id,
|
|
|
|
|
element_uuid=element_uuid,
|
|
|
|
|
previous_terminal_entry_count=existing_terminal_entry_count,
|
|
|
|
|
current_terminal_entry_count=payload_terminal_entry_count,
|
|
|
|
|
previous_display_tag=previous_display_tag,
|
|
|
|
|
previous_model_path=previous_path,
|
|
|
|
|
resolved_model_path=resolved_model_path,
|
|
|
|
|
@ -1616,12 +1759,19 @@ def import_devices_from_payload(payload, scene_path=""):
|
|
|
|
|
change_types=change_types,
|
|
|
|
|
added_terminal_uuids=added_terminal_uuids,
|
|
|
|
|
removed_terminal_uuids=removed_terminal_uuids,
|
|
|
|
|
previous_terminal_entry_count=existing_terminal_entry_count,
|
|
|
|
|
current_terminal_entry_count=payload_terminal_entry_count,
|
|
|
|
|
previous_display_tag=previous_display_tag,
|
|
|
|
|
previous_model_path=previous_path,
|
|
|
|
|
resolved_model_path=resolved_model_path,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
_store_device_payload_terminal_signatures(
|
|
|
|
|
device_group,
|
|
|
|
|
payload_terminal_signature_counts,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if not original_instance_id:
|
|
|
|
|
report["imported_without_instance_id"] += 1
|
|
|
|
|
finally:
|
|
|
|
|
|