Support ASTM framing for GeneXpert responses
This commit is contained in:
+35
-16
@@ -439,15 +439,13 @@ def create_genexpert_rsp_z02_response(orders, incoming_hl7, ip_addr=None):
|
|||||||
|
|
||||||
return "\r".join(segments) + "\r"
|
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)
|
orders = get_genexpert_query_orders(ip_addr, hl7_msg)
|
||||||
scheduled_orders = []
|
scheduled_orders = []
|
||||||
if not orders:
|
if not orders:
|
||||||
print(f"[GENEXPERT] Tidak ada order pending untuk {ip_addr}")
|
print(f"[GENEXPERT] Tidak ada order pending untuk {ip_addr}")
|
||||||
rsp = create_genexpert_rsp_z02_response([], hl7_msg, ip_addr=ip_addr)
|
rsp = create_genexpert_rsp_z02_response([], hl7_msg, ip_addr=ip_addr)
|
||||||
log_genexpert_hl7("OUT", ip_addr, rsp, label="qbp-empty")
|
send_genexpert_response(conn, ip_addr, rsp, response_framing, label="qbp-empty")
|
||||||
log_genexpert_hl7_full("OUT", ip_addr, rsp, label="qbp-empty")
|
|
||||||
conn.sendall(f"\x0b{rsp}\x1c\r".encode('utf-8'))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
qpd_segment = extract_segment(hl7_msg, "QPD")
|
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}")
|
print(f"[GENEXPERT] Mengirim {len(orders)} order ke {ip_addr}")
|
||||||
rsp = create_genexpert_rsp_z02_response(orders, hl7_msg, ip_addr=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 ""
|
first_accnumber = str(orders[0].rnoreg or "").strip() if orders else ""
|
||||||
log_genexpert_hl7("OUT", ip_addr, rsp, label=f"qbp-order:{first_accnumber}")
|
send_genexpert_response(conn, ip_addr, rsp, response_framing, 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'))
|
|
||||||
|
|
||||||
for order in orders:
|
for order in orders:
|
||||||
print(f"[GENEXPERT] Order ditawarkan ke {ip_addr}: {order.rnoreg}")
|
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}"
|
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):
|
def build_genexpert_result_query(accnumber, msg_control_id):
|
||||||
ts = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
ts = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||||
# Query hasil berbasis accession number di QRD-8.
|
# 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)
|
if end_marker_pos == -1: end_marker_pos = len(buffer)
|
||||||
|
|
||||||
full_message_bytes = buffer[:end_marker_pos]
|
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
|
# Sisa buffer (jika ada paket nempel di belakangnya) disimpan untuk loop berikutnya
|
||||||
buffer = buffer[end_marker_pos:]
|
buffer = buffer[end_marker_pos:]
|
||||||
@@ -2045,10 +2069,7 @@ def handle_genexpert_client(conn, addr):
|
|||||||
|
|
||||||
# 2. Kirim ACK (Terima Kasih)
|
# 2. Kirim ACK (Terima Kasih)
|
||||||
ack_msg = create_genexpert_ack_r01_response(clean_hl7)
|
ack_msg = create_genexpert_ack_r01_response(clean_hl7)
|
||||||
full_ack = f"\x0b{ack_msg}\x1c\r"
|
send_genexpert_response(conn, addr[0], ack_msg, response_framing, label="oru-ack")
|
||||||
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'))
|
|
||||||
print(f"[ACK SENT] Untuk hasil ID {incoming_control_id}")
|
print(f"[ACK SENT] Untuk hasil ID {incoming_control_id}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -2058,15 +2079,13 @@ def handle_genexpert_client(conn, addr):
|
|||||||
elif "QBP^Z01" in clean_hl7 or "QBP^Z03" in clean_hl7:
|
elif "QBP^Z01" in clean_hl7 or "QBP^Z03" in clean_hl7:
|
||||||
print("[GENEXPERT] Alat meminta ORDER")
|
print("[GENEXPERT] Alat meminta ORDER")
|
||||||
msg_id = extract_msg_control_id(clean_hl7)
|
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
|
continue
|
||||||
|
|
||||||
elif "QCN^J01" in clean_hl7:
|
elif "QCN^J01" in clean_hl7:
|
||||||
clear_genexpert_inflight_for_ip(addr[0], reason="query-confirmation")
|
clear_genexpert_inflight_for_ip(addr[0], reason="query-confirmation")
|
||||||
ack_msg = create_genexpert_ack_j01_response(clean_hl7)
|
ack_msg = create_genexpert_ack_j01_response(clean_hl7)
|
||||||
log_genexpert_hl7("OUT", addr[0], ack_msg, label="qcn-ack")
|
send_genexpert_response(conn, addr[0], ack_msg, response_framing, 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'))
|
|
||||||
print(f"[GENEXPERT] Menerima konfirmasi query dari {addr[0]}.")
|
print(f"[GENEXPERT] Menerima konfirmasi query dari {addr[0]}.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user