Skip to content

Commit

Permalink
Fix API BUG & Update Document
Browse files Browse the repository at this point in the history
  • Loading branch information
noahziheng committed Mar 4, 2018
1 parent a31e0f7 commit 581938f
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 4 deletions.
7 changes: 7 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
- [首页](README.md)
- [快速指南](howtouse/README.md)
- [开发者快速指南](howtouse/README.md)
- [安装](howtouse/README.md#installation)
- [基本使用](howtouse/README.md#basic_usage)
- [数据](howtouse/README.md#data)
- [设备](howtouse/README.md#device)
- [RESTFul API](howtouse/README.md#api)
- [Adapter](howtouse/README.md#adapter)
- [写在最后](howtouse/README.md#end)
- [实例1:MQTT 方案保存温度数据](howtouse/ex1.md)
- [配置文件详解](config.md)
- [RESTFul API](api/README.md)
Expand Down
Empty file added docs/adapter/README.md
Empty file.
6 changes: 6 additions & 0 deletions docs/howtouse/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ DataRef 类型(FreeIOT)用于记录某个数据主题的状态,详细参

## RESTFul API

<span id="api"></span>

由于 FreeIOT 对于 `设备``数据` 的操作支持集成在核心库内,所以,我们现在已经可以通过 HTTP API 进行读写操作了。

FreeIOT 采用 RESTFul API 作为主接口,使用 Flask 提供服务,集成 Flask-RESTFul 进行参数处理,并引入 [JWT](https://jwt.io) 作为认证手段。
Expand Down Expand Up @@ -192,6 +194,8 @@ FreeIOT 采用 RESTFul API 作为主接口,使用 Flask 提供服务,集成

## Adapter

<span id="adapter"></span>

`Adapter` 是使用 FreeIOT 开发物联网系统的最主要形式,可用于建立新的查询接口、建立操作界面、兼容新的数据类型以及最关键的使用“物联网”方式收集、发送数据。

RESTFul API 方式并不适合在设备侧使用,有 HTTP 资源消耗较大,开发繁琐,接口需要鉴权一类的缺点。而专为物联网而生的 MQTT 协议就完全解决了这些问题。
Expand All @@ -215,4 +219,6 @@ MQTTAdpter 是 FreeIOT 官方支持的,包含在 libfreeiot 包内,它的使

## 写在最后

<span id="end"></span>

以上我们简单介绍了 FreeIOT 的基本概念、用法,FreeIOT 的设计目标是一个框架,我们对开发接口(Adapter)、核心接口(RESTFul API)的描述将贯穿整个文档,希望大家能利用 FreeIOT提供的接口方案轻松打造出自己的物联网产品。
115 changes: 115 additions & 0 deletions docs/howtouse/ex1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# 实例1:MQTT 方案保存温度数据

在本文中,我们将带领读者,完成一个小的温度传感器上传温度到 FreeIOT 系统的一个模型。

## 准备工作

首先,建议读者全文阅读 [FreeIOT 快速指南](./README.md),并对使用 Python3 编程具有一定的基础。

其次,我们将用到下列工具:

- curl 命令行工具,用于操作命令行(习惯图形界面的读者可用 Postman 等 GUI 工具代替)
- MQTTBox Chrome 扩展,用于模拟设备侧行为(熟悉 MQTT 编程的读者亦可自行编写 MQTT 客户端代替)
- 最新版本的 libfreeiot 开发库
- 已安装的 MongoDB 数据库

如果您最好对 [MQTT](https://mqtt.org) 有所了解,中文协议推荐阅读 [https://github.com/mcxiaoke/mqtt](https://github.com/mcxiaoke/mqtt)

## MQTT Broker

使用 FreeIOT 开发 MQTT 方案的物联网系统,需要借助特有的 Adapter 机制,官方提供支持的 MQTTAdapter 功能为消息监听器,需要单独配置 MQTT Broker,形如下图:

![Structure of FreeIOT Middleware](../images/howtouse/2.png)

MQTTAdapter 建议使用 [Eclipse Mosquitto](https://mosquitto.org/),这是兼容性最好的选择,当然,使用其他符合 MQTT3 协议的 Broker 都可被兼容。

我在这里已经配置好了一个 Mosquiito,使用 TCP 协议在 1883 端口提供服务。

## 搭建系统

我们首先建立 `.env` 配置文件如下:

```dotenv
# 全局配置
PORT = 3000
DEBUG = false
FLASK_CONFIG = development
MONGO_HOST = localhost
MONGO_PORT = 27017
MONGO_DBNAME = freeiot
# MQTT Adapter 配置
MQTT_HOST = localhost
MQTT_PORT = 1883
MQTT_CLIENTID = "mqtt-guide"
MQTT_PARSE_DRIVER = json
TOPIC_NEEDS = ["tempature"]
```

再建立一个 `manage.py` 启动脚本:

```python
from libfreeiot import app
from libfreeiot.adapters.mqtt import MQTTAdapter

app.run(adapters = [ MQTTAdapter() ])
```

以上我们配置了一个具有 MQTT 功能的 FreeIOT 系统,MQTT Adapter 将在系统启动后介入观察本地 MQTT Broker 中的设备行为,并关注 `tempature` 主题。

> MQTTAdapter 使用的 Paho 库目前与调试模式存在冲突,使用 MQTT 时请关闭调试模式 `DEBUG`,修改代码后手动重启程序。
接下来使用 `python3 manage.py` 即可跑起这个系统。

## 建立设备

我们首先获取 JWT 凭证,FreeIOT 的默认用户名密码为 `admin/admin`,运行以下命令:

```shell
curl http://127.0.0.1:3000/api/auth\
-H "Accept: application/json"\
-H "Content-type: application/json"\
-X POST\
-d '{"username":"admin", "password": "admin"}'
```

可以得到

```json
{
"jwt": "<your jwt token>"
}
```

再运行:

```shell
curl http://127.0.0.1:3000/api/device\
-H "Accept: application/json"\
-H "Content-type: application/json"\
-H "Authorization:Bearer <your jwt token>"\
-X POST\
-d '{"remark": "测试样机", "status": 0, "version": "Unknown"}'
```

可以得到

```json
{
"remark": "\u6d4b\u8bd5\u6837\u673a",
"_id": {
"$oid": "<your device objectid>"
}
}
```

已经熟悉 FreeIOT 的读者可以了解到,我们通过 RESTFul API 接口建立了一个名为“测试样机”的设备,当前不在线,版本未知。

## MQTT 登场

好了,我们的配置部分到此就已经结束了,接下来就是模拟设备的行为,我们首先打开 `MQTTBox` 建立一个 MQTT Client,并修改其连接信息如下:

![MQTTBox Client Config](../images/howtouse/3.png)

我们主要是修改了 ClientId 来保证设备唯一,修改了 MQTT Broker 的连接地址,并配置了一份“遗嘱(will)”来让 FreeIOT 知悉设备的离线。

Binary file added docs/images/howtouse/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/howtouse/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 1 addition & 4 deletions libfreeiot/adapters/mqtt/Parse/sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ def offline(client, device):
d_id = dict(device).get("id")
mongo.db.devices.update_one(
{"_id": ObjectId(d_id)},
{ "$set": {
"status": Constant.Status.STATUS_UNKNOWN,
"power": -1
}
{ "$set": { "status": Constant.Status.STATUS_UNKNOWN }
})
client.publish(dict(device).get("id") + "/status/d", Constant.Status.STATUS_UNKNOWN)
if "TOPICS_NEED" in os.environ:
Expand Down
4 changes: 4 additions & 0 deletions libfreeiot/core/resources/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,16 @@ def post(self, device_id=None):
"""
parser = reqparse.RequestParser()
parser.add_argument('remark', type=str, help='Remark of the device')
parser.add_argument('status', type=int, help='Status of the device')
parser.add_argument('version', type=str, help='Version of the device')
args = parser.parse_args()
if device_id is None:
data = args
data['_id'] = ObjectId()
else:
data["remark"] = args["remark"]
data["status"] = args["status"]
data["version"] = args["version"]
res = mongo.db.devices.save(data)
return Response(
json_util.dumps(data),
Expand Down

0 comments on commit 581938f

Please sign in to comment.