#####一,简介
scratch是一款又麻省理工开发的图形化编程软件,这款软件提供了可以使用javascript与scratch交互的接口,同时提供了一个socket端口和一系列的命令与应用程序交互,这里我们讲解如何通过python与scratch交互
####二,说明
之所以选择python是主要基于以下几个原因:
1,python是非编译性语言,所以除非库的提供者将不想开源的代码写在C/C++,或者java等编译性语言的代码中,然后通过python调用,一般情况下我们是可以看到源代码的
2,scratch 对于使用python与它交互,有现成的python库可以调用,这样我们就不需要详细了解scratch对外定义的繁琐的命令结构,这样没有意义
####三,原理
1,当scratch启动的时候会默认打开本机的42001端口作为服务器端的socket接收应用程序请求(这个port只是默认的,可以修改)
2,我们通过本地socket连接到scratch,然后可以发送一系列的命令与scratch交互,这样我们就能通过scratch图形化编程操作我们希望操作的任何东西,比如硬件
####四,环境配置
说明:我实在ubuntu下面,可以在类似的linux发行版上面都行
1,安装scratch:注意要安装1.4版的,我在自己的机台上面用下面这条命令安装的就是1.4,如果有人安装不是1.4版,我这里暂时不敢保证
sudo apt-get install scratch
2,安装scratch 的python库
sudo apt-get install python-pip scratchpy
3,安装之后在安装目录有一个scratch.py的python脚本,可以查看scratch.py的代码,这个里面提供的通过python操作scratch的所有接口以及命令
####五,scratch.py提供的接口
下面贴出scratch.py在我们这里用到的部分代码:有兴趣的可以看scratch.py的源码
import array
import errno
import itertools
import socket
import struct
class ScratchError(Exception): pass
class ScratchConnectionError(ScratchError): pass
class Scratch(object):
prefix_len = 4
broadcast_prefix_len = prefix_len + len('broadcast ')
sensorupdate_prefix_len = prefix_len + len('sensor-update ')
msg_types = set(['broadcast', 'sensor-update'])
def __init__(self, host='localhost', port=42001):
self.host = host
self.port = port
self.socket = None
self.connected = False
self.connect()
def connect(self):
"""
Connects to Scratch.
"""
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.socket.connect((self.host, self.port))
except socket.error as (err, msg):
self.connected = False
raise ScratchError("[Errno %d] %s" % (err, msg))
self.connected = True
def broadcast(self, msg):
if getattr(msg, '__iter__', False): # iterable
for m in msg:
self._send('broadcast "%s"' % self._escape(str(m)))
print "hjptestfor:",self._escape(str(m))
else: # probably a string or number
self._send('broadcast "%s"' % self._escape(str(msg)))
print "hjptestfor:",self._escape(str(msg))
def receive(self):
return self._parse(self._recv())
1,我们可以看到使用的port端口是42001,是host是“localhost"(说明不支持远端连接),当然我们可以用我们的应用程序做一个跳板,然后远程操作scratch,这都是后话
2,我们也可以将上述代码翻译成其他语言比如C语言等,当然既然已经有了这个库也就没有必要了,有兴趣的作为一种尝试练习
####六,我们的例子
代码如下:
#filename:helloscratch.py
import scratch
try:
s = scratch.Scratch()
if s.connected:
print "Connected to Scratch successfully"
else:
print "Connected to Scratch error"
except scratch.ScratchError:
print "Scratch is not opened or remote sensor connections aren't enabled"
try:
print "broadcast begin"
s.broadcast('hello scratch')
except NameError:
print "Scratch: Unable to Broadcast"
while True:
try:
msg = s.receive()
print "Scratch: receive:",msg
except KeyboardInterrupt:
print "GrovePi Scratch: Disconnected from Scratch"
break
这段代码的主要功能是将scratch发送过来的字符串打印出来,为了操作硬件,我们可以自定义一套命令,比如i2c,address等,当收到这些字符串的时候我们可以在我们的客户端里面操作硬件(当然这个例子里面只是打印)
比如要操作i2c,只需要执行sudo apt-get install python-smbus就可以了,
####七,运行效果
执行:首先手动启动scratch,否则我们的客户端会由于服务器端不在线连接失败
在shell下直接输入:scratch 回车就启动了scratch
然后在shell下运行我们的客户端,就连接到了scratch:
suso python helloscratch.py
这样我们就可以与shell交互了
比如我们加入下面这个模块
当我们点击旗帜的时候scratch图形代码运行,在我们的客户端收到112这个字符串,效果如下:
如果需要操作硬件,可以把在join里面定义自己的命令:在接收到这些命令字符串之后,紧接着操作硬件,这样就起到了操作硬件的效果