smartpi 0.1.12__py3-none-any.whl → 0.1.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
smartpi/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  __all__ = ["base_driver"]
2
2
 
3
- __version__ = "0.1.12"
3
+ __version__ = "0.1.13"
4
4
 
smartpi/gui.py CHANGED
@@ -1,31 +1,97 @@
1
1
  import socket
2
2
  import json
3
3
  import sys
4
- import time
4
+ import threading
5
+ import queue
6
+ import atexit
5
7
 
6
8
  # 连接对象(模块级单例)
7
9
  _connection = None
10
+ # 命令队列
11
+ _command_queue = queue.Queue(maxsize=1000)
12
+ # 后台发送线程
13
+ _sender_thread = None
14
+ # 线程停止标志
15
+ _stop_event = threading.Event()
8
16
 
9
17
  def init(host="127.0.0.1", port=65167):
10
18
  """初始化GUI连接"""
11
- global _connection
19
+ global _connection, _sender_thread, _stop_event
12
20
  if _connection is None:
13
- _connection = socket.create_connection((host, port))
21
+ try:
22
+ _connection = socket.create_connection((host, port))
23
+ _connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
24
+ except ConnectionRefusedError:
25
+ print(f"无法连接到GUI服务器 {host}:{port}", file=sys.stderr)
26
+ return
27
+
28
+ # 启动后台发送线程
29
+ _stop_event.clear()
30
+ _sender_thread = threading.Thread(target=_send_worker, daemon=True)
31
+ _sender_thread.start()
14
32
  _send({"type": "clear"})
15
33
 
16
- def _send(cmd):
17
- """发送命令到服务器"""
18
- if _connection is None and "pytest" not in sys.modules: # 允许测试环境不初始化
19
- raise ConnectionError("GUI not initialized. Call gui.init() first.")
20
- time.sleep(0.1)
34
+ def _send_worker():
35
+ """后台发送线程的工作函数"""
36
+ while not _stop_event.is_set():
37
+ try:
38
+ # 从队列中获取命令,最多等待0.01秒
39
+ cmd = _command_queue.get(timeout=0.01)
40
+
41
+ if _connection:
42
+ data = json.dumps(cmd) + "\n"
43
+ _connection.sendall(data.encode())
44
+
45
+ # 标记任务完成
46
+ _command_queue.task_done()
47
+ except queue.Empty:
48
+ continue
49
+ except (BrokenPipeError, ConnectionResetError):
50
+ # 连接断开,尝试重新连接
51
+ _reconnect()
52
+ except Exception as e:
53
+ print(f"发送错误: {e}", file=sys.stderr)
54
+ time.sleep(0.1)
55
+
56
+ def _reconnect():
57
+ """尝试重新连接服务器"""
58
+ global _connection
21
59
  if _connection:
22
- _connection.sendall((json.dumps(cmd) + "\n").encode())
23
- time.sleep(0.1)
60
+ try:
61
+ _connection.close()
62
+ except:
63
+ pass
64
+ _connection = None
65
+
66
+ # 尝试重新连接
67
+ try:
68
+ _connection = socket.create_connection(("127.0.0.1", 65167))
69
+ _connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
70
+ _send({"type": "clear"})
71
+ except Exception as e:
72
+ print(f"重新连接失败: {e}", file=sys.stderr)
73
+
74
+ def _send(cmd):
75
+ """发送命令到服务器(线程安全)"""
76
+ # 如果没有连接,直接返回
77
+ if _connection is None and "pytest" not in sys.modules:
78
+ return
79
+
80
+ # 将命令放入队列由后台线程发送
81
+ try:
82
+ _command_queue.put(cmd, block=False)
83
+ except queue.Full:
84
+ # 队列满时丢弃最旧的一条命令
85
+ try:
86
+ _command_queue.get_nowait()
87
+ except queue.Empty:
88
+ pass
89
+ _command_queue.put(cmd, block=False)
24
90
 
25
91
  def show_text(x, y, text, color="black", size=16):
26
92
  _send({"type": "text", "x": x, "y": y, "text": text, "color": color, "size": size})
27
93
 
28
- def print(text): # 使用print作为函数名,因为调用时使用gui.print()
94
+ def print(text):
29
95
  _send({"type": "print", "text": text})
30
96
 
31
97
  def println(text):
@@ -54,11 +120,18 @@ def clear():
54
120
 
55
121
  def close():
56
122
  """关闭GUI连接"""
57
- global _connection
123
+ global _connection, _sender_thread, _stop_event
124
+ # 设置停止事件
125
+ _stop_event.set()
126
+ if _sender_thread:
127
+ # 等待发送线程退出
128
+ _sender_thread.join(timeout=0.5)
58
129
  if _connection:
59
- _connection.close()
130
+ try:
131
+ _connection.close()
132
+ except:
133
+ pass
60
134
  _connection = None
61
135
 
62
136
  # 注册程序退出时自动关闭连接
63
- import atexit
64
137
  atexit.register(close)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: smartpi
3
- Version: 0.1.12
3
+ Version: 0.1.13
4
4
  Summary: A library use for H2-RCU
5
5
  Author: ZMROBO
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,8 +1,8 @@
1
- smartpi/__init__.py,sha256=ynl00MdZK44BRltFscnxPvaQB9vT8qwdufP2vRovzWc,55
1
+ smartpi/__init__.py,sha256=hSlULYmtHrtLpplBFTQagFL4pXXCSoMgkNVFfklgtzc,55
2
2
  smartpi/base_driver.py,sha256=FmnwZFqKE2HVUsDoqxXigdX1YlElcY07YkLnlvKY_x8,18033
3
3
  smartpi/color_sensor.py,sha256=sTqD3jApjmc6qHMrDyEy2UjaRt8vhJZNR88vzgUiLKs,496
4
4
  smartpi/cw2015.py,sha256=1lAF-pi_ye_ya1AZQS1sjbgsDf7MThO5IAskKsNGBzA,5695
5
- smartpi/gui.py,sha256=VuZEhuM3M-Lz12dpzRhcdLxE8p-Hosdq4wa0jAbnnbc,2165
5
+ smartpi/gui.py,sha256=M0VXAxk9VmW8VXSbbcRfOtZUVigWIDn0pEEYZHMTeI0,4416
6
6
  smartpi/humidity.py,sha256=xtALQ_IlcwR2RCYvopCSmeNajB45kQU_ckk6FZ0rqko,497
7
7
  smartpi/led.py,sha256=n3_k1jGcQptfGXhezDLaYzH6UptgluP4Ze6qP_Y4WmU,536
8
8
  smartpi/light_sensor.py,sha256=kWmoXklYS1QG0eDz4Qn9FF4WueR3GARb3OwQSkXqUNA,569
@@ -12,7 +12,7 @@ smartpi/servo.py,sha256=B6X3yCoEz82qqpUIE5MSO0Eg9YZJ5zDzJEcRpioZpUo,4625
12
12
  smartpi/temperature.py,sha256=px2YeqgG63nPkyhJA1wDg3dwYx_oOCYuhMjtsVm_YO0,460
13
13
  smartpi/touch_sensor.py,sha256=F6IIQGewNRhC9U1RbHpVzuGYqb8H41lpeQ1Ejwsc_T8,438
14
14
  smartpi/ultrasonic.py,sha256=0meczFKXFLUt92kLxipeEc37vb5duvJjPs4kgtlpO8M,622
15
- smartpi-0.1.12.dist-info/METADATA,sha256=0HdhhFfnoSXNc6LVxBdE-zqiKdxdu1U7x7NxGLcAbcU,311
16
- smartpi-0.1.12.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
17
- smartpi-0.1.12.dist-info/top_level.txt,sha256=PoLhUCmWAiQUg5UeN2fS-Y1iQyBbF2rdUlizXtpHGRQ,8
18
- smartpi-0.1.12.dist-info/RECORD,,
15
+ smartpi-0.1.13.dist-info/METADATA,sha256=fyS1LxSRoLa2FGN9JpZ7QYayqJ6zx57Nyt_mTBP6JI0,311
16
+ smartpi-0.1.13.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
17
+ smartpi-0.1.13.dist-info/top_level.txt,sha256=PoLhUCmWAiQUg5UeN2fS-Y1iQyBbF2rdUlizXtpHGRQ,8
18
+ smartpi-0.1.13.dist-info/RECORD,,