gpt4 book ai didi

python - 转义序列中断 pyserial 客户端

转载 作者:行者123 更新时间:2023-11-28 21:43:49 25 4
gpt4 key购买 nike

我正在使用 pyserial 为网络设备编写客户端,它在登录设备后和在设备上收到提示之前挂起几秒钟。跟踪线上的字节,我看到以下转义序列是造成延迟的原因:

0003a0  73 65 20 6c 65 76 65 6c  0d 0a 0d 1b 5b 39 39 39       |se level....[999|
0003b0 39 42 0d 1b 5b 39 39 39 39 42 1b 5a 20 20 1b 5b |9B..[9999B.Z .[|
0003c0 36 6e 0d 0d 0d 0d 5b 61 64 6d 69 6e 40 73 77 69 |6n....[admin@swi|
0003d0 74 63 68 5d 20 3e 20 20 20 20 20 20 20 20 20 20 |tch] > |

当使用 screen 连接到设备时,不会出现延迟,因为 screen 正在正确响应。

0003a0  73 65 20 6c 65 76 65 6c  0d 0a 0d 1b 5b 39 39 39       |se level....[999|
0003b0 39 42 0d 1b 5b 39 39 39 39 42 1b 5a 20 |9B..[9999B.Z |

---=== WRITE ===---
000000 1b 5b 3f 31 3b 32 63 |.[?1;2c |

---=== READ ===---
000000 20 1b 5b 36 6e | .[6n |

---=== WRITE ===---
000000 1b 5b 35 37 3b 33 52 |.[57;3R |

---=== READ ===---
000000 1b 5b 34 6c 1b 5b 32 30 6c 1b 5b 3f 34 37 6c 1b |.[4l.[20l.[?47l.|
000010 5b 3f 37 68 1b 5b 3f 35 6c 1b 5b 3f 32 35 68 1b |[?7h.[?5l.[?25h.|
000020 5b 48 1b 5b 39 39 39 39 42 1b 5b 36 6e |[H.[9999B.[6n |

---=== WRITE ===---
000000 1b 5b 35 37 3b 31 52 |.[57;1R |

---=== READ ===---
000000 1b 5b 48 1b 5b 39 39 39 39 42 1b 44 1b 5b 39 39 |.[H.[9999B.D.[99|
000010 39 39 41 1b 5b 36 6e |99A.[6n |

---=== WRITE ===---
000000 1b 5b 31 3b 31 52 |.[1;1R |

---=== READ ===---
000000 1b 5b 48 1b 5b 39 39 39 39 43 1b 5b 36 6e |.[H.[9999C.[6n |

---=== WRITE ===---
000000 1b 5b 31 3b 31 34 31 52 |.[1;141R |

---=== READ ===---
000000 1b 5b 48 c4 9b 48 1b 5b 36 6e 0d 20 20 20 |.[H..H.[6n. |

---=== WRITE ===---
000000 1b 5b 31 3b 33 52 |.[1;3R |

---=== READ ===---
000000 1b 5b 48 1b 5b 39 39 39 39 43 1b 5b 36 6e 20 1b |.[H.[9999C.[6n .|

---=== WRITE ===---
000000 1b 5b 31 3b 31 34 31 52 |.[1;141R |

---=== READ ===---
000000 5b 36 6e 20 1b 5b 36 6e |[6n .[6n |

---=== WRITE ===---
000000 1b 5b 31 3b 31 34 32 52 1b 5b 32 3b 32 52 |.[1;142R.[2;2R |

---=== READ ===---
000000 1b 5b 33 3b 35 72 1b 5b 48 1b 5b 36 6e 0a 0a |.[3;5r.[H.[6n.. |
---=== WRITE ===---
000000 1b 5b 31 3b 31 52 |.[1;1R |

---=== READ ===---
000000 0a 0a 0a 0a 0a 1b 5b 36 6e 1b 5b |......[6n.[ |

---=== WRITE ===---
000000 1b 5b 35 3b 31 52 |.[5;1R |

---=== READ ===---
000000 39 39 39 39 42 1b 5b 36 6e 1b 5b 72 |9999B.[6n.[r |

---=== WRITE ===---
000000 1b 5b 35 3b 31 52 |.[5;1R |

---=== READ ===---
000000 1b 5b 31 3b 39 39 39 39 72 0d 0d 0d 1b 5b 39 39 |.[1;9999r....[99|
000010 39 39 42 5b 61 64 6d 69 6e 40 73 77 69 74 63 68 |99B[admin@switch|
000020 5d 20 3e 20 |] > |

这一系列转义序列到底在做什么,在我的客户端中处理这个问题的最佳方法是什么?

from asyncio import Protocol, get_event_loop
from serial.aio import create_serial_connection

class Serial(Protocol):

def connection_made(self, transport):
self.transport = transport

def data_received(self, data):
self.buffer += data.decode("utf-8")
self.handle()

def send(self, line):
self.transport.write("{}\r\n".format(line).encode())

loop = get_event_loop()
coro = create_serial_connection(loop, Serial, "/dev/ttyUSB0")
loop.run_until_complete(coro)
loop.run_forever()

最佳答案

带有 [6n(及其前面的转义字符)的 block 要求终端告诉它光标在哪里,作为确定屏幕大小的一部分。显然 pyserial 不理解这一点,您必须等待一段时间,让执行请求的程序放弃并继续。

XTerm Control Sequences :

CSI Ps n  Device Status Report (DSR).
...
Ps = 6 -> Report Cursor Position (CPR) [row;column].

其中 CSI 是控制序列发起者 escape[.

当你运行 screen 时,它 interprets这个控制序列(即,它阅读理解适本地回复):

        case 'n':            if (a1 == 5)    /* Report terminal status */                Report(win, "\033[0n", 0, 0);            else if (a1 == 6)   /* Report cursor position */                Report(win, "\033[%d;%dR", win->w_y + 1, win->w_x + 1);

The status report control sequence is used by a few programs such as resize to determine the size of your terminal's screen. It works by moving the cursor to an impossibly far lower-right-corner, and then (because terminals have limits) asking how far it got. This particular example is not using resize, which sends 999 for each coordinate (but it's debatable whether there's a real scenario where four digits are needed).

The application that is sending the device status control sequence moves the cursor down with the escape[9999B, and apparently uses that later when setting up scrolling margins with the sequence ending with r. This is a frequently-used VT100 feature not in ECMA-48 (the r denotes a private use sequence, i.e., not standardized).

If you give it a bogus value for the cursor position, you might get poor results.

It also tries with two different control sequences to move the cursor to the home (upper-left) in this sequence from the screen read/writes:

1b 5b 48 c4 9b 48

(0x9b0x1b0x5bescape 的 8 位等价物/kbd>[).

所以你的选择很少:

  • 消除(可能不必要的)屏幕尺寸查询,或者
  • 修改您的 pyserial 脚本以处理设备状态控制序列

关于python - 转义序列中断 pyserial 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41708420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com