fix: get_tyy_data方法调整

This commit is contained in:
shijing 2026-06-03 10:50:57 +08:00
parent beddfe98ba
commit b21c48b90c
2 changed files with 51 additions and 12 deletions

View File

@ -271,23 +271,41 @@ def get_svs_char(host, port, flow_unit=0, timeout=10):
"""连接 SVS维视智造 VisionBank用 VTFP 触发拍照并取回识别字符。 """连接 SVS维视智造 VisionBank用 VTFP 触发拍照并取回识别字符。
返回 ``{"char": 识别字符, "fields": [...], "raw": 原始应答行}`` 返回 ``{"char": 识别字符, "fields": [...], "raw": 原始应答行}``
不同流程的输出配置可能不一样有的回 ``VTFP 0 <数据>`` 完整应答有的只回
用户自定义的识别内容( ``1``)这里读到第一行完整数据就返回 ``VTFP``
前缀的按协议解析否则整行当作识别内容
""" """
cmd = f"VTFP {flow_unit}\r\n".encode("ascii") cmd = f"VTFP {flow_unit}\r".encode("ascii") # 该设备只认单 CR 结尾, 带 \n 会无响应
try: try:
with socket.create_connection((host, int(port)), timeout=timeout) as sc: with socket.create_connection((host, int(port)), timeout=timeout) as sc:
sc.sendall(cmd)
buf = bytearray() buf = bytearray()
while True: sc.sendall(cmd)
chunk = sc.recv(1024) # 第一次用完整超时等设备响应; 设备返回的识别内容(如 b'1')末尾可能没有
if not chunk: # 换行符, 因此拿到数据后只用很短的超时把剩余字节收干净(兼容多位数分包),
break # 不再死等换行, 否则会卡到超时
chunk = sc.recv(1024)
if chunk:
buf.extend(chunk) buf.extend(chunk)
text = buf.decode("utf-8", errors="replace") sc.settimeout(0.3)
# VTFP 应答前可能先收到 VGIF 等行,定位到 VTFP 那一行再解析 while b"\n" not in buf and b"\r" not in buf:
for ln in text.split("\r\n"): try:
if ln.startswith("VTFP"): more = sc.recv(1024)
char, fields = _parse_vtfp_line(ln) except socket.timeout:
return {"char": char, "fields": fields, "raw": ln} break
if not more:
break
buf.extend(more)
text = buf.decode("utf-8", errors="replace")
for ln in re.split(r"[\r\n]+", text):
ln = ln.strip()
if not ln:
continue
if ln.upper().startswith("VTFP"):
char, fields = _parse_vtfp_line(ln)
return {"char": char, "fields": fields, "raw": ln}
# 无 VTFP 前缀,设备直接回识别内容
return {"char": ln, "fields": ln.split(), "raw": ln}
except ParseError: except ParseError:
raise raise
except (socket.timeout, ConnectionError, OSError) as e: except (socket.timeout, ConnectionError, OSError) as e:

View File

@ -14,6 +14,7 @@ from rest_framework.decorators import action
from rest_framework.serializers import Serializer from rest_framework.serializers import Serializer
from django.db import transaction from django.db import transaction
from apps.em.services import daoru_equipment from apps.em.services import daoru_equipment
from apps.em import cd
from rest_framework.response import Response from rest_framework.response import Response
from django.conf import settings from django.conf import settings
from django.db.models import Count, Case, When, IntegerField from django.db.models import Count, Case, When, IntegerField
@ -127,6 +128,26 @@ class EquipmentViewSet(CustomModelViewSet):
return Response(json_result) return Response(json_result)
@swagger_auto_schema(
manual_parameters=[
openapi.Parameter(name="host", in_=openapi.IN_QUERY, description="SVS IP", type=openapi.TYPE_STRING, required=True),
openapi.Parameter(name="port", in_=openapi.IN_QUERY, description="SVS 端口", type=openapi.TYPE_STRING, required=True),
openapi.Parameter(name="flow_unit", in_=openapi.IN_QUERY, description="识别码(流程单元号), 多台 SVS 共用 IP 时用于区分设备", type=openapi.TYPE_STRING, required=True),
]
)
@action(methods=["get"], detail=False, perms_map={"get": "*"})
def get_svs_char(self, request, *args, **kwargs):
"""获取 SVS 识别字符
触发 SVS 拍照并取回识别字符, flow_unit 为识别码用于区分共用 IP 的不同设备
"""
host = request.query_params.get("host", None)
port = request.query_params.get("port", None)
if not host or not port:
raise ParseError("请传入host和port参数")
flow_unit = request.query_params.get("flow_unit", 0)
return Response(cd.get_svs_char(host, port, flow_unit))
class EcheckRecordViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet): class EcheckRecordViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, CustomGenericViewSet):
""" """