Support ASTM framing for GeneXpert responses

This commit is contained in:
Dwi Swandhana
2026-04-16 17:56:50 +07:00
parent b7195cc629
commit f301de8cb5
+35 -16
View File
@@ -439,15 +439,13 @@ def create_genexpert_rsp_z02_response(orders, incoming_hl7, ip_addr=None):
return "\r".join(segments) + "\r"
def send_all_orders(conn, ip_addr, hl7_msg, msg_id):
def send_all_orders(conn, ip_addr, hl7_msg, msg_id, response_framing="mllp"):
orders = get_genexpert_query_orders(ip_addr, hl7_msg)
scheduled_orders = []
if not orders:
print(f"[GENEXPERT] Tidak ada order pending untuk {ip_addr}")
rsp = create_genexpert_rsp_z02_response([], hl7_msg, ip_addr=ip_addr)
log_genexpert_hl7("OUT", ip_addr, rsp, label="qbp-empty")
log_genexpert_hl7_full("OUT", ip_addr, rsp, label="qbp-empty")
conn.sendall(f"\x0b{rsp}\x1c\r".encode('utf-8'))
send_genexpert_response(conn, ip_addr, rsp, response_framing, label="qbp-empty")
return
qpd_segment = extract_segment(hl7_msg, "QPD")
@@ -457,11 +455,8 @@ def send_all_orders(conn, ip_addr, hl7_msg, msg_id):
)
print(f"[GENEXPERT] Mengirim {len(orders)} order ke {ip_addr}")
rsp = create_genexpert_rsp_z02_response(orders, hl7_msg, ip_addr=ip_addr)
mllp = f"\x0b{rsp}\x1c\r"
first_accnumber = str(orders[0].rnoreg or "").strip() if orders else ""
log_genexpert_hl7("OUT", ip_addr, rsp, label=f"qbp-order:{first_accnumber}")
log_genexpert_hl7_full("OUT", ip_addr, rsp, label=f"qbp-order:{first_accnumber}")
conn.sendall(mllp.encode('utf-8'))
send_genexpert_response(conn, ip_addr, rsp, response_framing, label=f"qbp-order:{first_accnumber}")
for order in orders:
print(f"[GENEXPERT] Order ditawarkan ke {ip_addr}: {order.rnoreg}")
@@ -530,6 +525,34 @@ def log_genexpert_hl7_full(direction, ip_addr, hl7_message, label=""):
f"[GENEXPERT-HL7-{direction}-FULL] ip={ip_addr}, type={message_type}, control_id={control_id}{suffix}, payload={payload}"
)
def detect_genexpert_message_framing(message_bytes):
raw = message_bytes or b""
if b"\x1c" in raw or raw.startswith(b"\x0b"):
return "mllp"
if b"\x03" in raw:
return "astm"
return "plain"
def frame_genexpert_response(hl7_message, framing):
message = str(hl7_message or "")
if framing == "astm":
frame_body = f"{message}\x03"
chk = calculate_astm_checksum(frame_body)
return f"\x02{frame_body}{chk}\r\n".encode("latin-1")
if framing == "mllp":
return f"\x0b{message}\x1c\r".encode("utf-8")
return message.encode("utf-8")
def send_genexpert_response(conn, ip_addr, hl7_message, framing, label=""):
log_genexpert_hl7("OUT", ip_addr, hl7_message, label=label)
log_genexpert_hl7_full("OUT", ip_addr, hl7_message, label=label)
payload = frame_genexpert_response(hl7_message, framing)
print(
f"[GENEXPERT-DEBUG] Send response ip={ip_addr}, framing={framing}, "
f"label={label}, bytes={len(payload)}"
)
conn.sendall(payload)
def build_genexpert_result_query(accnumber, msg_control_id):
ts = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
# Query hasil berbasis accession number di QRD-8.
@@ -2004,6 +2027,7 @@ def handle_genexpert_client(conn, addr):
if end_marker_pos == -1: end_marker_pos = len(buffer)
full_message_bytes = buffer[:end_marker_pos]
response_framing = detect_genexpert_message_framing(full_message_bytes)
# Sisa buffer (jika ada paket nempel di belakangnya) disimpan untuk loop berikutnya
buffer = buffer[end_marker_pos:]
@@ -2045,10 +2069,7 @@ def handle_genexpert_client(conn, addr):
# 2. Kirim ACK (Terima Kasih)
ack_msg = create_genexpert_ack_r01_response(clean_hl7)
full_ack = f"\x0b{ack_msg}\x1c\r"
log_genexpert_hl7("OUT", addr[0], ack_msg, label="oru-ack")
log_genexpert_hl7_full("OUT", addr[0], ack_msg, label="oru-ack")
conn.sendall(full_ack.encode('utf-8'))
send_genexpert_response(conn, addr[0], ack_msg, response_framing, label="oru-ack")
print(f"[ACK SENT] Untuk hasil ID {incoming_control_id}")
continue
@@ -2058,15 +2079,13 @@ def handle_genexpert_client(conn, addr):
elif "QBP^Z01" in clean_hl7 or "QBP^Z03" in clean_hl7:
print("[GENEXPERT] Alat meminta ORDER")
msg_id = extract_msg_control_id(clean_hl7)
send_all_orders(conn, addr[0], clean_hl7, msg_id)
send_all_orders(conn, addr[0], clean_hl7, msg_id, response_framing=response_framing)
continue
elif "QCN^J01" in clean_hl7:
clear_genexpert_inflight_for_ip(addr[0], reason="query-confirmation")
ack_msg = create_genexpert_ack_j01_response(clean_hl7)
log_genexpert_hl7("OUT", addr[0], ack_msg, label="qcn-ack")
log_genexpert_hl7_full("OUT", addr[0], ack_msg, label="qcn-ack")
conn.sendall(f"\x0b{ack_msg}\x1c\r".encode('utf-8'))
send_genexpert_response(conn, addr[0], ack_msg, response_framing, label="qcn-ack")
print(f"[GENEXPERT] Menerima konfirmasi query dari {addr[0]}.")
continue