多门门禁控制器接入

更新时间:2023-06-21 06:38:04下载pdf

本文介绍了涂鸦智慧行业多门门禁控制器接入方案,通过涂鸦边缘网关实现与平台通信的能力。

方案架构

涂鸦提供了接入方案,帮助多门门禁控制器快速接入 涂鸦 IoT 开发平台。多门门禁控制器接入 涂鸦边缘网关 的方案架构如下图所示:
多门门禁控制器接入

多门门禁控制器采用 MQTT 协议接入涂鸦边缘网关,并进行通信。

业务流程

涂鸦 IoT 开发平台边缘网关设备网关同步设备信息激活设备返回结果返回结果云端下发控制指令下发指令返回执行结果返回结果上报设备属性上报设备属性返回处理结果返回结果定时上报设备上下线上报设备上下线涂鸦 IoT 开发平台边缘网关设备网关

设备功能列表

请求类型 设备能力 功能说明 指令类型
1 多门门禁控制器同步指令下发 同步多门门禁控制器信息 下发
2 多门门禁控制器信息上报 多门门禁控制器信息上报 上报
3 添加用户 新增用户信息 下发
4 修改用户 修改用户信息 下发
5 删除用户 删除用户信息 下发
6 添加用户门禁卡 用户门禁卡添加 下发
7 修改用户门禁卡 用户门禁卡修改 下发
8 删除用户门禁卡 用户门禁卡删除 下发
9 远程开门 远程开门 下发
10 门常开/常闭 门常开/常闭 下发
11 生成二维码 生成二维码 下发
12 清空设备数据 清空设备数据 下发
13 设备状态上报 上报设备的上线、离线消息 上报
14 多门门禁控制器通行事件上报 多门门禁控制器通行事件上报 上报
15 上报告警 告警事件上报 上报

对接协议

多门门禁控制器用 MQTT 协议与涂鸦边缘网关进行通信,其中多门门禁控制器做客户端,涂鸦边缘网关做 MQTT 代理(Broker)。

连接认证

  • ip:MQTT Broker 设备的 IP 地址。与涂鸦 IoT 开发平台联调时,由涂鸦提供(默认为边缘网关的 IP)。

  • port:MQTT Broker 设备的端口。与涂鸦 IoT 开发平台联调时,由涂鸦提供(默认为 56301)。

  • clientId:表示多门门禁控制器客户端 ID。

  • username:多门门禁控制器厂商标识,与涂鸦 IoT 开发平台联调时由涂鸦提供。

  • passwordsub(md5(clientId + username), 0, 16)password 生成示例:

    clientId: abcd1***
    username: tuya
    password: sub(md5(clientId + username), 0, 16)-> c88ba730489ed678
    

    ipportclientIdusername 需要提前配置到多门门禁控制器,便于您的多门门禁控制器每次启动都能读取到这些参数,从而连上边缘网关。

多门门禁控制器上报消息 Topic

  • 推送:gateway/multiaccess/out/{clientId}

  • payloadbase64.Encode(aes.encrypt(payload, password))

    消息示例

    password: "f4ae303385f24***"
    payload: `{"t":1655200***,"reqId":"1655200901125274***","reqType":2,"data":{}}`
    secPayload: "WMnpAqV9Diuz9hbhb5U5zMN3jgGubWaPGT3xDbY0QnUDy6B72W9pH0Li/cRN5i17dQnWqWZKnkicTZHv0G6WkKtFoEE6dkho0FhVAXOxNiY="
    

多门门禁控制器订阅消息 Topic

  • 推送:gateway/multiaccess/in/{clientId}

  • payloadbase64.Decode(aes.decrypt(payload, password))

    消息示例

    password: "f4ae303385f24***"
    secPayload: "WMnpAqV9Diuz9hbhb5U5zMN3jgGubWaPGT3xDbY0QnUDy6B72W9pH0Li/cRN5i17dQnWqWZKnkicTZHv0G6WkKtFoEE6dkho0FhVAXOxNiY="
    payload: `{"t":1655200***,"reqId":"1655200901125274***","reqType":1,"data":{}}`
    

消息加密和解密

设备推送和接收的消息要进行 AES 加密及解密:

  • 消息体使用 JSON 进行序列化和反序列化。
  • 加密解密方式:AES-ECB。
  • 加密解密密码:采用连接认证时使用的密码(password)。

加密或解密代码示例

password := "f4ae303385f24***"
payload := `{"t":1655199***,"reqId":"1655199371114618***","reqType":1,"data":null}`
data, err := aes_crypto.AesECBEncrypt([]byte(payload), []byte(password))
fmt.Println(err)
base64str := base64.StdEncoding.EncodeToString(data)
fmt.Println(base64str)

dataE, err := base64.StdEncoding.DecodeString(base64str)
fmt.Println(err)
dataD, err := aes_crypto.AesECBDecrypt(dataE, []byte(password))
fmt.Println(err)
fmt.Println(string(dataD))

设备管理

同步多门门禁控制器信息指令下发

用于多门门禁控制器信息同步,在多门门禁控制器连接上涂鸦边缘网关的 MQTT 服务器后;涂鸦边缘网关将发送设备信息同步指令,多门门禁控制器接收到指令后上报设备信息。

请求参数

参数 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 1,表示同步多门门禁控制器信息。
data Object 业务数据。

消息格式

{
	"t": 159801061***,
	"reqId": 123123***,
	"reqType": 1,
	"data": {}
}

设备信息上报

多门门禁控制器上报设备信息,涂鸦边缘网关会对上报的信息进行新增或更新。

请求参数

参数 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 2,表示设备信息上报。
data Array 业务数据。
+ cid String 多门门禁控制器设备唯一 ID
+ deviceName String 多门门禁控制器设备名称
+ installLocation String 安装地址
+ subDevices Array 多门门禁控制器下门禁子设备的唯一标识

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 2,

    "data": [{
        "cid": "doorId***",
        "deviceName": "一楼大厅",
        "installLocation": "一楼大厅东侧",
        "subDevices": ["1", "2", "3", "4"]
    }]
}

设备控制

用户添加

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 3,表示用户信息添加
cid String 门禁控制器唯一 ID
data Object 业务数据
+subDevices Array 门号
+uid String 用户 ID,不超过 32 个字符
+idCard String 证件 ID,不超过 32 个字符
+phone String 手机号,11 位数字
+beginTime Long 有效期开始时间,13 位时间戳
+endTime Long 有效期结束时间,13 位时间戳
+name String 用户名,不超过 64 个字符

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 3,
    "cid": "doorId***",
    "data": {
        "uid": "21313***",
        "subDevices": ["1", "2", "3", "4"],
        "idCard": "350725***",
        "phone": "188***",
        "beginTime": 1676007834382,
        "endTime": 1676007844382,
        "name": "林**"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 3,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success",
    }
}

用户修改

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 4,表示用户信息修改
cid String 门禁控制器唯一 ID
data Object 业务数据。
+subDevices Array 门号
+uid String 用户 ID,不超过 32 个字符
+idCard String 证件 ID,不超过 32 个字符
+phone String 手机号,11 位数字
+beginTime Long 有效期开始时间,13 位时间戳
+endTime Long 有效期结束时间,13 位时间戳
+name String 用户名,不超过 64 个字符

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 4,
    "cid": "doorId***",
    "data": {
        "subDevices": ["1", "2", "3", "4"],
        "idCard": "350725***",
        "phone": "188***",
        "beginTime": 1676007834382,
        "endTime": 1676007844382,
        "name": "林**",
        "uid": "350715***"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "cid": "doorId***",
   "reqType": 4,
   "data": {
        "success": true,
        "msg": "success",
    }
}

删除用户

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 5,表示用户信息删除
cid String 门禁控制器唯一 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 5,
    "cid": "doorId***",
    "data": {
        "uid": "350715***"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 5,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

用户门禁卡添加

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType =6,表示门禁卡添加
cid String 门禁控制器 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符
+cardNo String 卡号

消息格式

{
  "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 6,
    "cid": "doorId***",
    "data": {
        "uid": "350715***"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 6,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

用户门禁卡修改

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 7,表示门禁卡修改
cid String 多门门禁控制器 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符
+cardNo String 新卡号
+oldCardNo String 老卡号

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 7,
    "cid": "doorId***",
    "data": {
        "uid": "350715***",
  		  "oldCardNo": ,
        "cardNo": ""
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 7,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

门禁卡删除

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 8,表示门禁卡删除
cid String 多门门禁控制器 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符
+cardNo String 卡号

消息格式

{
  "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 8,
    "cid": "doorId***",
    "data": {
        "uid": "350715***",
        "cardNo": ""
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 8,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

远程开门

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 9,表示远程开门
cid String 多门门禁控制器 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符
+doorNo String 门号

消息格式

{
  "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 9,
    "cid": "doorId***",
    "data": {
        "uid": "350715***",
        "doorNo": "1"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 9,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

门常开/常闭

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 10,表示控制门常开或者常闭
cid String 多门门禁控制器 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符
+doorNo String 门号
+type Integer 枚举值(0 恢复正常、1 常开、2 常闭)

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 10,
    "cid": "doorId***",
    "data": {
        "uid": "350715***",
        "doorNo": "1",
        "type": 1
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 10,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

生成二维码

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 11,表示设备生成二维码
cid String 多门门禁控制器 ID
data Object 业务数据。
+uid String 用户 ID,不超过 32 个字符

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 11,
    "cid": "doorId***",
    "data": {
        "uid": "350715***"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 11,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
				"qrcode": "backkdsaodkoke"

    }
}

清空多门门禁控制器数据

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 12,表示清空数据
cid String 多门门禁控制器 ID
data Object 业务数据。
+all Boolean 是否清空全部数据
+person Boolean 是否清空用户数据
+face Boolean 是否清空用户人脸数据
+card Boolean 是否清空卡号数据
+qrcode Boolean 是否清空二维码数据
+passpwd Boolean 是否清空通行密码数据
+other Boolean 是否清空其他数据

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 12,
    "cid": "doorId***",
    "data": {
        "all": true,
        "person": false,
        "face": false,
        "card": false,
        "qrcode": false,
        "passpwd": false,
        "other": false
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 12,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

设备状态上报

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 13,表示设备状态上报
cid String 多门门禁控制器 ID
data Object 业务数据。
+online Integer 枚举值(1 设备离线、2 设备在线)

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 13,
    "cid": "doorId***",
    "data": {
        "online": 2
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 13,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

通行事件上报

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 14,表示通行事件上报
cid String 多门门禁控制器 ID
data Object 业务数据。
+doorNo String 门号
+uid String 用户 ID
+success Integer 0 失败、1 成功
+way String 通行方式 1(卡)/2(密码)/3(⼆维码)/4(⼈脸)/5(指纹)/9(远程)/10(其它)
+t Long 通行时间
+location String 读头位置 0(未知)/1(入口)/2(出口)
+imageUrl String 通行图片 url(支持 jpg 格式)
+cardNo String 卡号,刷卡通行时填写
+temp String 温度(浮点数字符串)

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 14,
    "cid": "doorId***",
    "data": {
        "doorNo": "1",
        "uid": "350715***",
        "success": 1,
        "way": "1",
        "t": 1655275***,
        "location": "1",
        "cardNo": "4132493",
        "temp": "36.8",
        "imageUrl": "https://oss.tuya.com/80/1.jpg"
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 14,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

告警上报

参数名 类型 描述 是否必填
t Long 消息推送时间。
reqId String 请求流水号。推荐 UUID 生成,网关可以根据 reqId 监听本次推送的结果。最大长度为 64 字符。
reqType Integer reqType = 15,表示告警事件上报
cid String 多门门禁控制器 ID
data Object 业务数据。
+alarmId String 告警 ID
+doorNo String 门号
+alarmType Integer 告警类型 1(防拆报警)/2(陌生人报警)/10(其它)
+alarmCont String 告警内容
+imageUrl String 告警图片 url
+t Integer 告警发生时间
+confirmEnable Boolean 报警处理标志,true 为已处理
+extendData String 扩展信息

消息格式

{
    "t": 1655275***,
    "reqId": "16552757***",
    "reqType": 15,
    "cid": "doorId***",
    "data": {
        "doorNo": "1",
        "alarmId": "fsajifasif",
        "alarmType": 2,
        "alarmCont": "陌生人告警",
        "t": 1655275***,
        "imageUrl": "https://oss.tuya.com/80/1.jpg",
        "confirmEnable": false,
        "extendData": ""
    }
}

响应消息格式

{
   "t": 1655275***,
   "reqId": "16552757***",
   "reqType": 15,
   "cid": "doorId***",
   "data": {
        "success": true,
        "msg": "success"
    }
}

应用示例

MQTT 连接示例:

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"log"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

var (
	client mqtt.Client
	pubTopic string
	subTopic string
	password string
)

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	var (
		username = "multiaccess***"
		clientId = "multiaccess"
		broker   = "tcp://ip:port"
	)
	password = string(genSecKey(clientId, username))
	pubTopic = fmt.Sprintf("gateway/multiaccess/out/%s", clientId)
	subTopic = fmt.Sprintf("gateway/multiaccess/in/%s", clientId)

	opts := mqtt.NewClientOptions().SetClientID(clientId).SetUsername(username).SetPassword(password)
	opts = opts.SetAutoReconnect(true).SetCleanSession(true).SetKeepAlive(5 * time.Second).
		SetMaxReconnectInterval(10 * time.Second).
		SetConnectRetry(true).SetConnectRetryInterval(time.Second)

	opts.AddBroker(broker)
	opts.SetOnConnectHandler(func(client mqtt.Client) {
		log.Println("connected")

		client.Subscribe(subTopic, 1, onMessage)
	}).SetConnectionLostHandler(func(client mqtt.Client, err error) {
		log.Println("connect lost")
	})
	client = mqtt.NewClient(opts)
	token := client.Connect()
	if ok := token.WaitTimeout(time.Second * 10); !ok {
		panic("connect timeout")
	}

	for {
	}
}

func onMessage(client mqtt.Client, msg mqtt.Message) {
	log.Printf("onmessage, topic:%v, messageId:%v, msg: %+v\n", msg.Topic(), msg.MessageID(), string(msg.Payload()))
	// TODO 消息处理逻辑
}

// publish 消息发送
func publish(payload []byte) error {
	token := client.Publish(pubTopic, 1, true, payload)
	log.Println(token)
	return nil
}

func genSecKey(clientID, userName string) []byte {
	secKey := genMd5(clientID + userName)[:16]
	return []byte(secKey)
}

func genMd5(source string) (md5str string) {
	md5Ctx := md5.New()
	md5Ctx.Write([]byte(source))
	cipherStr := md5Ctx.Sum(nil)
	md5str = hex.EncodeToString(cipherStr)
	return
}