Skip to content

Instantly share code, notes, and snippets.

@awong1900
Last active November 26, 2015 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awong1900/055a56cc973c5eba4cfe to your computer and use it in GitHub Desktop.
Save awong1900/055a56cc973c5eba4cfe to your computer and use it in GitHub Desktop.
article

怎么用tornado框架实现一个IOT服务器

How to use tornado implement a Iot Server

众所周知,tornado是一个非常好的非阻塞网络I/O框架,它能支持上万个连接,并支持长轮训,websocket。

The Internet of Things (IoT) is the network of physical objects or "things" embedded with electronics, software, sensors, and network connectivity.

我们想实现的目标是把iot device的功能抽象出来,用API的方式呈现给开发者。 targe

中间的问号部分就是我们想实现的IOT服务器,它能够与device进行通信,并且把device的功能用API的形式展现给开发者,同时它也可以响应开发者的API调用,获取Device数据或者让Device执行某种动作。

连接方式

IOT Device设备,我们选择了ESP8266,它具有wifi连接,并且支持TCP/IP。并且可以驱动其他的开源hardware模块(如Arduino module).

通过Tornado的tornado.tcpserver类,我们保持服务器和Device之间的TCP连接,并保持心跳检测。
通过Tornado的tornado.web类,我们提供主要RESTful API给到开发者。

用户管理和Device管理

我们需要管理用户和它们名下的Device,实际上我们给每个用户和device加上了独一无二的token。同时引入了SQLite,把User token和Device token关联起来。我们用token实现权限控制。用户可以通过API查询属于自己的Device。 user_device_manager

Device读取和操作

理想情况下,我们把device的功能抽象成一个个HTTP methods GET and POST. 这也是IOT server的核心功能。比如Device驱动了一个温度传感器,此时我们应该抽象出一个API:GET temperature. 用户通过这条API即可以得到当前温度。这并不容易做到, 但我们尽可能把它简化了。我们这里定义了一些规则,比如Read,Write函数。像Seeed的Grove module,只需要稍微修改一下原来的Arduino代码即可以抽象出它们的API。 device_read_write

Event处理

一个好的sever应该实现事件处理,它类似一个紧急通知或者是一个实时信息,能让实时通知应用层。我们在服务器实现了event队列,它会对每一个event排队并逐个发送给应用层。我们用websocket来实现这一过程。通过Tornado的tornado.websocket类我们很快做好了服务器端的websocket功能。应用层只需要简单实现websocket调用,即可以实时拿到device的event事件。 event

固件编译和OTA(Over The Air)

除了上述功能外,服务器还实现了一种云端固件编译的方法,用户通过API的方式定义编译哪些module的驱动进入固件,服务器会调用相关的编译链依据配置编译。然后通知device云端下载固件。这需要固件支持OTA升级功能。 这里我们利用了Tornado的长轮训(long-polling)机制来做编译和OTA状态更新。因为编译和下载固件的时间较长,用普通的HTTP请求会造成超时。

数据的安全传输

我们在TCP通信种采用了AES加密,我们自己实现了这种加密方式。 并且API调用采用了https加密,Tornado很容易实现https方式, 例如:

# implementation for SSL
http_server = tornado.httpserver.HTTPServer(application)
TCPServer(ssl_options={
    "certfile": os.path.join("/var/pyTest/keys/", "ca.csr"),
    "keyfile": os.path.join("/var/pyTest/keys/", "ca.key"),
})

不过我们直接使用nginx做https加密,效果是一样的。

数据格式

所有的API请求返回数据格式使用json.它易于使用和理解。 例如:

{
  "status": 200,
  "msg": "OK"
}

最终的架构

Architecture

我们完成了这个轻量级服务器,它是完全开源的。 Github地址:https://github.com/Seeed-Studio/Wio_Link

我们在这个服务器基础上做了一些额外事情:

  1. 我们实现了20+ Grove Sensor 的web API
  2. 我们实现了基于这个服务器的IFTTT channel.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment