Skip to content

Commit e1c6a3a

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 6f2c559 + cac31a2 commit e1c6a3a

File tree

8 files changed

+172
-32
lines changed

8 files changed

+172
-32
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# codelab_adapter_extensions
2-
[codelab-adapter](https://codelab-adapter-docs.codelab.club/) extensions.
2+
![](https://adapterv2.codelab.club/img/toys_party.jpeg)
33

4-
[codelab-adapter](https://codelab-adapter-docs.codelab.club/)[Scratch3 Lab](https://blog.just4fun.site/Scratch3-Lab.html)的一个子项目, 它也是[codelab.club](https://blog.just4fun.site/about-codelab-club.html)希望贡献给社区的一个基础设施。
4+
[Codelab Adapter](https://adapterv2.codelab.club/) extensions.
55

6-
Scratch3 Lab是一个将Scratch3.0接入开源硬件及AI的实验项目(Scratch3 Lab: connect Scratch3.0 to open-source hardware and AI)
6+
CodeLab Adapter 是由[CodeLab](https://www.codelab.club/)构建的基础项目(v2 是最新版本),致力于连接万物,无论是软件还是硬件,无论是 AI、开源硬件、现实世界的物体、还是虚拟世界的动画角色,在 CodeLab Adapter 的驱动下,皆可彼此互动
77

8-
我们的目标是使万物积木化。 这是一些[演示案例](https://codelab-adapter-docs.codelab.club/user_guide/gallery/)
8+
目前,我们在 CodeLab Neverland 中使用 CodeLab Adapter。CodeLab Neverland 是一个由 CodeLab Adapter 驱动的可编程空间,空间里的所有事物皆可编程

extensions_v2/extension_blender.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from codelab_adapter.core_extension import ControllerExtension
2+
from codelab_adapter.utils import get_server_file_path
3+
4+
5+
class BlenderControllerExtension(ControllerExtension):
6+
'''
7+
use to control VectorNode(server)
8+
'''
9+
10+
def __init__(self):
11+
super().__init__()
12+
self.server_extension_id = "eim/blender"
13+
self.EXTENSION_ID = f"{self.server_extension_id}/control" # default eim
14+
# 分布式的节点,手动启动
15+
self.server_file = None
16+
17+
18+
export = BlenderControllerExtension

extensions_v2/extension_eim.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,11 @@ class EIMExtension(Extension):
1212

1313
def __init__(self):
1414
super().__init__()
15-
self.EXTENSION_ID = "eim"
15+
self.EXTENSION_ID = "eim" # after super
1616

1717
def extension_message_handle(self, topic, payload):
18-
# print(topic, payload, type(payload))
19-
if type(payload) == str:
20-
self.logger.info(f'scratch eim message:{payload}')
21-
return
22-
elif type(payload) == dict:
23-
self.logger.info(f'eim message:{payload}')
24-
self.publish({"payload": payload})
18+
self.logger.info(f'eim message:{payload}')
19+
self.publish({"payload": payload})
2520

2621
def run(self):
2722
'''
@@ -30,7 +25,7 @@ def run(self):
3025
i = 0
3126
while self._running:
3227
message = self.message_template()
33-
message["payload"]["content"] = str(i) # topic可选
28+
message["payload"]["content"] = str(i)
3429
self.publish(message)
3530
time.sleep(1)
3631
i += 1
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import time
2+
from codelab_adapter.core_extension import Extension
3+
4+
5+
class HelloWorldExtension(Extension):
6+
def __init__(self):
7+
super().__init__()
8+
self.EXTENSION_ID = "eim"
9+
10+
def send_message_to_scratch(self, content):
11+
message = self.message_template()
12+
message["payload"]["content"] = content
13+
self.publish(message)
14+
15+
def extension_message_handle(self, topic, payload):
16+
self.logger.info(f'the message payload from scratch: {payload}')
17+
content = payload["content"]
18+
if type(content) == str:
19+
content_send_to_scratch = content[::-1] # 反转字符串
20+
self.send_message_to_scratch(content_send_to_scratch)
21+
22+
def run(self):
23+
while self._running:
24+
time.sleep(1)
25+
26+
export = HelloWorldExtension

extensions_v2/extension_robot_xy.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import time
2+
import random
3+
from codelab_adapter.core_extension import Extension
4+
5+
6+
class RobotXYExtension(Extension):
7+
def __init__(self):
8+
super().__init__()
9+
self.EXTENSION_ID = "eim/robot"
10+
11+
def extension_message_handle(self, topic, payload):
12+
self.logger.debug(f'the message payload from scratch: {payload}')
13+
content = payload["content"]
14+
if type(content) == dict:
15+
x = content["x"]
16+
y = content["y"]
17+
self.logger.info(f'x:{x}; y:{y}')
18+
19+
def run(self):
20+
while self._running:
21+
message = self.message_template()
22+
random_x = random.randint(-240,240)
23+
random_y = random.randint(-180,180)
24+
message["payload"]["content"] = {"x":random_x, "y":random_y}
25+
self.publish(message)
26+
time.sleep(1)
27+
28+
export = RobotXYExtension
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import time
2+
from codelab_adapter.core_extension import Extension
3+
4+
5+
class SyncHelloWorldExtension(Extension):
6+
def __init__(self):
7+
super().__init__()
8+
self.EXTENSION_ID = "eim"
9+
10+
def send_message_to_scratch(self, payload):
11+
message = self.message_template()
12+
message["payload"] = payload
13+
self.publish(message)
14+
15+
def extension_message_handle(self, topic, payload):
16+
self.logger.info(f'the message payload from scratch: {payload}')
17+
content = payload["content"]
18+
if type(content) == str:
19+
content_send_to_scratch = content[::-1] # 反转字符串
20+
time.sleep(1)
21+
payload["content"] = content_send_to_scratch
22+
self.send_message_to_scratch(payload)
23+
24+
def run(self):
25+
while self._running:
26+
time.sleep(1)
27+
28+
export = SyncHelloWorldExtension

extensions_v2/extension_wechat.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
'''
2-
构建2个管道
3-
'''
41
import itchat, time
52
from itchat.content import TEXT
63
import zmq
@@ -11,15 +8,11 @@
118

129
codelab_adapter_dir = pathlib.Path.home() / "codelab_adapter"
1310

14-
class WechatGateway(Extension):
15-
'''
16-
todo 作为网关
17-
使用插件来启停它
18-
'''
1911

12+
class WechatGateway(Extension):
2013
def __init__(self):
2114
super().__init__()
22-
self.EXTENSION_ID = "eim/wechat" # 放在内部
15+
self.EXTENSION_ID = "eim/wechat"
2316
self.quit_code = "quit!"
2417

2518
def extension_message_handle(self, topic, payload):
@@ -36,8 +29,8 @@ def extension_message_handle(self, topic, payload):
3629
if type == 'user':
3730
user2SendMessage = itchat.search_friends(nickName=username)[0]
3831
user2SendMessage.send(text)
39-
except:
40-
pass
32+
except Exception as e:
33+
self.logger.error(str(e))
4134

4235
def run(self):
4336
self.wechat_run_as_thread()
@@ -66,34 +59,33 @@ def text_reply(self, msg):
6659
"content": content,
6760
}
6861
self.publish(message)
69-
except:
70-
pass
62+
except Exception as e:
63+
self.logger.error(str(e))
7164

7265
# 群消息
7366
def group_text_reply(self, msg):
7467
'''
7568
将群消息发往scratch
7669
'''
77-
70+
7871
content = msg.text
7972
username = msg.actualNickName
8073
try:
8174
# 群消息有时候会有问题 msg.User.NickName不存在
8275
group_name = msg.User.NickName
8376
except:
8477
return
85-
# todo 主动发信息 第一条信息发两次
8678
try:
87-
# 如果有groupname就是群消息
79+
# groupname: 群消息
8880
message = {}
8981
message["payload"] = {
9082
"username": username,
9183
"content": content,
9284
"groupname": group_name
9385
}
9486
self.publish(message)
95-
except:
96-
pass
87+
except Exception as e:
88+
self.logger.error(str(e))
9789

9890
@threaded
9991
def wechat_run_as_thread(self):
@@ -106,7 +98,8 @@ def wechat_run_as_thread(self):
10698
itchat.msg_register(TEXT, isGroupChat=True)(self.group_text_reply)
10799
itchat.auto_login(
108100
True, picDir=picDir, statusStorageDir=statusStorageDir)
109-
itchat.run(True)
101+
itchat.run(True) # todo 提示有些账号无法登录
102+
110103

111104
export = WechatGateway
112105

servers_v2/blender_server.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# pip3 install codelab_adapter_client # blender
2+
from io import StringIO
3+
import contextlib
4+
import sys
5+
import time
6+
7+
from codelab_adapter_client import AdapterNode
8+
from codelab_adapter_client.utils import threaded
9+
import bpy
10+
from loguru import logger
11+
12+
13+
class BlenderNode(AdapterNode):
14+
def __init__(self):
15+
super().__init__()
16+
self.EXTENSION_ID = "eim/blender"
17+
18+
@contextlib.contextmanager
19+
def stdoutIO(self, stdout=None):
20+
old = sys.stdout
21+
if stdout is None:
22+
stdout = StringIO()
23+
sys.stdout = stdout
24+
yield stdout
25+
sys.stdout = old
26+
27+
def extension_message_handle(self, topic, payload):
28+
python_code = payload["content"]
29+
logger.info(f'python_code: {python_code}')
30+
# extension_python_kernel.py
31+
try:
32+
with self.stdoutIO() as s:
33+
exec(python_code)
34+
output = s.getvalue()
35+
except Exception as e:
36+
output = e
37+
payload["content"] = str(output)
38+
message = {"payload": payload}
39+
self.publish(message)
40+
41+
def exit_message_handle(self, topic, payload):
42+
self.terminate()
43+
44+
@threaded
45+
def run(self):
46+
while self._running:
47+
time.sleep(0.5)
48+
49+
50+
node = BlenderNode()
51+
node.receive_loop_as_thread()
52+
# node.run()

0 commit comments

Comments
 (0)