惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
T
Threatpost
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
PCI Perspectives
PCI Perspectives
T
The Exploit Database - CXSecurity.com
Y
Y Combinator Blog
雷峰网
雷峰网
爱范儿
爱范儿
The Hacker News
The Hacker News
Last Week in AI
Last Week in AI
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
S
Securelist
宝玉的分享
宝玉的分享
L
LangChain Blog
O
OpenAI News
AI
AI
P
Privacy International News Feed
L
LINUX DO - 最新话题
D
DataBreaches.Net
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs
罗磊的独立博客
M
MIT News - Artificial intelligence
Security Archives - TechRepublic
Security Archives - TechRepublic
月光博客
月光博客
博客园 - 【当耐特】
T
Tailwind CSS Blog
C
Cybersecurity and Infrastructure Security Agency CISA
H
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
Jina AI
Jina AI
The Last Watchdog
The Last Watchdog
K
Kaspersky official blog
Webroot Blog
Webroot Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
MyScale Blog
MyScale Blog
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
Recorded Future
Recorded Future
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender Scratch3技术分析之云变量 API(第7篇) [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事
Snap! 中的 MicroBlocks Client 库
种瓜 · 2024-07-04 · via 夜行人

前言

Like many of us, you are a Smalltalker at heart! – John Maloney

Thanks to MicroBlocks and Snap!, we are not homeless –wenjie

在制作完 Snap! 中的 CoCube 库 后, 我发现这个库的大多数工作都是通用的, 我们可以将其用于任何 MicroBlocks 设备!

通过提取出 CoCube 库的通用部分, 得到了 MicroBlocks Client 库.

这篇文章的许多内容与Snap! 中的 CoCube 库重合, MicroBlocks Client 库实质上是通用版本的 CoCube 库.

动机

使用 Snap! 驱动 MicroBlocks 设备, 通常有以下两个动机:

  • 将 Snap! 已有的 AI 库用于 MicroBlocks 设备
  • 在算力更强的上位机中制作高级驱动库(尤其是机器人相关的项目)

思路

构建优秀且可扩展的系统的关键更多的是设计模块之间如何通信,而不仅仅是设计其内部属性和行为 – Alan Kay

由于 Snap! 和 MicroBlocks 都是个人计算精神的产物, 都拥有极为出色的动态性, 我确信可以通过消息传递来实现目标: 在 Snap! 中对 MicroBlocks 设备进行编程. 事实上, MicroBlocks IDE 正是通过消息传递机制与 vm 协作的

我喜欢采用 消息传递 来设计系统之间的互操作机制, 这样做能够最大限度地降低了系统之间的耦合度.

Snap! 中已经存在了用于在 Snap! 和 MicroBlocks 直接传递消息的库:

这个库提供了传递消息的基础功能, 我打算以这个库为基础, 制作 MicroBlocks Client 库, 力求做到:

  1. 用户可以在 Snap! 中获取 MicroBlocks 设备的状态信息(reporter 积木)
  2. 用户可以在 Snap! 中给 MicroBlocks 设备发送指令(command 积木)
  3. 用户只需要在 Snap! 中编程即可, 无需在 Snap! 和 MicroBlocks 中来回切换.
  4. 尽可能好的可扩展性

关于第 1 点: 获取另一个系统的状态信息, 通常有两种方式:

  • push(推) 风格: 一个系统源源不断地向另一个系统广播携带状态数据的消息
  • pull(拉) 风格: 按需查询需要的状态信息, 通常是采用 request-response 风格的通信.
    • RPC/HTTP 是这种风格
    • Dynatalk 是这种风格

MicroBlocks messaging(BLE) 库提供了 PubSub 风格的消息机制, 我打算基于它构建出 dynatalk-over-ble, 然后基于 dynatalk-over-ble(类似dynatalk-over-postmessage) 实现 pull 风格的 MicroBlocks Client 库.

在我们的用例中, 只需要实现单向的 C/S 架构(Snap! 为 client, MicroBlocks 为 server). 所以 dynatalk-over-ble 的复杂性只有常规 dynatalk 的一半, 令人开心的是, 正好计算能力偏弱的 MicroBlocks 那一半极为简单.

实施

前头提到, 我们力求做到:

用户只需要在 Snap! 中编程即可, 无需在 Snap! 和 MicroBlocks 中来回切换.

因此我希望 MicroBlocks 一侧中的代码是完全通用的, 用户只需要刷入这个通用程序, 就不再需要打开 MicroBlocks 平台, 完全在 Snap! 中对设备进行编程

为了做到这点, 我们在 MicroBlocks 中运行这个通用程序:

这段程序负责以下工作:

  • 解释收到的消息, 将消息的语义"接地"到硬件设备的具体功能上. “接地” 工作是使用 call 积木实现的, 它类似其他编程语言中的 eval , 可以动态运行自定义积木和 vm primitive.
    • handle_message 积木用于处理非阻塞式的消息
    • handle_blocking_message 积木用于处理阻塞式的消息

你可以将这个程序视为运行在硬件中的 server, Snap! 则是它的 client. 我们使用了 C/S 架构.

Snap! 一侧

前边提到:

  1. 用户可以在 Snap! 中获取 MicroBlocks 设备的状态信息(reporter 积木)
  2. 用户可以在 Snap! 中给 MicroBlocks 设备发送指令(command 积木)

我们分别展示它们是如何做到的:

对于第 1 点, 获取状态信息(reporter 积木):

对于第 2 点, 发送指令(command 积木):

消息采用纯字符串形式, 携带方法名(自定义积木名字或者 vm primitive)和 参数, 以 , 分隔 , 以下是一个例子: call, <msg-id>, [display:mbPlot], 3, 3

如何使用 MicroBlocks Client 库?

要使用 MicroBlocks Client 库, 只需打开 Snap! 平台即可.

加载 MicroBlocks Client 库,

点击 open MicroBlocks project 积木, 将打开 MicroBlocks 窗口, 连接设备将程序刷入后, 即可断开并关闭 MicroBlocks 窗口.

然后在 Snap! 中开始编程.

FAQ

如何添加更多 MicroBlocks Client?

下载 https://snap.codelab.club/libraries/MicroBlocks-Client.xml. (在浏览器打开, 另存为本地文件)

执行以下操作

  • MicroBlocks-Client.xml 改名为 MicroBlocks-Client2.xml
  • 编辑 MicroBlocks-Client2.xml 文件:
    • 🐰 全部为 🐰2 (vscode 有批量替换功能)
    • _ble_ 全部替换为 _ble2_
  • 将修改获得文件(这是一个示例: https://wwj718.github.io/post/img/MicroBlocks-Client2.xml), 拖拽到 Snap! 里.

以此类推, 你可以添加任意多个 MicroBlocks Client!

使用场景

当有多个 MicroBlocks 设备时, Snap! 非常适合作为 “演示控制台”, 我在这个视频里做了分享

如何同时调试 Snap! MicroBlocks 的代码?

是的, 你可以同时调试软件和硬件侧的代码! 一切都是活性(liveness)的!

你可以在 Snap! MicroBlocks 中同时连接同一个设备, 然后观察消息在它们之间的流动:

如何在 Snap! 的 MicroBlocks 窗口中保存和加载 MicroBlocks 项目?

保存项目

由于 iframe 的限制 , 无法使用菜单中的 Save 按钮打开本地文件.

替代方案: 点击 Copy project url to clipboard, 然后粘贴到浏览器地址栏里, 之后再保存

加载项目

由于 iframe 的限制, 无法使用菜单中的 Open 按钮打开本地文件.

替代方案: 将本地文件直接拖拽到 MicroBlocks 窗口

如何查看 MicroBlocks 支持的 vm primitive?

可以在 ubl 库文件中找到这些 primitive, 它的形式是[a:b], 如 [display:mbPlot]

Peter 在 Discord 上分享了一些例子:

push 风格的版本

MicroBlocks 部分:

这段程序负责以下工作:

  1. 源源不断地将设备的状态 push 出去(when started 积木), 这些状态可以自行扩展. 目前的更新速率是 20 次/秒(可自定义)
  2. 解释收到的消息(handle_message 积木), 将消息的语义"接地"到硬件设备的具体功能上. “接地” 工作是使用 call 积木实现的, 它类似其他编程语言中的 eval , 可以动态运行自定义积木和 vm primitive.

Snap! 示例(点击运行)

值得注意的是, push 版本相比于 pull 版本有以下优势:

  • 速度更快
  • 更简单

如有需要, 可以把它们二者结合.

传递 event

有时候我们想要更精确地传递 event, 可以像 push status 一样 push event, 类似这样:

是否可以制作一个类似的 Python client 库?

本文的设计很容易迁移到 Python 中, 使用我之前为 Python 制作的 microblocks_messaging_librarydynatalk-py 库, 可以很容易地实现跟 MicroBlocks Client 库相同的功能.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# pip install -U microblocks
from microblocks import MicroblocksClient

client = MicroblocksClient()
found_devices = client.discover(timeout=5)
print("found devices:", found_devices)
client.connect("MicroBlocks AZB", timeout=3)

client.display_character('f')

while True:
    tiltX = client.tiltX
    print(tiltX)

记得先往设备里刷入这个程序(和 Snap! 相同)

更多 API 例子参考: notebooks

microblocks 库的源代码

批量连接设备

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from microblocks import MicroblocksClient

client = MicroblocksClient()
found_devices = client.discover(timeout=3) # timeout=5 in windows
print("found devices:", found_devices)
# connect all discovered devices
devices = [MicroblocksClient(i) for i in found_devices]

for index, device in enumerate(devices):
    device.display_character(index)

并行控制多个设备

1
2
3
4
5
6
from concurrent.futures import ThreadPoolExecutor

# Launching parallel tasks: https://docs.python.org/3/library/concurrent.futures.html
with ThreadPoolExecutor() as executor:
    for client in devices:
        executor.submit(client.scroll_text, "hello")

如何为自定义 MicroBlocks 设备制作 Python 库

上述 MicroblocksClient 类是通用的, 要为自定义的 MicroBlocks 设备制作 Python 库, 只需要继承 MicroblocksClient 类, 然后添加自定义方法即可. 参考 CoCube

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from microblocks import MicroblocksClient

class CoCube(MicroblocksClient):

    @property
    def battery(self):
        return int(self.request("Battery Percentage", []))

    @property
    def position_x(self):
        return int(self.request("position_X", []))

    def move_forward(self, speed=50):
        self.request("Move Forward", [speed])

    def move_backward(self, speed=50):
        self.request("Move Backward", [speed])

CoCube Python 库 使用 Hatch 创建, 非常推荐使用 Hatch 来开发和发布 Python 项目.

参考