# 2.1 房源对接方式的选择
智能设备管理系统开发的第一件事就是需要确定与云丁saas系统房源对接的方式。这里先介绍**房源**的概念:云丁智能设备管理是基于房源为单位的,对应于现实生活中的房源模型。具体说来就是建立一个房源,并且在其中创建房间,然后将相应的智能网关,智能门锁,智能采集器,智能电表和智能水表等添加到对应的房间。因此、智能设备管理也就是基于房源的管理。
商户自行开发的智能设备管理系统与云丁Saas系统进行房源对接的方式主要分为两种:
1. 已有设备,再对接
即:商户在云丁Saas系统先建立房源房间,并且添加设备之后再将云丁系统上的房源以及房源内的设备等数据导入自己的系统,实现系统之间的对接。(已有设备,再对接)
2. 先对接,再装设备(**推荐**)
即:商户先在自己的系统上建立房源房间,然后通过openAPI将自己的房源数据推送给云丁Saas系统;再根据工单模块添加安装工单,云丁交付团队上门安装设备。(先对接,再装设备)
重点推荐先对接,再装设备的方式。因此本文档也将通过先对接,再装设备的方式实现房源对接。
# 2.2 房源房间对接代码实现
根据上面的介绍,我们选择第二种先对接,再装设备的方式进行对接。因此,系统先实现房源的对接。
代码结构如下:
```
SmartDeviceMgrSystem
—apis
—home.py
—room.py
—ticket.py
—home_model.py
—main.py
```
**注意**:由于本文档的目的是让开发者快速了解与云丁系统对接的操作流程,因此房源数据结构采用json格式,不涉及模型的建立与数据库存储的操作。
apis文件夹主要存放调用云丁系统接口的函数,这一章我们完成的功能主要会调用到房源,房间和工单的接口,因此新建三个文件home.py, room.py, ticket.py。
以下是具体的代码示例:
home.py
```
import requests
def add_home(access_token, country, city, zone, location, block, home_id, home_name):
'''
添加房源
params:
access_token: 调用接口凭证
country: 国家
city:城市
zone:区域
location: 具体地址
block: 小区
home_id: 房源id(全局唯一)
home_name: 房源名称
'''
url = 'https://saas-openapi.dding.net/v2/add_home'
headers = {
'Content-type': 'Application/json',
'User-Agent': 'PostmanRuntime/7.13.0',
}
payload = {
'access_token': access_token,
'country': country,
'city': city,
'zone': zone,
'location': location,
'block': block,
'home_id': home_id,
'home_name': home_name
}
response = requests.request('POST', url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()
def get_home_info(access_token, home_id):
'''
获取房源信息
params:
access_token: 调用接口凭证
home_id: 房源id(全局唯一)
'''
url = 'https://saas-openapi.dding.net/v2/get_home_info'
headers = {
'Content-type': 'Application/json',
'User-Agent': 'PostmanRuntime/7.13.0',
}
payload = {
'access_token': access_token,
'home_id' : home_id
}
response = requests.request('POST', url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()
```
room.py
```
import requests
'''
添加房间
'''
def add_rooms(access_token, home_id, rooms):
'''
添加房间
params:
access_token: 调用接口凭证
home_id: 房源id
rooms: list类型 [room1, room2, ... roomn]
'''
url = 'https://saas-openapi.dding.net/v2/add_rooms'
headers = {
'Content-type': 'Application/json',
'User-Agent': 'PostmanRuntime/7.13.0',
}
payload = {
'access_token': access_token,
'home_id': home_id,
'rooms': rooms
}
response = requests.request('POST', url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()
~~~
```
ticket.py
~~~
import requests
'''
添加工单
'''
def add_ticket(access_token, home_id, service_target, service_type, room_ids, subscribe):
'''
添加工单
params:
access_token: 接口调用凭证
home_id: 房源id
service_target: 工单服务对象 1:网关 2:门锁 3:电表
service_type: 工单类型 1:安装 2:售后维修
room_ids: list 需要预约或维修的房间 [room1, room2]
subscribe: 下单人 dict
需包含:date, time, name, phone
date: 预约时间戳 ms
time: 100:全天 101:上午 102:下午
name: 下单人姓名
phone: 下单人联系方式
'''
url = 'https://saas-openapi.dding.net/v2/add_ticket'
headers = {
'Content-type': 'Application/json',
'User-Agent': 'PostmanRuntime/7.13.0',
}
payload = {
'access_token': access_token,
'home_id': home_id,
'service_target': service_target,
'service_type': service_type,
'room_ids': room_ids,
'subscribe': subscribe
}
response = requests.request('POST', url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()
~~~
然后在系统建立房源模型,注意:为了简洁,此处模型并不涉及数据库的操作。vim home_model.py
```
from apis.home import add_home, get_home_info
from apis.room import add_rooms
from apis.ticket import add_ticket
class Home:
def __init__(self, **kwargs):
access_token = kwargs['access_token']
country = kwargs['country']
city = kwargs['city']
zone = kwargs['zone']
location = kwargs['location']
block = kwargs['block']
home_id = kwargs['home_id']
home_name = kwargs['home_name']
res = add_home(access_token, country, city, zone, location, block,
home_id, home_name)
if 'ErrNo' in res:
if res['ErrNo'] == 0:
print('home creating successfully!')
else:
print('home creating failed')
def get_home_info(self, **kwargs):
access_token = kwargs['access_token']
home_id = kwargs['home_id']
res = get_home_info(access_token, home_id)
return res
def add_room(self, **kwargs):
access_token = kwargs['access_token']
home_id = kwargs['home_id']
rooms = kwargs['rooms']
res = add_rooms(access_token, home_id, rooms)
return res
def add_ticket(self, **kwargs):
access_token = kwargs['access_token']
home_id = kwargs['home_id']
service_target = kwargs['service_target']
service_type = kwargs['service_type']
room_ids = kwargs['room_ids']
subscribe = kwargs['subscribe']
res = add_ticket(access_token, home_id, service_target, service_type, room_ids, subscribe)
return res
```
创建Home类,并实现添加房间(add_home),获取房源信息(get_home_info),添加工单(add_ticket)等方法。
## 2.2.1 房源对接
刚刚已经实现了apis的接口函数和home_model,接着便可以在系统创建房源,并且与云丁Saas系统进行对接。vim main.py
```
from home_model import Home
def main():
#创建房源
home_data = {
'access_token' : '6afc3f360e04f806244af07c6c5eca1cee6065e83565e107fc4896b55ce8f735df5bd9a7d3c5e1e2f96f1fdd1c2ea52483ec2e10e5cc38517a17b1d4aff2ceff',
'country' : '中国',
'city' : '深圳',
'zone' : '南山区',
'location' : '深南大道118号',
'block' : '万科一期',
'home_id' : 'testhomeid123',
'home_name' : '18栋1501'
}
home = Home(**home_data)
if __name__ == '__main__':
main()
```
```
```
将需要创建的房源参数组装成Json格式,初始化Home类,成功创建房源。返回结果:
```
home creating successfully!
```
生产环境中需要将home模型存入数据库中,这重在说明实现的方法,因此省略数据库操作。
## 2.2.2 房间对接
接下来,在上述的房源中创建房间,并且与云丁Saas系统对接。vim main.py 其代码示例:
```
room_data = {
'access_token' : '6afc3f360e04f806244af07c6c5eca1cee6065e83565e107fc4896b55ce8f735df5bd9a7d3c5e1e2f96f1fdd1c2ea52483ec2e10e5cc38517a17b1d4aff2ceff',
'home_id' : 'testhomeid123',
'rooms' : [
{
'room_id':'0001',
'room_name':'房间1'
}
]
}
res = home.add_room(**room_data)
print(res)
```
房间成功创建,其返回结果为:
```
{'ReqID': '1SBR3NWtqmY', 'ErrNo': 0, 'ErrMsg': ''}
```
到此,我们实现了房源房间的对接,并且将home_id,room_id等数据都保存下来。
# 2.3 工单模块的实现
在实现了房源房间对接后,便需要安装设备了,因此需要实现工单功能。上面两小节中,我们已经创建了房源,房间并且把房源房间的基本数据,如:home_id, room_id等都保存了下来,接着使用它们建立工单。vim main.py
```
ticket_data = {
'access_token' : '6afc3f360e04f806244af07c6c5eca1cee6065e83565e107fc4896b55ce8f735df5bd9a7d3c5e1e2f96f1fdd1c2ea52483ec2e10e5cc38517a17b1d4aff2ceff',
'home_id' : 'testhomeid123',
'service_target' : 2, #2.门锁
'service_type' : 1, #1.新装工单
'room_ids' : ['0001', 'testhomeid123'],
'subscribe' : {
'date' : 1567094400000,
'time' : 102,
'name' : 'zengjia',
'phone' : '18620190127'
}
}
res = home.add_ticket(**ticket_data)
print(res)
```
工单的接口含义如下:
```
params:
access_token: 接口调用凭证
home_id: 房源id
service_target: 工单服务对象 1:网关 2:门锁 3:电表
service_type: 工单类型 1:安装 2:售后维修
room_ids: list 需要预约或维修的房间 [room1, room2]
subscribe: 下单人 dict
需包含:date, time, name, phone
date: 预约时间戳 ms
time: 100:全天 101:上午 102:下午
name: 下单人姓名
phone: 下单人联系方式
```
添加工单成功后,我们能从返回的结果的ticket_id字段中拿到工单编号
```
{'ReqID': '1SBR3ZfKpV6', 'ErrNo': 0, 'ErrMsg': '', 'ticket_id': 'ISLK1908301908503'}
```
# 2.4 设备安装完成的确定
当添加完工单后,云丁交付团队便会根据工单前往现场安装绑定设备,那么我们如何得知设备已经绑定成功,可以进行管理了呢?主要是两种方式:事件回调与主动轮询。
具体说明之前,先解释下**事件**。当我们对只能设备进行操作时,由于网络IO耗时,所以采取异步操作。当设备操作成功便会将该信息回调给系统,云丁将这种由设备产生的回调称为**事件**,如:绑定事件。
**1**.事件回调,在第一章申请对接的时候便填写过异步事件的回调地址,当有设备事件发生时,云丁系统便会将设备事件回调给商户对接的系统。云丁系统将对商户的回调url发起http请求。商户系统收到http请求之后,解析事件并能够知晓设备已经绑定成功。
**2**. 主动轮询get_home_info下面的devices字段,如果不为空,则说明设备已经添加成功。(注意:这里只是为了演示,并不考虑系统的效率问题,实际生产环境请使用解析事件的方法。)
vim main.py
```
while True:
res = home.get_home_info(**search_data)
if 'result'in res:
if 'devices'in res:
if len(res['result']['devices']) != 0:
for device in res['result']['devices']:
print(device)
break
print('设备添加完毕')
```
当设备都绑定成功后,get_home_info返回的结果如下:
```
{
"ReqID": "1SC5R5uFrIu",
"ErrNo": 0,
"ErrMsg": "",
"result": {
"home_id": "testhomeid123",
"home_name": "18栋1501",
"location": "深南大道118号",
"description": "",
"home_type": 2,
"province": "广东省",
"city": "深圳市",
"zone": "南山区",
"block": "万科一期",
"rooms": [
{
"room_id": "testhomeid123",
"room_name": "公区",
"description": "",
"sp_state": 1,
"install_state": 4
},
{
"room_id": "0001",
"room_name": "房间1",
"description": "",
"sp_state": 1,
"install_state": 4
}
],
"devices": [
{
"type": "lock",
"sn": "lkjl0019180300779045",
"uuid": "8dd9127be919024ba6b2dadd35ea4ff6",
"device_id": 534906033,
"description": "lock01",
"room_id": "testhomeid123",
"onoff": 1,
"is_out": true,
"center_uuid": "ccec6095685126a25213657764f7eb2f",
"model_name": "D2F",
"model": "lk-19",
"power": 94
},
{
"type": "gateway",
"sn": "cnjl0003180100385967",
"uuid": "ccec6095685126a25213657764f7eb2f",
"device_id": 2043770700,
"description": "网关",
"room_id": "testhomeid123",
"onoff": 1,
"is_out": true,
"model_name": "G2",
"model": "cn-03"
},
{
"type": "lock",
"sn": "lkjl0026190002800173",
"uuid": "157c4b2bfc87abe316378b42cde86141",
"device_id": 1632908514,
"description": "lock02",
"room_id": "0001",
"onoff": 1,
"center_uuid": "ccec6095685126a25213657764f7eb2f",
"model_name": "D3",
"model": "lk-26",
"power": 0
}
],
"lease_type": 1
}
}
```
devices字段已经有绑定的设备了。后面还需要安装新设备也是采用相同的方法。
# 2.5 小结
本章节按照先对接,再装设备的方式,完成了智能设备管理系统的房源房间对接以及设备添加。