1 驱动目的

使用驱动开发http跨平台,跨语言,跨设备之间的通信。

2 HTTP协议

HTTP超文本传输协议 (HTTP-Hypertext transfer protocol),是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。它是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。

3 驱动代码

#coding=utf-8
import sys
import time
sys.path.append("..")
from driver import *
import datetime
import requests
import json
reload(sys)
sys.setdefaultencoding('utf8')

url = 'https://lock.keenzy.cn:88/info'
edate = datetime.date.today() + datetime.timedelta(days=1)
sdate = str(datetime.datetime.now().strftime('%Y-%m')) + "-01"

#获取token ->传入用户名和密码 ->返回token和刷新token的令牌refreshentoken
def GetToken(self):
    basePath='/login/1/gettoken'
    data={
        'userlogin':self.cq_username,
        'password':self.cq_password
    }
    """print url+basePath+'?userlogin="'+userlogin+'"'+'&password="'+password+'"'
    res = requests.post(url=url+basePath+'?userlogin='+userlogin+'&password='+password)  拼接"""
    res=requests.post(url=url+basePath,data=data)
    r=json.loads(res.text)
    print res
    return r['result']['token'],r['result']['refreshentoken']

#更新token ->传入刷新token的令牌refreshentoken ->返回响应信息
def refToken(refreshentoken):
    basePath='/login/2/refreshentoken'
    data = {
        "refreshentoken":refreshentoken
    }
    res = requests.post(url=url + basePath, data=data)
    r = json.loads(res.text)
    print res
    return r

#无线门锁列表查询 ->传入页码、每页数量、用户token和房间位置或者唯一ID(非必要) ->返回响应信息
def QueryDoor(self, page,rows,token):
    basePath = '/lock/1/getdevicelock'
    data = {
        "page": page,
        "rows": rows,
        "token":token,
        "serch": ''
    }
    try:
        res = requests.post(url=url + basePath, data=data)
        # self.debug(res)
        r = json.loads(res.text)
    except Exception,e:
        pass
    for data in r['result']['data']:
        # 寻找到roomid对应的数据
        if data["roomid"] == self.cq_roomid:
            # 上传数据
            self.cq_roomlocation = data['details']['roomlocation']
            self.setValue(u'门锁号', data['roomid'])
            self.setValue(u'门锁状态', data['roomstate'])
            self.setValue(u'网关通讯ID', data['gatewaycode'])
            self.setValue(u'门锁通讯ID', data['roomcode'])
            self.setValue(u'门锁唯一ID', data['roomcode2'])
            self.setValue(u'门锁位置', data['details']['roomlocation'])
            self.setValue(u'电量', data['details']['roomcharge'])
            self.setValue(u'roomissyso', data['details']['roomissyso'])
            self.setValue(u'门锁强锁状态', data['details']['roomforcelock'])
            self.setValue(u'门锁工作模式', data['details']['roomworkmode'])
            self.setValue(u'最近在线时间', data['details']['lastactivedate'])
            self.setValue(u'门锁类型', data['details']['roommodel'])
            self.setValue(u'建筑号', data['buildid'])
            self.setValue(u'网关类型', data['gatewaytype'])
            self.setValue(u'roomid', "")
            #防止开关状态被重复刷新
            for key, lock_value in self.data2attrs.items():  # 拿出数据点的键和值
                if "private" in lock_value['config']['param']:
                    if lock_value['config']['param']['private'] == 'lock':
                        self.lockkey = key
                        self.debug(self.lockkey)
                        if "memoryvalue" not in self.data2attrs[key]:
                            self.setValue(u'开关门', 0)
                        else:
                            self.setValue(u'开关门', self.data2attrs[key]["memoryvalue"])
                    if lock_value['config']['param']['private'] == 'face':
                        self.facekey = key
                        self.debug(self.facekey)
                        if "memoryvalue" not in self.data2attrs[key]:
                            self.setValue(u'操作人脸', '下发格式为facecode,type')
                        else:
                            self.setValue(u'操作人脸', self.data2attrs[key]["memoryvalue"])
        print "-------------------------------------------"

#无线门锁列表查询 -> 传入时无roomid数据,则默认返回第一条数据,且返回的roomid为全部roomid拼接 ->返回响应信息
def QueryEmptyDoor(self, page,rows,token):
    basePath = '/lock/1/getdevicelock'
    data = {
        "page": page,
        "rows": rows,
        "token":token,
        "serch": ''
    }
    res = requests.post(url=url + basePath, data=data)
    r = json.loads(res.text)
    roomID = ""
    for data in r['result']['data']:
        roomID += data['roomid']
        roomID += "  "
    print "-------------------------------------------"
    # 上传数据
    self.cq_roomlocation = r['result']['data'][0]['details']['roomlocation']
    self.cq_roomid = r['result']['data'][0]['roomid']
    self.setValue(u'门锁号', r['result']['data'][0]['roomid'])
    self.setValue(u'门锁状态', r['result']['data'][0]['roomstate'])
    self.setValue(u'网关通讯ID', r['result']['data'][0]['gatewaycode'])
    self.setValue(u'门锁通讯ID', r['result']['data'][0]['roomcode'])
    self.setValue(u'门锁唯一ID', r['result']['data'][0]['roomcode2'])
    self.setValue(u'门锁位置', r['result']['data'][0]['details']['roomlocation'])
    self.setValue(u'电量', r['result']['data'][0]['details']['roomcharge'])
    self.setValue(u'roomissyso', r['result']['data'][0]['details']['roomissyso'])
    self.setValue(u'门锁强锁状态', r['result']['data'][0]['details']['roomforcelock'])
    self.setValue(u'门锁工作模式', r['result']['data'][0]['details']['roomworkmode'])
    self.setValue(u'最近在线时间', r['result']['data'][0]['details']['lastactivedate'])
    self.setValue(u'门锁类型', r['result']['data'][0]['details']['roommodel'])
    self.setValue(u'建筑号', r['result']['data'][0]['buildid'])
    self.setValue(u'网关类型', r['result']['data'][0]['gatewaytype'])
    self.setValue(u'roomid', roomID)

#获取开门记录
def OpendoorRecord(self, page,rows,token,sdate,edate):
    basePath = '/analysis/lockrecord/1/getlockrecord'
    data = {
        "page": page,
        "rows": rows,
        "token": token,
        "sdate": sdate,
        "edate": edate
    }
    res = requests.post(url=url + basePath, data=data)
    r = json.loads(res.text)
    for data in r['result']['data']:
        if data['roomlocation'] == self.cq_roomlocation:
            self.setValue(u'开门方式', data['unlockingtype'])
            self.setValue(u'开门时间', data['unlockingdate'])
            self.setValue(u'开门者姓名', data['personname'])
            self.setValue(u'开门者编号', data['personcode'])
            self.setValue(u'开门者所属', data['personlocation'])
            self.setValue(u'卡类型', data['cardtype'])
            self.setValue(u'卡编号', data['cardcode'])
            break
        else:
            continue

#远程开门 ->传入房间id、用户token ->返回响应信息
def OpenDoor(roomid,token):
    basePath = '/lockorder/3/remoteopenlock'
    data = {
        "roomid": roomid,
        "token":token,
    }
    res = requests.post(url=url + basePath, data=data)
    r = json.loads(res.text)
    print r['resultMsg']

#远程关门 ->传入房间id、用户token ->返回响应信息
def CloseDoor(roomid,token):
    basePath = '/lockorder/7/remotecloselock'
    data = {
        "roomid": roomid,
        "token":token,
    }
    res = requests.post(url=url + basePath, data=data)
    r = json.loads(res.text)
    print r['resultMsg']

#人脸列表
def ListFace(self,page,rows,token,search):
    basePath = '/face/manage/listFace'
    data = {
        "page": page,
        "rows": rows,
        "search": search,
        "token": token

    }
    res = requests.post(url=url + basePath, json=data)
    r = json.loads(res.text)
    facecode=""
    for data in r['result']['data']:
        facecode+=data['facecode']
        facecode+=','
    # self.debug(facecode)
    self.setValue(u'人脸列表',facecode)

#操作人脸 ->传入人脸编号,用户token和操作类型(1停用,2启用,3删除,4同步)
def ManageFace(facecode,token,type):
    basePath = '/face/manage/manageFace'
    data = {
        "facecode": facecode,
        "type": type,
        "token": token
    }
    res = requests.post(url=url + basePath, json=data)
    # r = json.loads(res.text)

class gatelockDriver(IOTOSDriverI):
    # 1、通信初始化
    def InitComm(self, attrs):
        try:
            self.cq_username = self.sysAttrs['config']['param']['username']
            self.cq_password = self.sysAttrs['config']['param']['password']
            self.cq_roomid = self.sysAttrs['config']['param']['roomid']
        except Exception, e:
            self.online(False)
        self.setPauseCollect(False)
        self.setCollectingOneCircle(False)
        self.online(True)

    # 2、采集引擎回调,可也可以开启,也可以直接注释掉(对于主动上报,不存在遍历采集的情况)
    def Collecting(self, dataId):
        try:
            # 获取token
            token, refreshentoken = GetToken(self)
            # 传输当前门锁数据
            if self.sysAttrs['config']['param']['roomid'] == "":
                QueryEmptyDoor(self, 1, 100, token)
            else:
                QueryDoor(self, 1, 100, token)
            # 获取门锁记录
            OpendoorRecord(self, 1,100,token,sdate, edate)

            #获取人脸的列表
            ListFace(self, 1, 100, token, '')
        except Exception, e:
            self.debug(u'数据上传失败' + e.message)
        time.sleep(18)
        return ()

    # 3、控制
    # 广播事件回调,其他操作访问
    def Event_customBroadcast(self, fromUuid, type, data):
        print("")
        return json.dumps({'code':0, 'msg':'', 'data':''})

    # 4、查询
    # 查询事件回调,数据点查询访问
    def Event_getData(self, dataId, condition):

        return json.dumps({'code':0, 'msg':'', 'data':''})

    # 5、控制事件回调,数据点控制访问
    def Event_setData(self, dataId, value):
        token, refreshentoken = GetToken(self)
        #对门锁进行远程开门和关门
        if dataId==self.lockkey:
            if value==1:
                if self.cq_roomid!="":
                    try:
                        OpenDoor(self.cq_roomid,token)
                        self.setValue(u'开关门',1)
                        self.setValue(u'下发信息提示',"远程开门成功!")
                    except Exception,e:
                        self.setValue(u'下发信息提示', "远程开门失败!")
                else:
                    pass
            else:
                if self.cq_roomid!="":
                    try:
                        CloseDoor(self.cq_roomid,token)
                        self.setValue(u'开关门', 0)
                        self.setValue(u'下发信息提示', "远程关门成功!")
                    except Exception, e:
                        self.setValue(u'下发信息提示', "远程关门失败!")
                else:
                    pass
        #对人脸数据进行操作
        if dataId==self.facekey:
            try:
                ManageFace(value.split(',')[0],token,value.split(',')[1])
                self.setValue(u'操作人脸', value)
                # 操作类型(1停用,2启用,3删除,4同步)
                if value.split(',')[1] == "1":
                    self.setValue(u'下发信息提示', value.split(',')[0] + "停用操作成功!")
                elif value.split(',')[1] == "2":
                    self.setValue(u'下发信息提示', value.split(',')[0] + "启用操作成功!")
                elif value.split(',')[1] == "3":
                    self.setValue(u'下发信息提示', value.split(',')[0] + "删除操作成功!")
                elif value.split(',')[1] == "4":
                    self.setValue(u'下发信息提示', value.split(',')[0] + "同步操作成功!")
                else:
                    self.setValue(u'操作人脸', '下发格式为facecode,type')
                    self.setValue(u'下发信息提示', "人脸操作失败!请检查格式是否正确!")
            except Exception,e:
                self.setValue(u'操作人脸', '下发格式为facecode,type')
                self.setValue(u'下发信息提示', "人脸操作失败!请检查格式是否正确!")
                return json.dumps({'code': 0, 'msg': '', 'data': e.message})


        return json.dumps({'code':0, 'msg':'', 'data':''})

    # 6、本地事件回调,数据点操作访问
    def Event_syncPubMsg(self, point, value):
        return json.dumps({'code':0, 'msg':'', 'data':''})

4 代码解析

4.1、导入相应的包,运行环境为python2.7

import sys
import time
sys.path.append("..")
from driver import *
import datetime
import requests
import json

4.2、获取存放在中台的数据

class gatelockDriver(IOTOSDriverI):
    # 1、通信初始化
    def InitComm(self, attrs):
        try:
            self.cq_username = self.sysAttrs['config']['param']['username']
            self.cq_password = self.sysAttrs['config']['param']['password']
            self.cq_roomid = self.sysAttrs['config']['param']['roomid']
        except Exception, e:
            self.online(False)
        self.setPauseCollect(False)
        self.setCollectingOneCircle(False)
        self.online(True)

4.3、根据协议获取数据将其展示到数据中台的数据点中

图片名称
图片名称

4.4、下发数据点数值如下

图片名称

5 使用示例

以中安易科的门锁为例,使用的是智慧物联管理平台的API。对于中台的具体操作流程可以参考开发时间 -> HelloWorld,这里只简述了大概的步骤

  • 5.1 创建模板

    依次点击【系统设备】->【模板驱动】->【我的模板】,点击右上角创建模板。详见系统设备管理-模板驱动,中安易科的驱动模板示例如下,三个参数为智慧物联管理平台的账号密码和门锁所在的roomid,roomid可以先不填,到数据出来后再填写上去:

  • 5.2 创建网关

    依次点击【系统设备】->【通信网关】,点击右上角创建网关。详见系统设备管理-通信网关。填写网关名称即可,这里我创建了我自己中台的网关实例,方便大家理解

  • 5.3 创建设备

    依次点击【系统设备】 -> 【通信网关】 -> 【设备实例】,点击右上角创建设备实例。详见系统设备管理-设备实例。填写设备名称,选择刚才创建的网关和模板即可(检查一下驱动根配置的“driver”参数,若在创建模板时已按要求配置,则现在无需修改,否则则需要在此进行配置,配置标准见创建模板),这里我创建了我自己中台的设备实例,方便大家理解

  • 5.4 创建数据点

  • 创建数据点,点击【我的设备】 -> 【通信网关】 -> 【设备实例】 -> 【数据点】,并在【设备实例】下拉列表选择刚刚创建的设备实例,然后进行数据点的创建。需要创建的数据如下详见系统设备管理-数据点注:运行驱动时先删除系统自带的那四个数据点(设备持续在线时长、网关持续运行时长、设备网络状态、网关网络状态)

    其中需要给两个数据点设置私有属性,分别是开关门、操作人脸。设置方式:依次点击该数据点【编辑】->【高级配置】。配置参数如下:
    开关门


    操作人脸

  • 5.5 运行驱动

    方式一:在SDK目录下的_example文件夹下建立一个.bat文件,建立完成后双击进行运行

    方式二:点击中台【系统设备】->【通信网关】,选择刚刚创建好的网关,点击高级,开启云网关,密码为账户密码。

  • 5.6 查看数据


  • 5.7 下发

    点击采集开关右侧的下发按钮,将开关设置为开启,即可远程开关门锁。

    后台画面

    中台情况

作者:admin  创建时间:2021-10-12 09:51
最后编辑:IOTOS  更新时间:2023-11-29 09:38