fix: get_tyy_data方法调整
This commit is contained in:
parent
beddfe98ba
commit
b21c48b90c
|
|
@ -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)
|
||||||
|
# 第一次用完整超时等设备响应; 设备返回的识别内容(如 b'1')末尾可能没有
|
||||||
|
# 换行符, 因此拿到数据后只用很短的超时把剩余字节收干净(兼容多位数分包),
|
||||||
|
# 不再死等换行, 否则会卡到超时
|
||||||
chunk = sc.recv(1024)
|
chunk = sc.recv(1024)
|
||||||
if not chunk:
|
if chunk:
|
||||||
break
|
|
||||||
buf.extend(chunk)
|
buf.extend(chunk)
|
||||||
|
sc.settimeout(0.3)
|
||||||
|
while b"\n" not in buf and b"\r" not in buf:
|
||||||
|
try:
|
||||||
|
more = sc.recv(1024)
|
||||||
|
except socket.timeout:
|
||||||
|
break
|
||||||
|
if not more:
|
||||||
|
break
|
||||||
|
buf.extend(more)
|
||||||
text = buf.decode("utf-8", errors="replace")
|
text = buf.decode("utf-8", errors="replace")
|
||||||
# VTFP 应答前可能先收到 VGIF 等行,定位到 VTFP 那一行再解析
|
for ln in re.split(r"[\r\n]+", text):
|
||||||
for ln in text.split("\r\n"):
|
ln = ln.strip()
|
||||||
if ln.startswith("VTFP"):
|
if not ln:
|
||||||
|
continue
|
||||||
|
if ln.upper().startswith("VTFP"):
|
||||||
char, fields = _parse_vtfp_line(ln)
|
char, fields = _parse_vtfp_line(ln)
|
||||||
return {"char": char, "fields": fields, "raw": 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:
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue