增加日志功能,增加打包成exe功能,点击exe就可以使用

This commit is contained in:
2026-03-03 14:07:54 +08:00
parent 9f54a0cb2e
commit b47962e5c8
23 changed files with 172395 additions and 65 deletions

View File

@@ -43,21 +43,42 @@ python remo_disp_server.py [装置IP]
python remo_disp_server.py 192.168.253.3
```
## 打包为 exeWindows
在项目目录下执行:
```bash
# 安装 PyInstaller 后打包
pip install pyinstaller
python -m PyInstaller remo_disp_server.spec --noconfirm
```
或直接双击运行 `build_exe.bat`
打包完成后可执行文件为 **dist\\remo_disp_server.exe**。双击运行,或在命令行:
```bash
dist\remo_disp_server.exe
dist\remo_disp_server.exe 192.168.253.3
```
运行后浏览器访问 http://localhost:8181。日志会输出到控制台同目录下会生成 `remo_disp.log`
## 项目结构
```
DTU-RemoteLCD/
├── remo_disp_server.py # Web 服务Flask + Socket.IO
├── remo_disp_server.spec # PyInstaller 打包配置
├── build_exe.bat # 一键打包脚本Windows
├── remo_disp_ui.html # Web 前端页面
├── requirements.txt # Python 依赖
├── requirements.txt # Python 依赖
├── static/ # 静态资源(可选)
│ └── favicon.ico # 网站图标
│ └── favicon.ico # 网站图标
└── README.md
```
## 协议说明RemoDispBus
`HMI/RemoeDisp/RemoDispBus.c` 兼容:
## 协议说明
| 项目 | 说明 |
|------|------|
@@ -96,6 +117,15 @@ DTU-RemoteLCD/
| flask-socketio | WebSocket 支持 |
| python-socketio | Socket.IO 服务端 |
| Pillow | 1bpp 位图转 PNG |
| loguru | 结构化日志、错误追踪 |
## 日志与调试
- 后端使用 `loguru` 输出日志,默认会打印到控制台,并写入当前目录下的 `remo_disp.log`
-`remo_disp_server.py` 顶部有 `LOG_LEVEL` 常量:
- `LOG_LEVEL = "INFO"`:只输出 INFO/WARNING/ERROR 级别日志(默认)。
- `LOG_LEVEL = "DEBUG"`:输出包括 DEBUG 在内的详细调试信息。
- exe 版本(`remo_disp_server.exe`)同样会在运行目录生成 `remo_disp.log`,方便线下排查问题。
## 配置说明

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,373 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean these modules are required for running your program. Both
Python's standard library and 3rd-party Python packages often conditionally
import optional modules, some of which may be available only on certain
platforms.
Types of import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named 'org.python' - imported by copy (optional), xml.sax (delayed, conditional)
missing module named org - imported by pickle (optional)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
missing module named pep517 - imported by importlib.metadata (delayed)
missing module named urllib.quote - imported by urllib (delayed), py._path.svnwc (delayed)
missing module named urllib.unquote_plus - imported by urllib (optional), lxml.html.clean (optional)
missing module named urllib.urlencode - imported by urllib (delayed, optional), lxml.html (delayed, optional)
missing module named urllib.FancyURLopener - imported by urllib (conditional, optional), pygments.lexers._sourcemod_builtins (conditional, optional)
missing module named urllib.urlretrieve - imported by urllib (conditional, optional), pygments.lexers._php_builtins (conditional, optional)
missing module named urllib.urlopen - imported by urllib (conditional, optional), pygments.lexers._lua_builtins (conditional, optional), pygments.lexers._postgres_builtins (conditional, optional), lxml.html (delayed, optional)
missing module named urllib.quote_plus - imported by urllib (conditional), docutils.utils.math.math2html (conditional)
missing module named urllib.url2pathname - imported by urllib (conditional), docutils.parsers.rst.directives.images (conditional), docutils.writers._html_base (conditional), docutils.writers.latex2e (conditional)
missing module named pwd - imported by posixpath (delayed, conditional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), distutils.util (delayed, conditional, optional), distutils.archive_util (optional), netrc (delayed, conditional), getpass (delayed), http.server (delayed, optional), webbrowser (delayed), psutil (optional), docutils.frontend (delayed, conditional, optional), setuptools._distutils.util (delayed, conditional, optional), setuptools._distutils.archive_util (optional), py._path.local (delayed), twisted.python.util (optional)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), distutils.archive_util (optional), setuptools._distutils.archive_util (optional), py._path.local (delayed), twisted.python.util (optional)
missing module named posix - imported by shutil (conditional), importlib._bootstrap_external (conditional), os (conditional, optional)
missing module named resource - imported by posix (top-level), ptyprocess.ptyprocess (top-level), IPython.utils.timing (optional), twisted.internet.process (delayed, optional)
missing module named pyimod02_importers - imported by C:\Users\16241\AppData\Roaming\Python\Python310\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed), C:\Users\16241\AppData\Roaming\Python\Python310\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgres.py (delayed)
missing module named _posixsubprocess - imported by subprocess (optional), multiprocessing.util (delayed)
missing module named fcntl - imported by subprocess (optional), zmq.eventloop.minitornado.platform.posix (top-level), paramiko.agent (delayed), pty (delayed, optional), ptyprocess.ptyprocess (top-level), psutil._compat (delayed, optional), xmlrpc.server (optional), sphinx.util.console (delayed, optional), atomicwrites (optional), twisted.python.compat (delayed, optional), twisted.internet.fdesc (optional), twisted.internet.process (optional)
missing module named _manylinux - imported by packaging._manylinux (delayed, optional), setuptools._vendor.packaging._manylinux (delayed, optional), pkg_resources._vendor.packaging._manylinux (delayed, optional)
missing module named jinja2.contextfunction - imported by jinja2 (optional), sphinx.jinja2glue (optional)
missing module named jinja2.environmentfilter - imported by jinja2 (optional), sphinx.util.rst (optional)
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level), loguru._logger (top-level)
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
missing module named termios - imported by getpass (optional), tty (top-level), ptyprocess.ptyprocess (top-level), psutil._compat (delayed, optional), IPython.core.page (delayed, optional), prompt_toolkit.input.vt100 (top-level), sphinx.util.console (delayed, optional), click._termui_impl (conditional), werkzeug._reloader (delayed, optional), twisted.internet.process (optional)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named 'java.lang' - imported by platform (delayed, optional), xml.sax._exceptions (conditional)
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
missing module named multiprocessing.freeze_support - imported by multiprocessing (top-level), black (top-level)
missing module named multiprocessing.Manager - imported by multiprocessing (top-level), black (top-level)
missing module named multiprocessing.Process - imported by multiprocessing (top-level), jupyter_client.ssh.tunnel (top-level)
missing module named multiprocessing.current_process - imported by multiprocessing (top-level), loguru._logger (top-level)
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
missing module named railroad - imported by pyparsing.diagram (top-level), pkg_resources._vendor.pyparsing.diagram (top-level), setuptools._vendor.pyparsing.diagram (top-level)
missing module named readline - imported by site (delayed, optional), rlcompleter (optional), cmd (delayed, conditional, optional), code (delayed, conditional, optional), pdb (delayed, optional), pstats (conditional, optional), dill.source (delayed, conditional, optional), flask.cli (delayed, conditional, optional), sphinx.cmd.quickstart (optional)
missing module named 'pkg_resources.extern.pyparsing' - imported by pkg_resources._vendor.packaging.markers (top-level), pkg_resources._vendor.packaging.requirements (top-level)
missing module named 'pkg_resources.extern.importlib_resources' - imported by pkg_resources._vendor.jaraco.text (optional)
missing module named 'typing.io' - imported by importlib.resources (top-level)
missing module named 'pkg_resources.extern.more_itertools' - imported by pkg_resources._vendor.jaraco.functools (top-level)
missing module named 'com.sun' - imported by pkg_resources._vendor.appdirs (delayed, conditional, optional)
missing module named com - imported by pkg_resources._vendor.appdirs (delayed)
missing module named _winreg - imported by platform (delayed, optional), pkg_resources._vendor.appdirs (delayed, conditional), pygments.formatters.img (optional)
missing module named pkg_resources.extern.packaging - imported by pkg_resources.extern (top-level), pkg_resources (top-level)
missing module named pkg_resources.extern.appdirs - imported by pkg_resources.extern (top-level), pkg_resources (top-level)
missing module named 'pkg_resources.extern.jaraco' - imported by pkg_resources (top-level), pkg_resources._vendor.jaraco.text (top-level)
missing module named vms_lib - imported by platform (delayed, optional)
missing module named java - imported by platform (delayed)
missing module named 'distutils._log' - imported by setuptools._distutils.command.bdist_dumb (top-level), setuptools._distutils.command.bdist_rpm (top-level), setuptools._distutils.command.build_clib (top-level), setuptools._distutils.command.build_ext (top-level), setuptools._distutils.command.build_py (top-level), setuptools._distutils.command.build_scripts (top-level), setuptools._distutils.command.clean (top-level), setuptools._distutils.command.config (top-level), setuptools._distutils.command.install (top-level), setuptools._distutils.command.install_scripts (top-level), setuptools._distutils.command.register (top-level), setuptools._distutils.command.sdist (top-level)
missing module named usercustomize - imported by site (delayed, optional)
missing module named sitecustomize - imported by site (delayed, optional)
missing module named 'setuptools.extern.pyparsing' - imported by setuptools._vendor.packaging.requirements (top-level), setuptools._vendor.packaging.markers (top-level)
missing module named collections.Sequence - imported by collections (optional), jsonpointer (optional), setuptools._vendor.ordered_set (optional)
missing module named collections.MutableSet - imported by collections (optional), setuptools._vendor.ordered_set (optional), lxml.html (optional), lxml.html._setmixin (optional)
missing module named 'setuptools.extern.jaraco' - imported by setuptools._reqs (top-level), setuptools._entry_points (top-level), setuptools.command.egg_info (top-level), setuptools._vendor.jaraco.text (top-level)
missing module named setuptools.extern.importlib_resources - imported by setuptools.extern (conditional), setuptools._importlib (conditional), setuptools._vendor.jaraco.text (optional)
missing module named setuptools.extern.tomli - imported by setuptools.extern (delayed), setuptools.config.pyprojecttoml (delayed)
missing module named setuptools.extern.importlib_metadata - imported by setuptools.extern (conditional), setuptools._importlib (conditional)
missing module named setuptools.extern.ordered_set - imported by setuptools.extern (top-level), setuptools.dist (top-level)
missing module named setuptools.extern.packaging - imported by setuptools.extern (top-level), setuptools.dist (top-level), setuptools.command.egg_info (top-level), setuptools.depends (top-level)
missing module named 'setuptools.extern.more_itertools' - imported by setuptools.dist (top-level), setuptools.config.expand (delayed), setuptools._itertools (top-level), setuptools._entry_points (top-level), setuptools.msvc (top-level), setuptools._vendor.jaraco.functools (top-level)
missing module named 'setuptools.extern.packaging.version' - imported by setuptools.config.setupcfg (top-level), setuptools.msvc (top-level)
missing module named 'setuptools.extern.packaging.utils' - imported by setuptools.wheel (top-level)
missing module named 'setuptools.extern.packaging.tags' - imported by setuptools.wheel (top-level)
missing module named trove_classifiers - imported by setuptools.config._validate_pyproject.formats (optional)
missing module named 'setuptools.extern.packaging.specifiers' - imported by setuptools.config.setupcfg (top-level), setuptools.config._apply_pyprojecttoml (delayed)
missing module named 'setuptools.extern.packaging.requirements' - imported by setuptools.config.setupcfg (top-level)
missing module named '_typeshed.wsgi' - imported by werkzeug._internal (conditional), werkzeug.exceptions (conditional), werkzeug.http (conditional), werkzeug.wsgi (conditional), werkzeug.utils (conditional), werkzeug.wrappers.response (conditional), werkzeug.test (conditional), werkzeug.formparser (conditional), werkzeug.wrappers.request (conditional), werkzeug.serving (conditional), werkzeug.debug (conditional), werkzeug.middleware.shared_data (conditional), werkzeug.local (conditional), werkzeug.routing.exceptions (conditional), werkzeug.routing.map (conditional), flask.typing (conditional)
missing module named _watchdog_fsevents - imported by watchdog.observers.fsevents (top-level)
missing module named StringIO - imported by six (conditional), urllib3.packages.six (conditional), docutils.writers.docutils_xml (conditional), docutils.writers.odf_odt (conditional)
missing module named cryptography.x509.UnsupportedExtension - imported by cryptography.x509 (optional), urllib3.contrib.pyopenssl (optional)
missing module named _curses - imported by curses (top-level), curses.has_key (top-level)
missing module named aiohttp - imported by engineio.async_client (optional)
missing module named wsaccel - imported by websocket._utils (optional)
missing module named 'backports.ssl_match_hostname' - imported by websocket._ssl_compat (conditional, optional)
missing module named collections.Callable - imported by collections (optional), cffi.api (optional), socks (optional), bs4.element (optional), bs4.builder._lxml (optional)
missing module named 'six.moves.urllib.parse' - imported by websocket._url (top-level)
missing module named httplib - imported by websocket._handshake (conditional)
missing module named Cookie - imported by websocket._cookiejar (optional)
missing module named 'wsaccel.xormask' - imported by websocket._abnf (conditional, optional)
missing module named dummy_threading - imported by psutil._compat (optional), requests.cookies (optional)
missing module named _dummy_thread - imported by cffi.lock (conditional, optional), numpy.core.arrayprint (optional)
missing module named numpy.core.result_type - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.float_ - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.number - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.object_ - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (delayed)
missing module named numpy.core.all - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (delayed)
missing module named numpy.core.bool_ - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.inf - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.array2string - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.signbit - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.isscalar - imported by numpy.core (delayed), numpy.testing._private.utils (delayed), numpy.lib.polynomial (top-level)
missing module named numpy.core.isinf - imported by numpy.core (delayed), numpy.testing._private.utils (delayed)
missing module named numpy.core.errstate - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (delayed)
missing module named numpy.core.isfinite - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (delayed)
missing module named numpy.core.isnan - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (delayed)
missing module named numpy.core.array - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (top-level), numpy.lib.polynomial (top-level)
missing module named numpy.core.isnat - imported by numpy.core (top-level), numpy.testing._private.utils (top-level)
missing module named numpy.core.ndarray - imported by numpy.core (top-level), numpy.testing._private.utils (top-level), numpy.lib.utils (top-level)
missing module named numpy.core.array_repr - imported by numpy.core (top-level), numpy.testing._private.utils (top-level)
missing module named numpy.core.arange - imported by numpy.core (top-level), numpy.testing._private.utils (top-level), numpy.fft.helper (top-level)
missing module named numpy.core.empty - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (top-level), numpy.fft.helper (top-level)
missing module named numpy.core.float32 - imported by numpy.core (top-level), numpy.testing._private.utils (top-level)
missing module named numpy.core.intp - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.testing._private.utils (top-level)
missing module named numpy.core.linspace - imported by numpy.core (top-level), numpy.lib.index_tricks (top-level)
missing module named numpy.core.iinfo - imported by numpy.core (top-level), numpy.lib.twodim_base (top-level)
missing module named numpy.core.transpose - imported by numpy.core (top-level), numpy.lib.function_base (top-level)
missing module named numpy._typing._ufunc - imported by numpy._typing (conditional)
missing module named numpy.uint - imported by numpy (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.core.asarray - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.lib.utils (top-level), numpy.fft._pocketfft (top-level), numpy.fft.helper (top-level)
missing module named numpy.core.integer - imported by numpy.core (top-level), numpy.fft.helper (top-level)
missing module named numpy.core.sqrt - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.fft._pocketfft (top-level)
missing module named numpy.core.conjugate - imported by numpy.core (top-level), numpy.fft._pocketfft (top-level)
missing module named numpy.core.swapaxes - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.fft._pocketfft (top-level)
missing module named numpy.core.zeros - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.fft._pocketfft (top-level)
missing module named numpy.core.reciprocal - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.sort - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.argsort - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.sign - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.count_nonzero - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.divide - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.matmul - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.asanyarray - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.atleast_2d - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.product - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.amax - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.amin - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.moveaxis - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.geterrobj - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.finfo - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.lib.polynomial (top-level)
missing module named numpy.core.sum - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.fastCopyAndTranspose - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.multiply - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.add - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.dot - imported by numpy.core (top-level), numpy.linalg.linalg (top-level), numpy.lib.polynomial (top-level)
missing module named numpy.core.Inf - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.newaxis - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.complexfloating - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.inexact - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.cdouble - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.csingle - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.double - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.single - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.intc - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.empty_like - imported by numpy.core (top-level), numpy.linalg.linalg (top-level)
missing module named numpy.core.ufunc - imported by numpy.core (top-level), numpy.lib.utils (top-level)
missing module named numpy.core.ones - imported by numpy.core (top-level), numpy.lib.polynomial (top-level)
missing module named numpy.core.hstack - imported by numpy.core (top-level), numpy.lib.polynomial (top-level)
missing module named numpy.core.atleast_1d - imported by numpy.core (top-level), numpy.lib.polynomial (top-level)
missing module named numpy.core.atleast_3d - imported by numpy.core (top-level), numpy.lib.shape_base (top-level)
missing module named numpy.core.vstack - imported by numpy.core (top-level), numpy.lib.shape_base (top-level)
missing module named pickle5 - imported by numpy.compat.py3k (optional), cloudpickle.compat (conditional, optional)
missing module named numpy.eye - imported by numpy (delayed), numpy.core.numeric (delayed)
missing module named numpy.recarray - imported by numpy (top-level), numpy.ma.mrecords (top-level)
missing module named numpy.expand_dims - imported by numpy (top-level), numpy.ma.core (top-level)
missing module named numpy.array - imported by numpy (top-level), numpy.ma.core (top-level), numpy.ma.extras (top-level), numpy.ma.mrecords (top-level), dill._objects (optional)
missing module named numpy.iscomplexobj - imported by numpy (top-level), numpy.ma.core (top-level)
missing module named numpy.amin - imported by numpy (top-level), numpy.ma.core (top-level)
missing module named numpy.amax - imported by numpy (top-level), numpy.ma.core (top-level)
missing module named numpy.float64 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.float32 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.uint64 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random.bit_generator (top-level), numpy.random._philox (top-level), numpy.random._sfc64 (top-level), numpy.random._generator (top-level)
missing module named numpy.uint32 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random.bit_generator (top-level), numpy.random._generator (top-level), numpy.random._mt19937 (top-level)
missing module named numpy.uint16 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.uint8 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.int64 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.int32 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level), dill._objects (optional)
missing module named numpy.int16 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.int8 - imported by numpy (top-level), numpy.array_api._typing (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.bytes_ - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.str_ - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.void - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.object_ - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.datetime64 - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.timedelta64 - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.number - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.complexfloating - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.floating - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.integer - imported by numpy (top-level), numpy._typing._array_like (top-level), numpy.ctypeslib (top-level)
missing module named numpy.unsignedinteger - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.bool_ - imported by numpy (top-level), numpy._typing._array_like (top-level), numpy.ma.core (top-level), numpy.ma.mrecords (top-level), numpy.random.mtrand (top-level), numpy.random._generator (top-level)
missing module named numpy.generic - imported by numpy (top-level), numpy._typing._array_like (top-level)
missing module named numpy.dtype - imported by numpy (top-level), numpy._typing._array_like (top-level), numpy.array_api._typing (top-level), numpy.ma.mrecords (top-level), numpy.random.mtrand (top-level), numpy.random.bit_generator (top-level), numpy.random._philox (top-level), numpy.random._sfc64 (top-level), numpy.random._generator (top-level), numpy.random._mt19937 (top-level), numpy.ctypeslib (top-level), dill._dill (delayed)
missing module named numpy.ndarray - imported by numpy (top-level), numpy._typing._array_like (top-level), numpy.ma.core (top-level), numpy.ma.extras (top-level), numpy.ma.mrecords (top-level), numpy.random.mtrand (top-level), numpy.random.bit_generator (top-level), numpy.random._philox (top-level), numpy.random._sfc64 (top-level), numpy.random._generator (top-level), numpy.random._mt19937 (top-level), numpy.ctypeslib (top-level), IPython.core.magics.namespace (delayed, conditional, optional), dill._dill (delayed), _pytest.python_api (conditional)
missing module named numpy.ufunc - imported by numpy (top-level), numpy._typing (top-level), dill._dill (delayed), dill._objects (optional)
missing module named numpy.histogramdd - imported by numpy (delayed), numpy.lib.twodim_base (delayed)
missing module named simplejson - imported by requests.compat (conditional, optional)
runtime module named urllib3.packages.six.moves - imported by http.client (top-level), urllib3.util.response (top-level), urllib3.connectionpool (top-level), urllib3.packages.six.moves.urllib (top-level), urllib3.util.queue (top-level)
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named Queue - imported by urllib3.util.queue (conditional), debugpy.common.compat (conditional)
missing module named 'urllib3.packages.six.moves.urllib.parse' - imported by urllib3.request (top-level), urllib3.poolmanager (top-level)
missing module named collections.MutableMapping - imported by collections (conditional), paramiko.hostkeys (conditional), urllib3._collections (optional), lxml.html (optional)
missing module named collections.Mapping - imported by collections (optional), parso.python.tree (optional), pytz.lazy (optional), jsonpointer (optional), urllib3._collections (optional)
missing module named unicodedata2 - imported by charset_normalizer.utils (optional)
missing module named urllib3_secure_extra - imported by urllib3 (optional)
missing module named olefile - imported by PIL.FpxImagePlugin (top-level), PIL.MicImagePlugin (top-level)
missing module named PIL._imagingcms - imported by PIL (optional), PIL.ImageCms (optional)
missing module named dummy_thread - imported by cffi.lock (conditional, optional)
missing module named thread - imported by cffi.lock (conditional, optional), cffi.cparser (conditional, optional), zmq.eventloop.minitornado.ioloop (optional), paramiko.win_pageant (optional)
missing module named cStringIO - imported by cffi.ffiplatform (optional), paramiko.py3compat (conditional), yapf.yapflib.py3compat (conditional)
missing module named cPickle - imported by pycparser.ply.yacc (delayed, optional), pickleshare (optional)
missing module named cffi._pycparser - imported by cffi (optional), cffi.cparser (optional)
missing module named xmlrpclib - imported by defusedxml.xmlrpc (conditional)
missing module named PIL._imagingagg - imported by PIL (delayed, conditional, optional), PIL.ImageDraw (delayed, conditional, optional)
missing module named geventwebsocket - imported by flask_socketio (delayed, conditional, optional)
missing module named gevent - imported by socketio.kombu_manager (delayed, conditional), flask_socketio (delayed, conditional), zmq.green.core (top-level), zmq.green.poll (top-level)
missing module named 'eventlet.green' - imported by socketio.zmq_manager (delayed, optional), flask_socketio (delayed, conditional)
missing module named 'eventlet.wsgi' - imported by flask_socketio (delayed, conditional)
missing module named eventlet - imported by socketio.kombu_manager (delayed, conditional), flask_socketio (delayed, conditional)
missing module named asgiref - imported by flask.app (delayed, optional)
missing module named dotenv - imported by flask.cli (delayed, optional)
missing module named socketio.socketio_manage - imported by socketio (optional), flask_socketio (optional)
missing module named aio_pika - imported by socketio.async_aiopika_manager (optional)
missing module named 'valkey.exceptions' - imported by socketio.redis_manager (optional), socketio.async_redis_manager (optional)
missing module named valkey - imported by socketio.redis_manager (optional), socketio.async_redis_manager (optional)
missing module named 'aioredis.exceptions' - imported by socketio.async_redis_manager (optional)
missing module named aioredis - imported by socketio.async_redis_manager (optional)
missing module named 'redis.exceptions' - imported by socketio.redis_manager (optional), socketio.async_redis_manager (optional)
missing module named redis - imported by socketio.redis_manager (optional), socketio.async_redis_manager (optional)
missing module named kafka - imported by socketio.kafka_manager (optional)
missing module named 'gevent.monkey' - imported by socketio.redis_manager (delayed, conditional)
missing module named 'eventlet.patcher' - imported by socketio.redis_manager (delayed, conditional)
missing module named kombu - imported by socketio.kombu_manager (optional)
missing module named '__pypy__.builders' - imported by msgpack.fallback (conditional, optional)
missing module named __pypy__ - imported by msgpack.fallback (conditional)
missing module named aiocontextvars - imported by loguru._contextvars (delayed, conditional)
missing module named exceptiongroup - imported by loguru._better_exceptions (conditional, optional)
missing module named trio - imported by IPython.core.async_helpers (delayed), ipykernel.trio_runner (top-level)
missing module named _typeshed - imported by prompt_toolkit.eventloop.inputhook (conditional)
missing module named ConfigParser - imported by docutils.frontend (conditional), yapf.yapflib.py3compat (conditional), docutils.writers.odf_odt (conditional)
missing module named __builtin__ - imported by paramiko.py3compat (conditional), ptyprocess.ptyprocess (optional), yapf.yapflib.py3compat (conditional), debugpy.common.compat (conditional)
missing module named 'blib2to3.driver' - imported by blib2to3.pgen2.parse (conditional)
missing module named pgen2 - imported by blib2to3.pgen2.conv (top-level)
missing module named jnius - imported by platformdirs.android (delayed, optional)
missing module named tokenize_rt - imported by black.handle_ipynb_magics (delayed, optional)
missing module named typed_ast - imported by sphinx.pycode.ast (conditional, optional), black.parsing (optional)
missing module named tomllib - imported by black.files (conditional, optional)
missing module named uvloop - imported by black.concurrency (delayed, optional)
missing module named prompt_toolkit.filters.vi_mode - imported by prompt_toolkit.filters (top-level), prompt_toolkit.document (top-level), prompt_toolkit.key_binding.bindings.page_navigation (top-level), prompt_toolkit.widgets.toolbars (top-level), IPython.terminal.shortcuts (top-level)
missing module named 'prompt_toolkit.key_binding.key_bindings.vi' - imported by prompt_toolkit.key_binding.vi_state (conditional)
missing module named prompt_toolkit.filters.is_done - imported by prompt_toolkit.filters (top-level), prompt_toolkit.layout.menus (top-level), prompt_toolkit.widgets.base (top-level), prompt_toolkit.shortcuts.progress_bar.base (top-level), prompt_toolkit.shortcuts.prompt (top-level)
missing module named prompt_toolkit.filters.has_completions - imported by prompt_toolkit.filters (top-level), prompt_toolkit.layout.menus (top-level), prompt_toolkit.widgets.toolbars (top-level), prompt_toolkit.widgets.dialogs (top-level), IPython.terminal.shortcuts (top-level)
missing module named prompt_toolkit.filters.vi_insert_mode - imported by prompt_toolkit.filters (top-level), prompt_toolkit.layout.containers (top-level), prompt_toolkit.key_binding.bindings.basic (top-level), IPython.terminal.shortcuts (top-level)
missing module named prompt_toolkit.filters.emacs_insert_mode - imported by prompt_toolkit.filters (top-level), prompt_toolkit.layout.containers (top-level), prompt_toolkit.key_binding.bindings.basic (top-level), prompt_toolkit.key_binding.bindings.emacs (top-level), IPython.terminal.shortcuts (top-level)
missing module named prompt_toolkit.filters.is_searching - imported by prompt_toolkit.filters (top-level), prompt_toolkit.search (top-level), prompt_toolkit.key_binding.bindings.search (top-level), prompt_toolkit.key_binding.bindings.vi (top-level)
missing module named ctags - imported by pygments.formatters.html (optional)
missing module named pygments.formatters.LatexFormatter - imported by pygments.formatters (delayed), IPython.lib.display (delayed), sphinx.highlighting (top-level)
missing module named pygments.formatters.HtmlFormatter - imported by pygments.formatters (delayed), IPython.lib.display (delayed), IPython.core.oinspect (top-level), stack_data.core (delayed), sphinx.highlighting (top-level)
missing module named pygments.lexers.TextLexer - imported by pygments.lexers (top-level), sphinx.highlighting (top-level)
missing module named pygments.lexers.RstLexer - imported by pygments.lexers (top-level), sphinx.highlighting (top-level)
missing module named pygments.lexers.PythonConsoleLexer - imported by pygments.lexers (top-level), sphinx.highlighting (top-level), sphinx.transforms.post_transforms.code (top-level)
missing module named pygments.lexers.Python3Lexer - imported by pygments.lexers (top-level), sphinx.highlighting (top-level)
missing module named pygments.lexers.CLexer - imported by pygments.lexers (top-level), sphinx.highlighting (top-level)
missing module named pygments.lexers.PythonLexer - imported by pygments.lexers (top-level), IPython.core.oinspect (top-level), sphinx.highlighting (top-level)
missing module named 'sphinx.domain' - imported by sphinx.transforms (conditional), sphinx.util.nodes (conditional)
missing module named sets - imported by pytz.tzinfo (optional)
missing module named UserDict - imported by pytz.lazy (optional)
missing module named sphinx_rtd_theme - imported by sphinx.theming (delayed, optional)
missing module named Stemmer - imported by sphinx.util.stemmer (optional), snowballstemmer (optional)
missing module named Levenshtein - imported by sphinx.versioning (optional)
missing module named urllib2 - imported by docutils.parsers.rst.directives.misc (delayed, conditional), docutils.writers.odf_odt (conditional), docutils.parsers.rst.directives.tables (delayed, conditional), lxml.ElementInclude (optional), lxml.html.html5parser (optional)
missing module named Image - imported by docutils.parsers.rst.directives.images (optional)
missing module named roman - imported by docutils.writers.latex2e (optional), docutils.writers.manpage (optional), sphinx.writers.latex (optional)
missing module named 'requests.packages.urllib3' - imported by sphinx.util.requests (optional)
missing module named htmlentitydefs - imported by lxml.html.soupparser (optional)
missing module named BeautifulSoup - imported by lxml.html.soupparser (optional)
missing module named cchardet - imported by bs4.dammit (optional)
missing module named 'html5lib.treebuilders' - imported by bs4.builder._html5lib (optional), lxml.html._html5builder (top-level), lxml.html.html5parser (top-level)
missing module named 'html5lib.constants' - imported by bs4.builder._html5lib (top-level)
missing module named html5lib - imported by bs4.builder._html5lib (top-level), lxml.html.html5parser (top-level)
missing module named urlparse - imported by lxml.ElementInclude (optional), lxml.html (optional), lxml.html.clean (optional), lxml.html.html5parser (optional)
missing module named subunit - imported by twisted.trial.reporter (optional)
missing module named '_pytest.code' - imported by _pytest.hookspec (conditional)
missing module named py.process - imported by py (top-level), py._path.svnurl (top-level)
missing module named py.path - imported by py (top-level), py._path.svnurl (top-level)
missing module named apipkg - imported by py (optional)
missing module named 'importlib.resources.readers' - imported by _pytest.assertion.rewrite (delayed, conditional)
missing module named argcomplete - imported by _pytest._argcomplete (conditional, optional)
missing module named jieba - imported by sphinx.search.zh (optional)
missing module named janome - imported by sphinx.search.ja (optional)
missing module named MeCab - imported by sphinx.search.ja (optional)
missing module named traitlets.config.Application - imported by traitlets.config (delayed, conditional), traitlets.log (delayed, conditional), ipykernel.kernelspec (top-level)
missing module named importlib_resources - imported by matplotlib.style.core (conditional), jsonschema._utils (conditional)
missing module named matplotlib.axes.Axes - imported by matplotlib.axes (delayed), matplotlib.legend (delayed), matplotlib.projections.geo (top-level), matplotlib.projections.polar (top-level), mpl_toolkits.mplot3d.axes3d (top-level), matplotlib.figure (top-level), matplotlib.pyplot (top-level)
missing module named six.moves.range - imported by six.moves (top-level), dateutil.rrule (top-level)
runtime module named six.moves - imported by dateutil.tz.tz (top-level), dateutil.tz._factories (top-level), dateutil.tz.win (top-level), dateutil.rrule (top-level), asttokens.asttokens (top-level), six.moves.urllib (top-level)
missing module named six.moves.xrange - imported by six.moves (top-level), asttokens.asttokens (top-level)
missing module named dateutil.tz.tzfile - imported by dateutil.tz (top-level), dateutil.zoneinfo (top-level)
missing module named gi - imported by matplotlib.cbook (delayed, conditional), ipykernel.gui.gtk3embed (top-level)
missing module named shiboken2 - imported by matplotlib.backends.qt_compat (delayed, conditional, optional)
missing module named sip - imported by IPython.external.qt_loaders (delayed, optional), matplotlib.backends.qt_compat (delayed, conditional), PyQt5 (top-level)
missing module named shiboken6 - imported by matplotlib.backends.qt_compat (delayed, conditional)
missing module named setuptools_scm - imported by matplotlib (delayed, conditional)
missing module named prompt_toolkit.filters.vi_insert_multiple_mode - imported by prompt_toolkit.filters (top-level), prompt_toolkit.layout.processors (top-level)
missing module named System - imported by IPython.utils._process_cli (top-level)
missing module named clr - imported by IPython.utils._process_cli (top-level)
missing module named curio - imported by IPython.core.async_helpers (delayed)
missing module named 'gi.repository' - imported by ipykernel.gui.gtk3embed (top-level)
missing module named gtk - imported by ipykernel.gui.gtkembed (top-level)
missing module named gobject - imported by ipykernel.gui.gtkembed (top-level)
missing module named wx - imported by IPython.lib.guisupport (delayed), ipykernel.eventloops (delayed)
missing module named PySide2 - imported by ipykernel.eventloops (delayed, conditional, optional)
missing module named ipyparallel - imported by ipykernel.zmqshell (delayed, conditional)
missing module named ipykernel.get_connection_info - imported by ipykernel (top-level), ipykernel.zmqshell (top-level)
missing module named ipykernel.get_connection_file - imported by ipykernel (top-level), ipykernel.zmqshell (top-level)
missing module named ipykernel.connect_qtconsole - imported by ipykernel (top-level), ipykernel.zmqshell (top-level)
missing module named isoduration - imported by jsonschema._format (top-level)
missing module named uri_template - imported by jsonschema._format (top-level)
missing module named webcolors - imported by jsonschema._format (top-level)
missing module named rfc3339_validator - imported by jsonschema._format (top-level)
missing module named rfc3986_validator - imported by jsonschema._format (optional)
missing module named rfc3987 - imported by jsonschema._format (optional)
missing module named fqdn - imported by jsonschema._format (top-level)
missing module named _subprocess - imported by jupyter_client.launcher (delayed, conditional, optional), ipykernel.parentpoller (delayed, optional)
missing module named _dbm - imported by dbm.ndbm (top-level)
missing module named _gdbm - imported by dbm.gnu (top-level)
missing module named diff - imported by dill._dill (delayed, conditional, optional)
missing module named dill.diff - imported by dill (delayed, conditional, optional), dill._dill (delayed, conditional, optional)
missing module named version - imported by dill (optional)
missing module named 'ipyparallel.serialize' - imported by ipykernel.ipkernel (delayed, optional), ipykernel.serialize (optional), ipykernel.pickleutil (top-level)
missing module named appnope - imported by ipykernel.ipkernel (delayed, conditional)
missing module named '_pydevd_bundle.pydevd_api' - imported by ipykernel.debugger (delayed)
missing module named '_pydevd_bundle.pydevd_suspended_frames' - imported by ipykernel.debugger (optional)
missing module named _pydevd_bundle - imported by debugpy._vendored.force_pydevd (top-level), ipykernel.debugger (optional)
missing module named pydevd_file_utils - imported by debugpy.server.api (top-level)
missing module named '_pydevd_bundle.pydevd_constants' - imported by debugpy.server.api (top-level)
missing module named pydevd - imported by debugpy._vendored.force_pydevd (top-level), debugpy.server.api (top-level)
missing module named netifaces - imported by jupyter_client.localinterfaces (delayed)
missing module named 'tornado.platform.select' - imported by zmq.eventloop.minitornado.ioloop (delayed)
missing module named 'tornado.platform.kqueue' - imported by zmq.eventloop.minitornado.ioloop (delayed, conditional)
missing module named 'tornado.platform.epoll' - imported by zmq.eventloop.minitornado.ioloop (delayed, conditional)
missing module named monotime - imported by zmq.eventloop.minitornado.platform.auto (optional)
missing module named 'tornado.stack_context' - imported by zmq.eventloop.zmqstream (optional)
missing module named zmq.ZMQError - imported by zmq (delayed, optional), zmq.sugar.attrsettr (delayed, optional), zmq.eventloop._deprecated (top-level)
missing module named invoke - imported by paramiko.config (optional)
missing module named gssapi - imported by paramiko.ssh_gss (optional)
missing module named jupyter_client.write_connection_file - imported by jupyter_client (top-level), ipykernel.kernelapp (top-level), ipykernel.connect (top-level)
missing module named 'gevent.core' - imported by zmq.green.core (delayed, optional)
missing module named 'gevent.hub' - imported by zmq.green.core (top-level)
missing module named 'gevent.event' - imported by zmq.green.core (top-level)
missing module named zmq.backend.zmq_version_info - imported by zmq.backend (top-level), zmq.sugar.version (top-level)
missing module named zmq.backend.Frame - imported by zmq.backend (top-level), zmq.sugar.frame (top-level), zmq.sugar.tracker (top-level)
missing module named zmq.backend.Socket - imported by zmq.backend (top-level), zmq.sugar.socket (top-level)
missing module named zmq.backend.zmq_poll - imported by zmq.backend (top-level), zmq.sugar.poll (top-level)
missing module named pyczmq - imported by zmq.sugar.context (delayed)
missing module named zmq.backend.Context - imported by zmq.backend (top-level), zmq.sugar.context (top-level)
missing module named zmq.backend.zmq_errno - imported by zmq.backend (delayed), zmq.error (delayed, conditional)
missing module named zmq.backend.strerror - imported by zmq.backend (delayed), zmq.error (delayed)
missing module named zmq.zmq_version_info - imported by zmq (delayed, conditional), zmq.error (delayed, conditional)
missing module named zmq.zmq_version - imported by zmq (delayed, conditional), zmq.error (delayed, conditional)
missing module named zmq.libzmq - imported by zmq (delayed, optional)
missing module named docrepr - imported by IPython.core.interactiveshell (optional)
missing module named pathlib2 - imported by pickleshare (optional)

File diff suppressed because it is too large Load Diff

17
build_exe.bat Normal file
View File

@@ -0,0 +1,17 @@
@echo off
chcp 65001 >nul
echo 正在打包 DTU-RemoteLCD 为 exe ...
echo.
rem 使用当前环境中的 python 和 pip而不是系统默认 pip
python -m pip install pyinstaller -q
python -m PyInstaller remo_disp_server.spec --noconfirm
if %ERRORLEVEL% equ 0 (
echo.
echo 打包完成。可执行文件: dist\remo_disp_server.exe
echo 直接双击运行,或在命令行: dist\remo_disp_server.exe [装置IP]
) else (
echo 打包失败,请检查错误信息。
exit /b 1
)

140
dist/remo_disp.log vendored Normal file
View File

@@ -0,0 +1,140 @@
2026-03-03 11:21:23.189 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 11:21:23.190 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 11:21:23.190 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 11:21:23.917 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 11:21:23.917 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 11:21:23.918 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 11:21:23.934 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=Ctr5knFEiqAgM5p4AAAB
2026-03-03 11:21:23.939 | INFO | __main__:on_disconnect_device:409 - [on_disconnect_device] 前端请求断开设备 sid=Ctr5knFEiqAgM5p4AAAB
2026-03-03 11:21:23.939 | INFO | __main__:on_disconnect_device:415 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 11:21:33.635 | INFO | __main__:on_disconnect:374 - [on_disconnect] WebSocket 客户端断开 sid=Ctr5knFEiqAgM5p4AAAB
2026-03-03 11:21:33.709 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=E1OFdqsmDVZG6Zn_AAAD
2026-03-03 11:21:35.789 | INFO | __main__:on_connect_device:388 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 11:21:35.811 | INFO | __main__:connect:153 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 11:21:35.812 | INFO | __main__:_screen_refresh_loop:305 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 11:21:35.812 | INFO | __main__:on_connect_device:396 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 11:21:35.817 | INFO | __main__:on_connect_device:398 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=E1OFdqsmDVZG6Zn_AAAD
2026-03-03 11:21:44.896 | INFO | __main__:on_disconnect_device:409 - [on_disconnect_device] 前端请求断开设备 sid=E1OFdqsmDVZG6Zn_AAAD
2026-03-03 11:21:44.896 | INFO | __main__:disconnect_device:288 - [disconnect_device] 正在关闭与 DTU 的连接
2026-03-03 11:21:44.897 | INFO | __main__:on_disconnect_device:415 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 11:21:44.897 | ERROR | __main__:_recv:218 - [_recv] 接收异常 - [WinError 10038] 在一个非套接字上尝试了一个操作。
Traceback (most recent call last):
File "threading.py", line 973, in _bootstrap
File "threading.py", line 1016, in _bootstrap_inner
File "threading.py", line 953, in run
File "remo_disp_server.py", line 309, in _screen_refresh_loop
File "remo_disp_server.py", line 238, in fetch_screen
> File "remo_disp_server.py", line 187, in _recv
OSError: [WinError 10038] 在一个非套接字上尝试了一个操作。
2026-03-03 11:21:44.901 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 11:21:44.902 | INFO | __main__:_screen_refresh_loop:331 - [_screen_refresh_loop] 刷新线程退出
2026-03-03 11:40:43.024 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 11:40:43.024 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 11:40:43.024 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 11:40:43.041 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=nzlFmUGqWK1FZE5ZAAAB
2026-03-03 11:40:55.131 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 11:40:55.132 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 11:40:55.132 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 11:40:55.817 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=PNeE423Ccgzhel5wAAAB
2026-03-03 11:41:09.161 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 11:41:09.164 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 11:41:09.165 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 11:41:09.840 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=41Q1HD4nG4kq43pTAAAB
2026-03-03 13:51:50.972 | INFO | __main__:on_connect_device:388 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 13:51:50.992 | INFO | __main__:connect:153 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 13:51:50.992 | INFO | __main__:_screen_refresh_loop:305 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 13:51:50.994 | INFO | __main__:on_connect_device:396 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 13:51:50.994 | INFO | __main__:on_connect_device:398 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=41Q1HD4nG4kq43pTAAAB
2026-03-03 13:51:54.806 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:51:54.806 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:51:58.564 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:51:58.565 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:00.800 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:00.800 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:02.585 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:02.585 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:03.648 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:03.648 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:04.710 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:04.710 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:07.686 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:07.686 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:08.496 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:08.499 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:09.592 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:09.592 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:09.939 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:09.940 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:11.246 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:11.247 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:12.157 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:12.157 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:12.492 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:12.492 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:12.600 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:12.601 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:14.349 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:14.349 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:14.577 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:14.577 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:14.804 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:14.804 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:15.261 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:15.261 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:15.854 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:15.855 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:16.082 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:16.082 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:16.462 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:16.462 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:16.692 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:16.692 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:16.920 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:16.920 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:17.147 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:17.151 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:17.375 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:17.376 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:17.602 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:17.602 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:20.000 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:20.001 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:20.344 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:20.345 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:20.808 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:20.808 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:21.886 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:21.887 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:21.991 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:21.991 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:22.336 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:22.337 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:52:22.724 | ERROR | __main__:parse_frame:113 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 13:52:22.725 | ERROR | __main__:fetch_screen:246 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 13:56:19.508 | INFO | __main__:on_disconnect_device:409 - [on_disconnect_device] 前端请求断开设备 sid=41Q1HD4nG4kq43pTAAAB
2026-03-03 13:56:19.509 | INFO | __main__:disconnect_device:288 - [disconnect_device] 正在关闭与 DTU 的连接
2026-03-03 13:56:19.509 | INFO | __main__:_screen_refresh_loop:331 - [_screen_refresh_loop] 刷新线程退出
2026-03-03 13:56:19.511 | INFO | __main__:on_disconnect_device:415 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 14:01:44.744 | INFO | __main__:main:460 - 日志级别: INFO
2026-03-03 14:01:44.744 | INFO | __main__:main:461 - 远程显示服务: http://localhost:8181
2026-03-03 14:01:44.745 | INFO | __main__:main:462 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 14:01:45.667 | INFO | __main__:main:460 - 日志级别: INFO
2026-03-03 14:01:45.668 | INFO | __main__:main:461 - 远程显示服务: http://localhost:8181
2026-03-03 14:01:45.668 | INFO | __main__:main:462 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 14:01:45.695 | INFO | __main__:on_connect:372 - [on_connect] WebSocket 客户端已连接 sid=aitu2nSlxwEd-tDSAAAB
2026-03-03 14:01:48.901 | INFO | __main__:on_disconnect:380 - [on_disconnect] WebSocket 客户端断开 sid=aitu2nSlxwEd-tDSAAAB
2026-03-03 14:01:49.043 | INFO | __main__:on_connect:372 - [on_connect] WebSocket 客户端已连接 sid=EwBLjRaj-HkrDyLDAAAD
2026-03-03 14:01:51.328 | INFO | __main__:on_connect_device:394 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 14:01:51.332 | INFO | __main__:connect:154 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 14:01:51.333 | INFO | __main__:_screen_refresh_loop:311 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 14:01:51.333 | INFO | __main__:on_connect_device:402 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 14:01:51.334 | INFO | __main__:on_connect_device:404 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=EwBLjRaj-HkrDyLDAAAD
2026-03-03 14:02:29.052 | INFO | __main__:on_disconnect_device:415 - [on_disconnect_device] 前端请求断开设备 sid=EwBLjRaj-HkrDyLDAAAD
2026-03-03 14:02:29.052 | INFO | __main__:disconnect_device:294 - [disconnect_device] 正在关闭与 DTU 的连接
2026-03-03 14:02:29.052 | INFO | __main__:_screen_refresh_loop:337 - [_screen_refresh_loop] 刷新线程退出
2026-03-03 14:02:29.053 | INFO | __main__:on_disconnect_device:421 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 14:02:35.051 | INFO | __main__:on_connect_device:394 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 14:02:35.054 | INFO | __main__:connect:154 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 14:02:35.056 | INFO | __main__:_screen_refresh_loop:311 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 14:02:35.056 | INFO | __main__:on_connect_device:402 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 14:02:35.057 | INFO | __main__:on_connect_device:404 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=EwBLjRaj-HkrDyLDAAAD

BIN
dist/remo_disp_server.exe vendored Normal file

Binary file not shown.

907
remo_disp.log Normal file
View File

@@ -0,0 +1,907 @@
2026-03-03 10:39:32.028 | INFO | __main__:main:408 - 远程显示服务: http://localhost:8181
2026-03-03 10:39:32.029 | INFO | __main__:main:409 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:39:32.623 | INFO | __main__:main:408 - 远程显示服务: http://localhost:8181
2026-03-03 10:39:32.623 | INFO | __main__:main:409 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:39:32.649 | INFO | __main__:on_connect:331 - [on_connect] WebSocket 客户端已连接 sid=KYbr0SIfA_Ge-yHjAAAB
2026-03-03 10:39:39.958 | INFO | __main__:on_disconnect_device:374 - [on_disconnect_device] 前端请求断开设备 sid=KYbr0SIfA_Ge-yHjAAAB
2026-03-03 10:39:39.959 | INFO | __main__:on_disconnect_device:380 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 10:39:42.887 | INFO | __main__:on_connect_device:353 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 10:39:42.891 | INFO | __main__:connect:137 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 10:39:42.892 | INFO | __main__:_screen_refresh_loop:270 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 10:39:42.892 | INFO | __main__:on_connect_device:361 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 10:39:42.892 | INFO | __main__:on_connect_device:363 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=KYbr0SIfA_Ge-yHjAAAB
2026-03-03 10:39:42.892 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:42.919 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 2048 字节
2026-03-03 10:39:42.919 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:43.025 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.026 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=1161
2026-03-03 10:39:43.026 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:43.026 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:43.130 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.130 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.130 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.131 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.187 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.210 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=881
2026-03-03 10:39:43.312 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.312 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.313 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.313 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.314 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.320 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=881
2026-03-03 10:39:43.432 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.432 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.432 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.434 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.434 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.453 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=881
2026-03-03 10:39:43.569 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.570 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.570 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.570 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.570 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.577 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=881
2026-03-03 10:39:43.692 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.692 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.692 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.692 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.692 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.702 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=881
2026-03-03 10:39:43.813 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.813 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.814 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.814 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.814 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.822 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=881
2026-03-03 10:39:43.936 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:43.936 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:43.937 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:43.937 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:43.937 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:43.944 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.057 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.057 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.057 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.059 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.059 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.065 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.179 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.179 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.179 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.179 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.179 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.187 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.301 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.302 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.302 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.302 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.302 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.307 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.421 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.422 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.422 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.422 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.422 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.430 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.542 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.542 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.543 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.543 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.543 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.549 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.663 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.663 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.663 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.664 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.664 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.672 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.784 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.784 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.784 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.784 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.786 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.792 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:44.904 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:44.904 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:44.904 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:44.906 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:44.906 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:44.912 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:45.026 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.026 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.027 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.027 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.027 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.033 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=882
2026-03-03 10:39:45.148 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.152 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:39:45.153 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:45.269 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.269 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4958
2026-03-03 10:39:45.270 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:45.270 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:45.376 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.376 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.376 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.376 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.376 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.382 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:45.495 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.497 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.497 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.497 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.498 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.506 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:45.616 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.616 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.618 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.618 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.618 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.629 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:45.739 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.740 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.740 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.740 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.740 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.746 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:45.860 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.860 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.861 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.861 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.861 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.868 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:45.982 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:45.982 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:45.983 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:45.983 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:45.983 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:45.990 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.102 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.102 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.103 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.103 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.103 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.110 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.223 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.224 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.224 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.224 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.224 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.233 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.345 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.345 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.345 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.346 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.346 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.352 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.453 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.453 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.454 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.454 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.454 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.460 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.574 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.575 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.575 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.575 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.575 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.582 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.695 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.695 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.696 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.696 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.696 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.704 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.818 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.818 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.819 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.819 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.819 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.826 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:46.937 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:46.938 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:46.938 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:46.939 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:46.939 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:46.947 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:47.060 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.060 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.061 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.061 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.061 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.068 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=987
2026-03-03 10:39:47.180 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.180 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.180 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.180 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.180 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.190 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:47.302 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.302 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.303 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.303 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.304 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.310 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:47.423 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.423 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.424 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.424 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.424 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.431 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:47.546 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.546 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.546 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.546 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.546 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.554 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:47.668 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.668 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.668 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.668 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.668 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.675 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:47.790 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.790 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:47.790 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:47.792 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:47.792 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:47.797 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:47.910 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:47.919 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:39:47.919 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:48.032 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.033 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4958
2026-03-03 10:39:48.033 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:48.033 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:48.137 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.137 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.137 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.138 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.138 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.148 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:48.260 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.260 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.261 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.261 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.261 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.270 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:48.381 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.381 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.382 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.382 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.382 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.387 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:48.502 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.503 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.503 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.504 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.504 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.513 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:48.624 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.624 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.625 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.625 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.625 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.632 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:48.746 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.746 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.746 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.747 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.747 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.754 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:48.866 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.866 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.866 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.867 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.867 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.873 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:48.988 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:48.988 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:48.988 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:48.989 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:48.989 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:48.994 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=988
2026-03-03 10:39:49.109 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.119 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:39:49.119 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:49.231 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.232 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4958
2026-03-03 10:39:49.233 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:49.233 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:49.338 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.338 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:49.339 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:49.339 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:49.339 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:49.347 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:49.459 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.459 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:49.460 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:49.460 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:49.460 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:49.467 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:49.581 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.582 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:49.582 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:49.582 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:49.582 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:49.589 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:49.702 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.702 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:49.702 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:49.703 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:49.703 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:49.713 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:49.822 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.823 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:49.823 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:49.823 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:49.823 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:49.830 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=990
2026-03-03 10:39:49.944 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:49.944 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:49.944 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:49.944 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:49.944 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:49.951 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.066 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.066 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.066 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.067 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.067 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.080 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.202 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.203 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.203 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.203 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.204 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.209 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.323 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.323 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.323 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.323 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.325 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.331 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.444 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.444 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.444 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.445 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.445 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.451 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.566 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.567 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.568 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.568 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.568 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.575 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.686 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.686 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.686 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.687 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.687 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.696 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.808 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.808 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.808 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.808 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.808 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.814 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:50.914 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:50.916 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:50.916 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:50.917 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:50.917 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:50.928 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:51.036 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.037 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.038 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.038 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.038 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.043 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:51.160 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.160 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.161 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.161 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.162 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.169 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:51.281 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.281 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.281 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.281 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.282 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.288 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=991
2026-03-03 10:39:51.402 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.403 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.403 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.403 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.403 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.411 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=929
2026-03-03 10:39:51.524 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.524 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.525 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.525 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.525 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.533 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=929
2026-03-03 10:39:51.644 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.644 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.644 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.645 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.645 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.651 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=929
2026-03-03 10:39:51.751 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.752 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:51.752 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:51.752 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:51.752 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:51.761 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=929
2026-03-03 10:39:51.871 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.886 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:39:51.886 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:51.991 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:51.991 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4958
2026-03-03 10:39:51.992 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:51.992 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:52.099 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.100 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.100 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.100 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.101 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.107 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.221 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.222 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.222 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.222 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.222 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.230 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.343 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.343 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.344 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.345 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.346 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.358 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.463 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.463 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.465 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.465 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.466 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.474 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.585 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.586 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.586 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.587 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.587 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.597 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.708 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.708 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.708 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.708 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.709 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.717 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.829 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.829 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.830 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.830 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.831 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.838 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:52.950 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:52.950 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:52.951 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:52.951 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:52.951 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:52.958 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=931
2026-03-03 10:39:53.070 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.070 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.071 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.071 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.071 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.078 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.193 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.194 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.194 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.194 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.195 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.203 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.315 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.317 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.317 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.317 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.317 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.324 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.437 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.437 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.438 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.438 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.438 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.444 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.557 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.558 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.558 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.558 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.558 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.565 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.679 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.680 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.680 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.680 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.681 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.686 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.800 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.800 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.800 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.800 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.801 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.807 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:53.922 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:53.922 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:53.923 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:53.923 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:53.923 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:53.930 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.044 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.044 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.044 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.044 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.045 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.053 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.165 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.165 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.165 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.167 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.167 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.172 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.287 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.288 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.288 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.288 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.288 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.297 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.408 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.409 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.409 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.410 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.410 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.419 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.530 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.530 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.531 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.531 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.531 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.537 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.650 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.650 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.651 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.651 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.651 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.658 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.772 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.772 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.772 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.772 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.772 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.780 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:54.894 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:54.895 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:54.895 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:54.895 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:54.896 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:54.902 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.014 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.014 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.014 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.014 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.015 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.021 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.136 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.136 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.136 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.137 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.137 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.145 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.259 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.259 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.259 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.260 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.260 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.266 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.378 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.379 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.379 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.380 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.380 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.387 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.500 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.500 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.500 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.501 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.501 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.507 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.622 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.622 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.623 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.623 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.624 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.633 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.744 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.744 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.745 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.745 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.745 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.752 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.866 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.866 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.866 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.866 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.867 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.875 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:55.986 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:55.987 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:55.987 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:55.988 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:55.988 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:55.995 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:56.109 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.110 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:56.110 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:56.110 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:56.110 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:56.118 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=930
2026-03-03 10:39:56.229 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.253 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:39:56.253 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:56.366 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.367 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4958
2026-03-03 10:39:56.367 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:56.367 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:56.472 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.473 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:56.473 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:56.474 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:56.474 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:56.481 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:56.593 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.594 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:56.594 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:56.595 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:56.595 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:56.603 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:56.715 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.715 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:56.716 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:56.716 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:56.716 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:56.724 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:56.837 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.837 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:56.838 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:56.838 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:56.838 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:56.846 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:56.960 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:56.960 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:56.960 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:56.960 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:56.961 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:56.968 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:57.083 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.083 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:57.083 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:57.083 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:57.085 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:57.093 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:57.203 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.203 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:57.204 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:57.204 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:57.204 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:57.212 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:57.326 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.327 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:57.327 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:57.328 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:57.328 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:57.336 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:57.447 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.453 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:39:57.454 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:57.554 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.554 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4958
2026-03-03 10:39:57.555 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:57.555 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:57.660 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.661 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:57.661 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:57.661 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:57.662 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:57.669 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:57.782 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.782 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:57.783 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:57.783 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:57.783 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:57.790 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:57.904 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:57.904 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:57.904 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:57.905 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:57.905 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:57.915 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:58.026 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.026 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:58.026 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:58.026 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:58.026 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:58.033 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:58.147 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.147 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:58.147 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:58.147 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:58.147 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:58.154 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:58.267 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.267 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:58.267 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:58.267 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:58.267 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:58.275 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:58.389 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.389 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:58.389 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:58.391 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:58.391 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:58.396 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:58.498 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.498 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=3209
2026-03-03 10:39:58.498 | DEBUG | __main__:parse_frame:115 - [parse_frame] 成功解析帧 cmd=0x3, length=3204
2026-03-03 10:39:58.498 | DEBUG | __main__:fetch_screen:207 - [fetch_screen] 收到 LCDMEMpayload_len=3204
2026-03-03 10:39:58.499 | DEBUG | __main__:mono_to_png:222 - [mono_to_png] 开始转换为 PNGwidth=160, height=160, data_len=3200
2026-03-03 10:39:58.508 | DEBUG | __main__:mono_to_png:238 - [mono_to_png] 转换 PNG 成功, png_len=928
2026-03-03 10:39:58.618 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.619 | ERROR | __main__:_recv:174 - [_recv] 数据不完整, 需要 3209 字节, 实际 2048 字节
2026-03-03 10:39:58.619 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:58.724 | DEBUG | __main__:_send:152 - [_send] 已发送 cmd=0x3, data_len=4
2026-03-03 10:39:58.724 | DEBUG | __main__:_recv:180 - [_recv] 收到原始数据 len=4370
2026-03-03 10:39:58.724 | ERROR | __main__:parse_frame:97 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:39:58.726 | ERROR | __main__:fetch_screen:211 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:39:58.736 | INFO | __main__:on_disconnect_device:374 - [on_disconnect_device] 前端请求断开设备 sid=KYbr0SIfA_Ge-yHjAAAB
2026-03-03 10:39:58.736 | INFO | __main__:disconnect_device:253 - [disconnect_device] 正在关闭与 DTU 的连接
2026-03-03 10:39:58.736 | INFO | __main__:_screen_refresh_loop:296 - [_screen_refresh_loop] 刷新线程退出
2026-03-03 10:39:58.737 | INFO | __main__:on_disconnect_device:380 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 10:42:03.734 | INFO | __main__:main:408 - 远程显示服务: http://localhost:8181
2026-03-03 10:42:03.735 | INFO | __main__:main:409 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:42:03.764 | INFO | __main__:on_connect:331 - [on_connect] WebSocket 客户端已连接 sid=5WGcCeshP4VteYt8AAAB
2026-03-03 10:42:10.376 | INFO | __main__:main:423 - 日志级别: INFO设置环境变量 LOG_LEVEL=DEBUG 可显示调试信息)
2026-03-03 10:42:10.376 | INFO | __main__:main:424 - 远程显示服务: http://localhost:8181
2026-03-03 10:42:10.376 | INFO | __main__:main:425 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:42:10.403 | INFO | __main__:on_connect:331 - [on_connect] WebSocket 客户端已连接 sid=W8a_sM62XqavuiVCAAAB
2026-03-03 10:42:15.940 | INFO | __main__:main:426 - 日志级别: INFO设置环境变量 LOG_LEVEL=DEBUG 可显示调试信息)
2026-03-03 10:42:15.941 | INFO | __main__:main:427 - 远程显示服务: http://localhost:8181
2026-03-03 10:42:15.941 | INFO | __main__:main:428 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:42:15.970 | INFO | __main__:on_connect:334 - [on_connect] WebSocket 客户端已连接 sid=4EYcfW07jGHRZ4WmAAAB
2026-03-03 10:44:27.578 | INFO | __main__:main:425 - 日志级别: INFO设置环境变量 LOG_LEVEL=DEBUG 可显示调试信息)
2026-03-03 10:44:27.578 | INFO | __main__:main:426 - 远程显示服务: http://localhost:8181
2026-03-03 10:44:27.578 | INFO | __main__:main:427 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:44:27.914 | INFO | __main__:on_connect:333 - [on_connect] WebSocket 客户端已连接 sid=kpFFdwZQI9_UkdRVAAAB
2026-03-03 10:44:31.364 | INFO | __main__:main:432 - 日志级别: INFO设置环境变量 LOG_LEVEL=DEBUG 可显示调试信息)
2026-03-03 10:44:31.364 | INFO | __main__:main:433 - 远程显示服务: http://localhost:8181
2026-03-03 10:44:31.365 | INFO | __main__:main:434 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:44:31.389 | INFO | __main__:on_connect:340 - [on_connect] WebSocket 客户端已连接 sid=fWxaQlSu66H29I2kAAAB
2026-03-03 10:44:35.913 | INFO | __main__:main:428 - 日志级别: INFO
2026-03-03 10:44:35.914 | INFO | __main__:main:429 - 远程显示服务: http://localhost:8181
2026-03-03 10:44:35.914 | INFO | __main__:main:430 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:44:36.676 | INFO | __main__:on_connect:340 - [on_connect] WebSocket 客户端已连接 sid=MqqCHhOXdrL5TKhEAAAB
2026-03-03 10:45:10.479 | INFO | __main__:main:428 - 日志级别: INFO
2026-03-03 10:45:10.481 | INFO | __main__:main:429 - 远程显示服务: http://localhost:8181
2026-03-03 10:45:10.481 | INFO | __main__:main:430 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:45:10.930 | INFO | __main__:on_connect:340 - [on_connect] WebSocket 客户端已连接 sid=XFoaDsSCPcyC2O4CAAAB
2026-03-03 10:45:50.769 | INFO | __main__:main:428 - 日志级别: INFO
2026-03-03 10:45:50.769 | INFO | __main__:main:429 - 远程显示服务: http://localhost:8181
2026-03-03 10:45:50.771 | INFO | __main__:main:430 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:45:50.800 | INFO | __main__:on_connect:340 - [on_connect] WebSocket 客户端已连接 sid=x3LE0sEpg8ZaNOzsAAAB
2026-03-03 10:46:00.098 | INFO | __main__:on_connect_device:362 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 10:46:00.119 | INFO | __main__:connect:146 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 10:46:00.120 | INFO | __main__:_screen_refresh_loop:279 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 10:46:00.120 | INFO | __main__:on_connect_device:370 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 10:46:00.121 | INFO | __main__:on_connect_device:372 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=x3LE0sEpg8ZaNOzsAAAB
2026-03-03 10:46:00.167 | ERROR | __main__:_recv:183 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:46:00.167 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:00.269 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:46:00.269 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:02.032 | ERROR | __main__:_recv:183 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:46:02.033 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:02.146 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:46:02.147 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:04.367 | ERROR | __main__:_recv:183 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:46:04.367 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:04.473 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:46:04.474 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:04.833 | ERROR | __main__:_recv:183 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:46:04.833 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:04.943 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:46:04.944 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:06.801 | ERROR | __main__:_recv:183 - [_recv] 数据不完整, 需要 3209 字节, 实际 1460 字节
2026-03-03 10:46:06.801 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:06.903 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:46:06.903 | ERROR | __main__:fetch_screen:220 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:46:07.711 | INFO | __main__:on_disconnect_device:383 - [on_disconnect_device] 前端请求断开设备 sid=x3LE0sEpg8ZaNOzsAAAB
2026-03-03 10:46:07.712 | INFO | __main__:disconnect_device:262 - [disconnect_device] 正在关闭与 DTU 的连接
2026-03-03 10:46:07.712 | INFO | __main__:_screen_refresh_loop:305 - [_screen_refresh_loop] 刷新线程退出
2026-03-03 10:46:07.712 | INFO | __main__:on_disconnect_device:389 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 10:48:17.165 | INFO | __main__:main:447 - 日志级别: INFO
2026-03-03 10:48:17.165 | INFO | __main__:main:448 - 远程显示服务: http://localhost:8181
2026-03-03 10:48:17.167 | INFO | __main__:main:449 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:48:17.894 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=mRDPLRSJgqAGeYNnAAAB
2026-03-03 10:49:32.451 | INFO | __main__:main:447 - 日志级别: INFO
2026-03-03 10:49:32.451 | INFO | __main__:main:448 - 远程显示服务: http://localhost:8181
2026-03-03 10:49:32.451 | INFO | __main__:main:449 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:49:32.607 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=f7ZyM2Ov63vgtKalAAAB
2026-03-03 10:49:35.851 | INFO | __main__:on_disconnect:367 - [on_disconnect] WebSocket 客户端断开 sid=f7ZyM2Ov63vgtKalAAAB
2026-03-03 10:49:35.983 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=PFi1_1ZJ9M7nGGCFAAAD
2026-03-03 10:49:37.907 | INFO | __main__:on_connect_device:381 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 10:49:37.931 | INFO | __main__:connect:146 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 10:49:37.931 | INFO | __main__:_screen_refresh_loop:298 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 10:49:37.931 | INFO | __main__:on_connect_device:389 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 10:49:37.932 | INFO | __main__:on_connect_device:391 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=PFi1_1ZJ9M7nGGCFAAAD
2026-03-03 10:50:50.153 | INFO | __main__:main:447 - 日志级别: INFO
2026-03-03 10:50:50.153 | INFO | __main__:main:448 - 远程显示服务: http://localhost:8181
2026-03-03 10:50:50.153 | INFO | __main__:main:449 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:50:50.178 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=v7jDucygwL-SI5UhAAAB
2026-03-03 10:50:58.018 | INFO | __main__:on_disconnect_device:402 - [on_disconnect_device] 前端请求断开设备 sid=v7jDucygwL-SI5UhAAAB
2026-03-03 10:50:58.018 | INFO | __main__:on_disconnect_device:408 - [on_disconnect_device] 设备已断开(若为最后一个客户端)
2026-03-03 10:50:59.618 | INFO | __main__:on_connect_device:381 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 10:50:59.621 | INFO | __main__:connect:146 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 10:50:59.622 | INFO | __main__:_screen_refresh_loop:298 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 10:50:59.622 | INFO | __main__:on_connect_device:389 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 10:50:59.622 | INFO | __main__:on_connect_device:391 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=v7jDucygwL-SI5UhAAAB
2026-03-03 10:51:14.877 | INFO | __main__:main:447 - 日志级别: INFO
2026-03-03 10:51:14.877 | INFO | __main__:main:448 - 远程显示服务: http://localhost:8181
2026-03-03 10:51:14.878 | INFO | __main__:main:449 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:51:15.157 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=2DZB0uc0SIWIREuiAAAB
2026-03-03 10:52:45.587 | INFO | __main__:main:447 - 日志级别: INFO
2026-03-03 10:52:45.587 | INFO | __main__:main:448 - 远程显示服务: http://localhost:8181
2026-03-03 10:52:45.588 | INFO | __main__:main:449 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:52:46.054 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=5QBk67LW-TFDL6tHAAAB
2026-03-03 10:52:47.445 | INFO | __main__:on_disconnect:367 - [on_disconnect] WebSocket 客户端断开 sid=5QBk67LW-TFDL6tHAAAB
2026-03-03 10:52:47.518 | INFO | __main__:on_connect:359 - [on_connect] WebSocket 客户端已连接 sid=RPNvfkDbk1Eonm-BAAAD
2026-03-03 10:52:51.425 | INFO | __main__:on_connect_device:381 - [on_connect_device] 请求连接 DTU: 192.168.253.3:7003
2026-03-03 10:52:51.442 | INFO | __main__:connect:146 - [connect] 连接 DTU 成功: 192.168.253.3:7003
2026-03-03 10:52:51.442 | INFO | __main__:_screen_refresh_loop:298 - [_screen_refresh_loop] 刷新线程启动
2026-03-03 10:52:51.442 | INFO | __main__:on_connect_device:389 - [on_connect_device] 已启动屏幕刷新线程
2026-03-03 10:52:51.443 | INFO | __main__:on_connect_device:391 - [on_connect_device] 连接 DTU 成功,已加入订阅 sid=RPNvfkDbk1Eonm-BAAAD
2026-03-03 10:53:08.347 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:08.347 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:11.872 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:11.872 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:13.715 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:13.716 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:14.049 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:14.049 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:15.355 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:15.355 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:15.461 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:15.463 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:17.394 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:17.395 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:18.778 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:18.779 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:20.549 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:20.549 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:21.248 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:21.248 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:22.066 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:22.066 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:23.254 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:23.254 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:44.448 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:44.448 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:58.162 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:58.162 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:53:59.088 | ERROR | __main__:parse_frame:106 - [parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len=5
2026-03-03 10:53:59.088 | ERROR | __main__:fetch_screen:239 - [fetch_screen] 未收到有效 LCDMEM 回复result=None
2026-03-03 10:54:51.004 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 10:54:51.005 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 10:54:51.005 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:54:51.038 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=BRUqnH5JE_4q_ZfiAAAB
2026-03-03 10:55:00.524 | INFO | __main__:main:454 - 日志级别: INFO
2026-03-03 10:55:00.525 | INFO | __main__:main:455 - 远程显示服务: http://localhost:8181
2026-03-03 10:55:00.526 | INFO | __main__:main:456 - 使用 WebSocket 传输,在浏览器中打开上述地址
2026-03-03 10:55:00.561 | INFO | __main__:on_connect:366 - [on_connect] WebSocket 客户端已连接 sid=bIsKlXE2qx-4QLI3AAAB

View File

@@ -8,7 +8,9 @@
用法: python remo_disp_server.py [装置IP]
启动后访问 http://localhost:8181
依赖: pip install flask flask-socketio pillow
依赖: pip install flask flask-socketio pillow loguru
日志级别: 在代码中设置 LOG_LEVEL见下方"INFO" 不显示 DEBUG"DEBUG" 显示调试信息。
"""
# base64将二进制 PNG 编码为字符串,便于通过 JSON/WebSocket 传输
@@ -21,12 +23,21 @@ import struct
import threading
# sys读取命令行参数装置 IP
import sys
# os获取当前脚本目录,拼接 favicon 路径
# os获取当前脚本目录、路径与文件检查
import os
# ioBytesIO 用于在内存中保存 PNG
import io
def _get_base_path() -> str:
"""打包成 exe 时资源在 sys._MEIPASS否则为脚本所在目录。"""
if getattr(sys, "frozen", False):
return sys._MEIPASS # type: ignore[attr-defined]
return os.path.dirname(os.path.abspath(__file__))
# typing类型注解
from typing import Optional, Tuple, Set
# loguru结构化日志记录错误与调试信息
from loguru import logger
# FlaskWeb 框架,提供 HTTP 路由
from flask import Flask, request, send_file
@@ -47,6 +58,13 @@ PORT = 7003
# CMD_LCDMEM 3读取显存屏幕画面
CMD_KEEPLIVE, CMD_INIT, CMD_KEY, CMD_LCDMEM = 0, 1, 2, 3
# =============================================================================
# 日志级别(在代码中直接修改)
# =============================================================================
# "INFO":仅输出 INFO/WARNING/ERROR不显示 DEBUG
# "DEBUG":输出包括 DEBUG 在内的全部日志
LOG_LEVEL = "INFO"
# =============================================================================
# 全局状态
# =============================================================================
@@ -90,19 +108,29 @@ def parse_frame(raw: bytes) -> Optional[Tuple[int, bytes]]:
"""
解析设备回复帧,返回 (cmd, data) 或 None。
帧格式: [TAG(1)][cmd(1)][len_hi(1)][len_lo(1)][data(length)][crc(1)]
最短合法帧长度为 5 字节(长度为 0 时: 1+1+2+0+1
"""
if len(raw) < 6 or raw[0] != TAG_DEVICE: # 至少 6 字节且帧头为 TAG_DEVICE
print("[parse_frame] 错误: 帧太短或帧头不是 TAG_DEVICE(0xBB), len=%d" % len(raw))
if len(raw) < 5 or raw[0] != TAG_DEVICE: # 至少 5 字节且帧头为 TAG_DEVICE
logger.error(
"[parse_frame] 帧太短或帧头不是 TAG_DEVICE(0xBB), len={len_}",
len_=len(raw),
)
return None
length = (raw[2] << 8) | raw[3] # 大端序解析数据区长度
if len(raw) < 4 + length + 1: # 检查是否收齐整帧头4字节+数据+CRC1字节
print("[parse_frame] 错误: 数据不完整, 需要 %d 字节, 实际 %d 字节" % (4 + length + 1, len(raw)))
logger.error(
"[parse_frame] 数据不完整, 需要 {need} 字节, 实际 {actual} 字节",
need=4 + length + 1,
actual=len(raw),
)
return None
data = raw[4:4 + length] # 提取数据区
if calc_crc(data) != raw[4 + length]: # CRC 校验失败
print("[parse_frame] 错误: CRC 校验失败")
logger.error("[parse_frame] CRC 校验失败")
return None
return (raw[1], data) # 返回 (命令码, 数据)
cmd = raw[1]
logger.debug("[parse_frame] 成功解析帧 cmd={cmd:#x}, length={length}", cmd=cmd, length=length)
return (cmd, data) # 返回 (命令码, 数据)
# =============================================================================
@@ -118,49 +146,77 @@ def connect(host: str, port: int = PORT) -> bool:
try:
if _sock:
_sock.close() # 关闭旧连接
logger.info("[connect] 已关闭旧连接")
_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建 TCP socket
_sock.settimeout(3.0) # 连接阶段超时 3 秒
_sock.connect((host, port)) # 连接目标主机和端口
_sock.settimeout(2.0) # 连接成功后收发超时 2 秒
logger.info("[connect] 连接 DTU 成功: {host}:{port}", host=host, port=port)
return True
except Exception as e:
print("[connect] 错误: 连接失败 - %s" % e)
logger.exception("[connect] 连接失败: {host}:{port} - {err}", host=host, port=port, err=e)
return False
def _send(cmd: int, data: bytes = b"") -> bool:
"""发送一帧到设备"""
if not _sock:
print("[_send] 错误: 未连接设备")
logger.error("[_send] 未连接设备,无法发送 cmd={cmd:#x}", cmd=cmd)
return False
try:
_sock.sendall(build_frame(cmd, data)) # 构造帧并一次性发送
frame = build_frame(cmd, data)
_sock.sendall(frame) # 构造帧并一次性发送
logger.debug("[_send] 已发送 cmd={cmd:#x}, data_len={length}", cmd=cmd, length=len(data))
return True
except Exception as e:
print("[_send] 错误: 发送失败 - %s" % e)
logger.exception("[_send] 发送失败 cmd={cmd:#x} - {err}", cmd=cmd, err=e)
return False
def _recv() -> Optional[Tuple[int, bytes]]:
"""
从设备接收一帧,一次性 recv 最多 256KB。
至少需 5 字节4 字节头+1 字节数据或 CRC根据头中 length 检查是否收齐整帧
从设备接收一帧。若首次接收长度不足,会再尝试接收最多 2 次(共 3 次),
拼齐整帧后再解析。单次 recv 最多 256KB
"""
if not _sock:
print("[_recv] 错误: 未连接设备")
logger.error("[_recv] 未连接设备,无法接收数据")
return None
try:
data = _sock.recv(256 * 1024) # 单次接收最多 256KB
if len(data) < 5: # 至少需要 5 字节4 头 + 1 数据/CRC
print("[_recv] 错误: 接收数据太短, len=%d" % len(data))
buffer = b""
max_attempts = 3 # 首次 + 最多再收 2 次
for attempt in range(max_attempts):
chunk = _sock.recv(256 * 1024)
if not chunk:
logger.debug("[_recv] 第 {n} 次 recv 收到空数据,连接可能已关闭", n=attempt + 1)
break
buffer += chunk
if len(buffer) < 5: # 至少需要 5 字节才能解析头
logger.debug("[_recv] 第 {n} 次 recv 后共 {len_} 字节,继续接收", n=attempt + 1, len_=len(buffer))
continue
data_len = (buffer[2] << 8) | buffer[3] # 数据区长度
need = 4 + data_len + 1 # 整帧长度
if len(buffer) >= need:
logger.debug("[_recv] 第 {n} 次 recv 后收齐整帧 len={len_}", n=attempt + 1, len_=need)
return parse_frame(buffer[:need])
logger.debug(
"[_recv] 第 {n} 次 recv 后共 {have} 字节,需要 {need} 字节,继续接收",
n=attempt + 1,
have=len(buffer),
need=need,
)
if len(buffer) < 5:
logger.error("[_recv] 接收数据太短, len={len_}", len_=len(buffer))
return None
length = (data[2] << 8) | data[3] # 解析数据区长度
if len(data) < 4 + length + 1: # 数据不完整
print("[_recv] 错误: 数据不完整, 需要 %d 字节, 实际 %d 字节" % (4 + length + 1, len(data)))
return None
return parse_frame(data[:4 + length + 1]) # 解析并返回 (cmd, data)
need = 4 + ((buffer[2] << 8) | buffer[3]) + 1
logger.error(
"[_recv] 尝试 {max_attempts} 次后数据不完整, 需要 {need} 字节, 实际 {actual} 字节",
max_attempts=max_attempts,
need=need,
actual=len(buffer),
)
return None
except Exception as e:
print("[_recv] 错误: 接收异常 - %s" % e)
logger.exception("[_recv] 接收异常 - {err}", err=e)
return None
@@ -175,19 +231,26 @@ def fetch_screen() -> Optional[bytes]:
发送 CMD_LCDMEM + 起始地址 0设备回复 payload 前 4 字节为地址,后续为位图,返回 payload[4:]。
"""
if not _sock:
print("[fetch_screen] 错误: 未连接设备")
logger.error("[fetch_screen] 未连接设备,无法读取屏幕")
return None
if not _send(CMD_LCDMEM, struct.pack(">I", 0)): # 发送读取显存命令,起始地址 0大端 4 字节)
print("[fetch_screen] 错误: 发送 CMD_LCDMEM 失败")
logger.error("[fetch_screen] 发送 CMD_LCDMEM 失败")
return None
result = _recv() # 接收设备回复
if result and result[0] == CMD_LCDMEM: # 确认为 LCDMEM 回复
payload = result[1] # 数据区
if len(payload) >= 4: # 前 4 字节为地址,后面是位图
return payload[4:]
return payload or None
print("[fetch_screen] 错误: 未收到有效 LCDMEM 回复")
return None
if not result:
logger.error("[fetch_screen] 未收到任何回复result=None")
return None
cmd, payload = result
if cmd != CMD_LCDMEM:
# 可能是按键 ACK、保活等其他短帧按键操作时较常见这里只做调试日志不视为错误
logger.debug("[fetch_screen] 收到非 LCDMEM 帧 cmd={cmd:#x},忽略", cmd=cmd)
return None
# 确认为 LCDMEM 回复
if len(payload) >= 4: # 前 4 字节为地址,后面是位图
logger.debug("[fetch_screen] 收到 LCDMEMpayload_len={len_}", len_=len(payload))
return payload[4:]
logger.debug("[fetch_screen] 收到 LCDMEMpayload_len={len_} (<4)", len_=len(payload))
return payload or None
def mono_to_png(data: bytes, width: int, height: int) -> Optional[bytes]:
@@ -197,18 +260,29 @@ def mono_to_png(data: bytes, width: int, height: int) -> Optional[bytes]:
"""
try:
from PIL import Image
logger.debug(
"[mono_to_png] 开始转换为 PNGwidth={width}, height={height}, data_len={len_}",
width=width,
height=height,
len_=len(data),
)
img = Image.new("1", (width, height)) # 创建 1bpp 黑白图像
pix = img.load() # 获取像素访问对象
for y in range(height):
for x in range(width):
bi = (y * width + x) // 8 # 字节索引:每 8 像素一字节
bit = 7 - (x % 8) # 位索引:高位在前
pix[x, y] = 255 if (bi < len(data) and (data[bi] >> bit) & 1) else 0 # 1→白 0→黑
pix[x, y] = 0 if (bi < len(data) and (data[bi] >> bit) & 1) else 255 # 1→白 0→黑
buf = io.BytesIO() # 内存缓冲区
img.save(buf, format="PNG") # 保存为 PNG 格式
return buf.getvalue() # 返回 PNG 字节流
png_bytes = buf.getvalue()
logger.debug("[mono_to_png] 转换 PNG 成功, png_len={len_}", len_=len(png_bytes))
return png_bytes # 返回 PNG 字节流
except ImportError:
print("[mono_to_png] 错误: 缺少 PIL/Pillow, 请执行 pip install pillow")
logger.error("[mono_to_png] 缺少 PIL/Pillow, 请执行 pip install pillow")
return None
except Exception as e:
logger.exception("[mono_to_png] 转换 PNG 失败 - {err}", err=e)
return None
@@ -217,10 +291,11 @@ def disconnect_device():
global _sock
try:
if _sock:
logger.info("[disconnect_device] 正在关闭与 DTU 的连接")
_sock.close() # 关闭 socket
_sock = None # 清空引用
except Exception as e:
print("[disconnect_device] 错误: 关闭连接时异常 - %s" % e)
logger.exception("[disconnect_device] 关闭连接时异常 - {err}", err=e)
# =============================================================================
@@ -233,21 +308,33 @@ def _screen_refresh_loop():
_refresh_stop.wait(0.1) 既作间隔,也便于收到 set 时快速退出。
"""
global _screen_clients, _refresh_stop
while not _refresh_stop.is_set(): # 未被要求停止时持续循环
if _screen_clients and _sock: # 有客户端且已连接设备
data = fetch_screen() # 拉取屏幕位图
if data:
info = {"width": 160, "height": 160} # 设置长宽 160x160
w, h = info.get("width", 160), info.get("height", 160)
png = mono_to_png(data, w, h) # 转为 PNG
if png:
b64 = base64.b64encode(png).decode("ascii") # base64 编码便于 JSON 传输
for sid in list(_screen_clients): # 复制列表避免迭代时修改
try:
socketio.emit("screen", {"png": b64, "w": w, "h": h}, room=sid) # 推送给该客户端
except Exception:
pass
_refresh_stop.wait(timeout=0.1) # 等待 100ms若被 set 则立即返回
logger.info("[_screen_refresh_loop] 刷新线程启动")
try:
while not _refresh_stop.is_set(): # 未被要求停止时持续循环
if _screen_clients and _sock: # 有客户端且已连接设备
data = fetch_screen() # 拉取屏幕位图
if data:
# 当前协议未返回宽高,这里固定为 160x160可根据实际情况调整
w, h = 160, 160
png = mono_to_png(data, w, h) # 转为 PNG
if png:
b64 = base64.b64encode(png).decode("ascii") # base64 编码便于 JSON 传输
for sid in list(_screen_clients): # 复制列表避免迭代时修改
try:
socketio.emit(
"screen",
{"png": b64, "w": w, "h": h},
room=sid,
) # 推送给该客户端
except Exception as e:
logger.exception(
"[_screen_refresh_loop] 推送 screen 给 {sid} 失败 - {err}",
sid=sid,
err=e,
)
_refresh_stop.wait(timeout=0.1) # 等待 100ms若被 set 则立即返回
finally:
logger.info("[_screen_refresh_loop] 刷新线程退出")
# =============================================================================
@@ -258,7 +345,7 @@ app = Flask(__name__) # 创建 Flask 应用
app.config["SECRET_KEY"] = "remo_disp" # 会话密钥
socketio = SocketIO(app, cors_allowed_origins="*") # 创建 SocketIO允许跨域
FAVICON_PATH = os.path.join(os.path.dirname(__file__), "static", "favicon.ico") # favicon 文件路径
FAVICON_PATH = os.path.join(_get_base_path(), "static", "favicon.ico") # favicon 文件路径
@app.route("/favicon.ico")
@@ -274,7 +361,7 @@ def favicon():
def index():
"""主页,返回前端 HTML"""
return send_file(
os.path.join(os.path.dirname(__file__), "remo_disp_ui.html"),
os.path.join(_get_base_path(), "remo_disp_ui.html"),
mimetype="text/html; charset=utf-8",
)
@@ -282,7 +369,7 @@ def index():
@socketio.on("connect")
def on_connect():
"""WebSocket 客户端连接时触发(可留空)"""
pass
logger.info("[on_connect] WebSocket 客户端已连接 sid={sid}", sid=request.sid)
@socketio.on("disconnect")
@@ -290,6 +377,7 @@ def on_disconnect():
"""WebSocket 客户端断开(关标签页等)时,从 _screen_clients 移除,若无客户端则断开设备"""
global _screen_clients, _refresh_thread, _refresh_stop
sid = request.sid # 获取断开客户端的 session id
logger.info("[on_disconnect] WebSocket 客户端断开 sid={sid}", sid=sid)
if sid in _screen_clients:
_screen_clients.discard(sid) # 从订阅列表移除
if not _screen_clients: # 若无其他客户端
@@ -303,6 +391,7 @@ def on_connect_device(data):
global _screen_clients, _refresh_thread, _refresh_stop
host = (data.get("host") or "").strip() # 从 data 取 host去空格
port = int(data.get("port") or PORT) # 从 data 取 port缺省 7003
logger.info("[on_connect_device] 请求连接 DTU: {host}:{port}", host=host, port=port)
ok = connect(host, port) # 建立 TCP 连接
if ok:
_screen_clients.add(request.sid) # 将当前客户端加入屏幕订阅
@@ -310,8 +399,11 @@ def on_connect_device(data):
if _refresh_thread is None or not _refresh_thread.is_alive(): # 刷新线程未运行
_refresh_thread = threading.Thread(target=_screen_refresh_loop, daemon=True) # 创建后台线程
_refresh_thread.start() # 启动线程
logger.info("[on_connect_device] 已启动屏幕刷新线程")
emit("connect_result", {"success": True}) # 回复连接成功
logger.info("[on_connect_device] 连接 DTU 成功,已加入订阅 sid={sid}", sid=request.sid)
else:
logger.error("[on_connect_device] 连接 DTU 失败: {host}:{port}", host=host, port=port)
emit("connect_result", {"success": False, "error": "connect failed"}) # 回复连接失败
@@ -320,17 +412,20 @@ def on_disconnect_device():
"""前端请求断开设备:从 _screen_clients 移除,若无客户端则断开设备,回复 disconnect_result"""
global _screen_clients, _refresh_stop
sid = request.sid
logger.info("[on_disconnect_device] 前端请求断开设备 sid={sid}", sid=sid)
_screen_clients.discard(sid) # 从订阅列表移除
if not _screen_clients: # 若无其他客户端
_refresh_stop.set() # 通知刷新线程停止
disconnect_device() # 断开设备连接
emit("disconnect_result", {"ok": True}) # 回复断开成功
logger.info("[on_disconnect_device] 设备已断开(若为最后一个客户端)")
@socketio.on("key")
def on_key(data):
"""前端发送按键:从 data 取 code转发给设备"""
code = int(data.get("code", 0)) # 按键码,缺省 0
logger.debug("[on_key] 收到按键 code={code:#x}", code=code)
send_key(code) # 发送给 DTU 设备
@@ -338,14 +433,40 @@ def on_key(data):
# 启动
# =============================================================================
def _configure_log_level():
"""根据全局 LOG_LEVEL 配置日志级别(见文件顶部 LOG_LEVEL 常量)。"""
level = LOG_LEVEL.upper() if isinstance(LOG_LEVEL, str) else "INFO"
if level not in ("TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"):
level = "INFO"
logger.remove() # 移除默认的 stderr 输出
logger.add(sys.stderr, level=level, format="<green>{time:HH:mm:ss}</green> | <level>{level: <8}</level> | <level>{message}</level>")
logger.add(
"remo_disp.log",
rotation="1 week",
encoding="utf-8",
enqueue=True,
backtrace=True,
diagnose=False,
level=level,
)
return level
@logger.catch
def main():
"""主入口:启动 Web 服务"""
port = 8181 # HTTP 服务端口
print(f"远程显示服务: http://localhost:{port}")
print("使用 WebSocket 传输,在浏览器中打开上述地址")
log_level = _configure_log_level()
logger.info("日志级别: {level}", level=log_level)
logger.info("远程显示服务: http://localhost:{port}", port=port)
logger.info("使用 WebSocket 传输,在浏览器中打开上述地址")
if len(sys.argv) >= 2:
connect(sys.argv[1]) # 若命令行有 IP预连接
print(f"已预连接: {sys.argv[1]}")
host = sys.argv[1]
logger.info("[main] 尝试预连接 DTU: {host}", host=host)
if connect(host): # 若命令行有 IP预连接
logger.info("[main] 已预连接: {host}", host=host)
else:
logger.error("[main] 预连接失败: {host}", host=host)
socketio.run(app, host="0.0.0.0", port=port, debug=True, allow_unsafe_werkzeug=True) # 监听所有网卡

63
remo_disp_server.spec Normal file
View File

@@ -0,0 +1,63 @@
# -*- mode: python ; coding: utf-8 -*-
# PyInstaller 打包配置python -m PyInstaller remo_disp_server.spec
# 打包后运行 dist\remo_disp_server\remo_disp_server.exe [装置IP]
block_cipher = None
# 需要随 exe 一起打包的数据文件HTML、静态资源
added_files = [
('remo_disp_ui.html', '.'),
]
# 若存在 static 目录则打包favicon 等)
import os as _os
if _os.path.isdir('static'):
added_files.append(('static', 'static'))
a = Analysis(
['remo_disp_server.py'],
pathex=[],
binaries=[],
datas=added_files,
hiddenimports=[
'engineio.async_drivers.threading',
'flask_socketio',
'python_engineio',
'python_socketio',
'werkzeug',
'PIL',
'PIL._tkinter_finder',
'loguru',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='remo_disp_server',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

View File

@@ -143,8 +143,12 @@
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* 垂直方向居中,与左侧显示区对齐 */
gap: 16px;
padding: 8px;
align-self: stretch;
/* 与 .main 同高,便于内容居中 */
}
/* ========== D-pad 方向键 ========== */
.dpad {

View File

@@ -1,6 +1,6 @@
# 远程显示 Web 服务依赖
# remo_disp_server.py 需要 Flask + flask-socketio + Pillow
# Dependencies for DTU-RemoteLCD web service
Flask>=2.0.0
Pillow>=9.0.0
flask-socketio>=5.0.0
python-socketio>=5.0.0
loguru>=0.7.0