thingsboard 和tb-gateway 是通过源码idea启动测试开发
为了测试这里只是买了臻识道闸的摄像机模组方便调试,然后添加一个开关量开关模拟雷达
道闸品牌
臻识C3R3C5R5变焦500万车牌识别相机高速追逃费相机华厦V86像机
淘宝地址 https://item.taobao.com/item.htm?_u=s1thkikq47ab&id=705371091697&spm=a1z09.2.0.0.2fe72e8dxewbm6
了解道闸协议
这里通过mqtt进行通信,下面是臻识道闸的mqtt通信协议,这里只是截图用到的部分
道闸识别车牌结果发送topic
车牌识别topic ${sn}/device/message/up/ivs_result
下发设备io事件开闸
开闸topic ${sn}/device/message/down/gpio_out
thingsboard 设置
1.在平台添加一个网关,设置为网关
配置iot gateway 并且启动
-
修改iot gateway 配置文件路径:thingsboard_gateway/config/tb_gateway.json
设置host 为thingsboard服务器的mqtt地址
-
复制网关token到gateway配置
粘贴到accessToken
-
开启gprc
-
添加mqtt配置引用
下面是总的配置文件不要直接复制我的,token不一样
{
"thingsboard": {
"host": "127.0.0.1",
"port": 1883,
"remoteShell": false,
"remoteConfiguration": true,
"statistics": {
"enable": true,
"statsSendPeriodInSeconds": 3600
},
"deviceFiltering": {
"enable": false,
"filterFile": "list.json"
},
"maxPayloadSizeBytes": 1024,
"minPackSendDelayMS": 200,
"minPackSizeToSend": 500,
"checkConnectorsConfigurationInSeconds": 60,
"handleDeviceRenaming": true,
"security": {
"type": "accessToken",
"accessToken": "QWk7kMTZsdjQC8nVEo7f"
},
"qos": 1,
"checkingDeviceActivity": {
"checkDeviceInactivity": false,
"inactivityTimeoutSeconds": 200,
"inactivityCheckPeriodSeconds": 500
}
},
"storage": {
"type": "memory",
"read_records_count": 100,
"max_records_count": 100000,
"data_folder_path": "./data/",
"max_file_count": 10,
"max_read_records_count": 10,
"max_records_per_file": 10000,
"data_file_path": "./data/data.db",
"messages_ttl_check_in_hours": 1,
"messages_ttl_in_days": 7
},
"grpc": {
"enabled": true,
"serverPort": 9595,
"keepaliveTimeMs": 10000,
"keepaliveTimeoutMs": 5000,
"keepalivePermitWithoutCalls": true,
"maxPingsWithoutData": 0,
"minTimeBetweenPingsMs": 10000,
"minPingIntervalWithoutDataMs": 5000,
"keepAliveTimeMs": 10000,
"keepAliveTimeoutMs": 5000
},
"connectors": [
{
"name": "MQTT Broker Connector",
"type": "mqtt",
"configuration": "mqtt.json"
}
]
}
- 启动一个 mqtt broker,这里用docker 启动
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.3.2
- 配置mqtt.json
5.1 配置文件路径:thingsboard_gateway/config/mqtt.json
修改成你自己启动的mqtt broker
5.2 在"mapping"[]里面添加下面配置
这个/device/message/up/ivs_result 是臻识道闸车牌识别topic
timeseries内的是重新组合设备数据
eventType 字段是事件触发类型1代表是车牌识别
license 车牌 base64加密
full_image_content 车牌拍照图片 base64加密
{
"topicFilter": "/device/message/up/ivs_result",
"converter": {
"type": "json",
"deviceNameJsonExpression": "${sn}",
"deviceTypeJsonExpression": "臻识道闸设备配置",
"sendDataOnlyOnChange": false,
"timeout": 60000,
"attributes": [
],
"timeseries": [
{
"type": "string",
"key": "eventType",
"value": "1"
},
{
"type": "string",
"key": "id",
"value": "${id}"
},
{
"type": "string",
"key": "sn",
"value": "${sn}"
},
{
"type": "string",
"key": "name",
"value": "${name}"
},
{
"type": "string",
"key": "version",
"value": "${version}"
},
{
"type": "long",
"key": "timestamp",
"value": "${timestamp}"
},
{
"type": "string",
"key": "license",
"value": "${payload.AlarmInfoPlate.result.PlateResult.license}"
},
{
"type": "string",
"key": "full_image_content",
"value": "${payload.AlarmInfoPlate.result.PlateResult.full_image_content}"
}
]
}
},
5.3 配置单向下发rpc控制
在serverSideRpc 里面下面配置配置
${deviceName}/device/message/down/gpio_out 是控制道闸开闸的topic
{
"type": "oneWay",
"deviceNameFilter": ".*",
"methodFilter": "no-reply",
"requestTopicExpression": "/${deviceName}/device/message/down/gpio_out",
"valueExpression": "${params}"
},
具体全部配置 mqtt.json
{
"broker": {
"name": "192.168.1.73",
"host": "192.168.1.73",
"port": 1883,
"clientId": "ThingsBoard_gateway111",
"version": 5,
"maxMessageNumberPerWorker": 10,
"maxNumberOfWorkers": 100,
"sendDataOnlyOnChange": false,
"security": {
"type": "basic",
"username": "admin",
"password": "public"
}
},
"mapping": [
{
"topicFilter": "sensor/data",
"converter": {
"type": "json",
"deviceNameJsonExpression": "${serialNumber}",
"deviceTypeJsonExpression": "${sensorType}",
"sendDataOnlyOnChange": false,
"timeout": 60000,
"attributes": [
{
"type": "string",
"key": "model",
"value": "${sensorModel}"
},
{
"type": "string",
"key": "${sensorModel}",
"value": "on"
}
],
"timeseries": [
{
"type": "double",
"key": "temperature",
"value": "${temp}"
},
{
"type": "double",
"key": "humidity",
"value": "${hum}"
},
{
"type": "string",
"key": "combine",
"value": "${hum}:${temp}"
}
]
}
},
{
"topicFilter": "/device/message/up/ivs_result",
"converter": {
"type": "json",
"deviceNameJsonExpression": "${sn}",
"deviceTypeJsonExpression": "臻识道闸设备配置",
"sendDataOnlyOnChange": false,
"timeout": 60000,
"attributes": [
],
"timeseries": [
{
"type": "string",
"key": "eventType",
"value": "1"
},
{
"type": "string",
"key": "id",
"value": "${id}"
},
{
"type": "string",
"key": "sn",
"value": "${sn}"
},
{
"type": "string",
"key": "name",
"value": "${name}"
},
{
"type": "string",
"key": "version",
"value": "${version}"
},
{
"type": "long",
"key": "timestamp",
"value": "${timestamp}"
},
{
"type": "string",
"key": "license",
"value": "${payload.AlarmInfoPlate.result.PlateResult.license}"
},
{
"type": "string",
"key": "full_image_content",
"value": "${payload.AlarmInfoPlate.result.PlateResult.full_image_content}"
}
]
}
},
{
"topicFilter": "sensor/+/data",
"converter": {
"type": "json",
"deviceNameTopicExpression": "(?<=sensor/)(.*?)(?=/data)",
"deviceTypeTopicExpression": "Thermometer",
"sendDataOnlyOnChange": false,
"timeout": 60000,
"attributes": [
{
"type": "string",
"key": "model",
"value": "${sensorModel}"
}
],
"timeseries": [
{
"type": "double",
"key": "temperature",
"value": "${temp}"
},
{
"type": "double",
"key": "humidity",
"value": "${hum}"
}
]
}
},
{
"topicFilter": "sensor/raw_data",
"converter": {
"type": "bytes",
"deviceNameExpression": "[0:4]",
"deviceTypeExpression": "default",
"sendDataOnlyOnChange": false,
"timeout": 60000,
"attributes": [
{
"type": "raw",
"key": "rawData",
"value": "[:]"
}
],
"timeseries": [
{
"type": "raw",
"key": "temp",
"value": "[4:]"
}
]
}
},
{
"topicFilter": "custom/sensors/+",
"converter": {
"type": "custom",
"extension": "CustomMqttUplinkConverter",
"cached": true,
"extension-config": {
"temperatureBytes": 2,
"humidityBytes": 2,
"batteryLevelBytes": 1
}
}
}
],
"connectRequests": [
{
"topicFilter": "sensor/connect",
"deviceNameJsonExpression": "${serialNumber}"
},
{
"topicFilter": "sensor/+/connect",
"deviceNameTopicExpression": "(?<=sensor/)(.*?)(?=/connect)"
}
],
"disconnectRequests": [
{
"topicFilter": "sensor/disconnect",
"deviceNameJsonExpression": "${serialNumber}"
},
{
"topicFilter": "sensor/+/disconnect",
"deviceNameTopicExpression": "(?<=sensor/)(.*?)(?=/disconnect)"
}
],
"attributeRequests": [
{
"retain": false,
"topicFilter": "v1/devices/me/attributes/request",
"deviceNameJsonExpression": "${serialNumber}",
"attributeNameJsonExpression": "${versionAttribute}, ${pduAttribute}",
"topicExpression": "devices/${deviceName}/attrs",
"valueExpression": "${attributeKey}: ${attributeValue}"
}
],
"attributeUpdates": [
{
"retain": true,
"deviceNameFilter": ".*",
"attributeFilter": "firmwareVersion",
"topicExpression": "sensor/${deviceName}/${attributeKey}",
"valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}"
}
],
"serverSideRpc": [
{
"type": "twoWay",
"deviceNameFilter": ".*",
"methodFilter": "echo",
"requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
"responseTopicExpression": "sensor/${deviceName}/response/${methodName}/${requestId}",
"responseTimeout": 10000,
"valueExpression": "${params}"
},
{
"type": "oneWay",
"deviceNameFilter": ".*",
"methodFilter": "no-reply",
"requestTopicExpression": "/${deviceName}/device/message/down/gpio_out",
"valueExpression": "${params}"
},
{
"type": "oneWay",
"deviceNameFilter": ".*",
"methodFilter": "no-reply",
"requestTopicExpression": "asd/123",
"valueExpression": "${params}"
}
],
"id": "546ac257-db5e-43a0-8d38-4755ae904aa8"
}
配置完成启动tb-gateway服务
设置道闸规则链
在thingsboard添加一个名字为臻识道闸规则链 的责任链
注意在switch 事件切换进行事件触发判断
在script 进行组合下发命令
然后rpc call request 进行下发发送执行
switch tbel编写
function nextRelation(metadata, msg) {
var arr=[];
if(msg.eventType == "1") {
arr.push('车牌识别触发事件');
}
return arr;
}
return nextRelation(metadata, msg);
script tbel编写
msg.payload={
type: "gpio_out",
body: {
delay: 500,
io: 0,
value: 2
}
};
msg.name="gpio_out";
msg.version="1.0";
var decodedData = atob(msg.license); // 解析base64车牌
if(decodedData.indexOf("无")== -1){
var msg1={method:"no-reply",params:msg};
metadata.oneway=true;
return {msg: msg1, metadata: metadata, msgType: "RPC_CALL_FROM_SERVER_TO_DEVICE"};
}
这个是规则链json,复制下来直接导入即可
{
"ruleChain": {
"name": "臻识道闸规则链",
"type": "CORE",
"firstRuleNodeId": null,
"root": false,
"debugMode": false,
"configuration": null,
"additionalInfo": {
"description": ""
}
},
"metadata": {
"firstNodeIndex": 6,
"nodes": [
{
"type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode",
"name": "Save Timeseries",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"defaultTTL": 0
},
"additionalInfo": {
"description": null,
"layoutX": 569,
"layoutY": 120
}
},
{
"type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode",
"name": "Save Client Attributes",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 2,
"configuration": {
"scope": "CLIENT_SCOPE",
"notifyDevice": false,
"sendAttributesUpdatedNotification": false,
"updateAttributesOnlyOnValueChange": true
},
"additionalInfo": {
"description": null,
"layoutX": 612,
"layoutY": 24
}
},
{
"type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode",
"name": "Message Type Switch",
"debugMode": false,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"version": 0
},
"additionalInfo": {
"description": null,
"layoutX": 257,
"layoutY": 127
}
},
{
"type": "org.thingsboard.rule.engine.action.TbLogNode",
"name": "Log RPC from Device",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
},
"additionalInfo": {
"description": null,
"layoutX": 554,
"layoutY": 230
}
},
{
"type": "org.thingsboard.rule.engine.action.TbLogNode",
"name": "Log Other",
"debugMode": false,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"scriptLang": "TBEL",
"jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);",
"tbelScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);"
},
"additionalInfo": {
"description": null,
"layoutX": 554,
"layoutY": 343
}
},
{
"type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode",
"name": "RPC Call Request",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"timeoutInSeconds": 60
},
"additionalInfo": {
"description": null,
"layoutX": 557,
"layoutY": 430
}
},
{
"type": "org.thingsboard.rule.engine.profile.TbDeviceProfileNode",
"name": "Device Profile Node",
"debugMode": false,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"persistAlarmRulesState": false,
"fetchAlarmRulesStateOnStart": false
},
"additionalInfo": {
"description": "Process incoming messages from devices with the alarm rules defined in the device profile. Dispatch all incoming messages with \"Success\" relation type.",
"layoutX": 190,
"layoutY": 413
}
},
{
"type": "org.thingsboard.rule.engine.transform.TbTransformMsgNode",
"name": "下发",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"scriptLang": "TBEL",
"jsScript": "msg.payload={\ntype: \"gpio_out\",\n body: {\n delay: 500,\n io: 0,\n value: 2\n }\n}\nvar msg1={method:\"no-reply\",params:msg,}\nmetadata.oneway=true;\nreturn {msg: msg1, metadata: metadata, msgType: \"RPC_CALL_FROM_SERVER_TO_DEVICE\"};",
"tbelScript": "msg.payload={\ntype: \"gpio_out\",\n body: {\n delay: 500,\n io: 0,\n value: 2\n }\n};\nmsg.name=\"gpio_out\";\nmsg.version=\"1.0\";\nvar decodedData = atob(msg.license); // decode the string\nif(decodedData.indexOf(\"无\")== -1){\nvar msg1={method:\"no-reply\",params:msg};\nmetadata.oneway=true;\nreturn {msg: msg1, metadata: metadata, msgType: \"RPC_CALL_FROM_SERVER_TO_DEVICE\"};\n}"
},
"additionalInfo": {
"description": "",
"layoutX": 1074,
"layoutY": 421
}
},
{
"type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode",
"name": "下发",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"timeoutInSeconds": 60
},
"additionalInfo": {
"description": "",
"layoutX": 1001,
"layoutY": 655
}
},
{
"type": "org.thingsboard.rule.engine.filter.TbJsSwitchNode",
"name": "事件切换",
"debugMode": true,
"singletonMode": false,
"queueName": null,
"configurationVersion": 0,
"configuration": {
"scriptLang": "TBEL",
"jsScript": "function nextRelation(metadata, msg) {\n return ['one','nine'];\n}\nif(msgType === 'POST_TELEMETRY_REQUEST') {\n return ['two'];\n}\nreturn nextRelation(metadata, msg);",
"tbelScript": "function nextRelation(metadata, msg) {\n var arr=[];\n\nif(msg.eventType == \"1\") {\n arr.push('车牌识别触发事件');\n \n}\nreturn arr;\n}\nreturn nextRelation(metadata, msg);"
},
"additionalInfo": {
"description": "",
"layoutX": 1005,
"layoutY": 197
}
}
],
"connections": [
{
"fromIndex": 0,
"toIndex": 9,
"type": "Success"
},
{
"fromIndex": 2,
"toIndex": 0,
"type": "Post telemetry"
},
{
"fromIndex": 2,
"toIndex": 1,
"type": "Post attributes"
},
{
"fromIndex": 2,
"toIndex": 3,
"type": "RPC Request from Device"
},
{
"fromIndex": 2,
"toIndex": 4,
"type": "Other"
},
{
"fromIndex": 2,
"toIndex": 5,
"type": "RPC Request to Device"
},
{
"fromIndex": 6,
"toIndex": 2,
"type": "Success"
},
{
"fromIndex": 7,
"toIndex": 8,
"type": "Success"
},
{
"fromIndex": 9,
"toIndex": 7,
"type": "车牌识别触发事件"
}
],
"ruleChainConnections": null
}
}
创建一个设备配置
设备配置规则链要用上面配置的规则链"臻识道闸设备配置"
臻识道闸设备配置这个名称不要写错,因为在网关gateway 的配置中
“deviceTypeJsonExpression”: “臻识道闸设备配置”, 是对应的deviceType的
配置道闸后台
首先要给道闸插网线,然后电脑和道闸在一个网络
登录道闸后台,道闸后台的地址在摄像头模组上有地址
1.在后台的高级设置>高级网络>mqtt配置
先配置mqtt broker
然后配置topic,注意这里只配置
道闸识别topic /device/message/up/ivs_result
下发控制io事件topic /设备id/device/message/down/gpio_out
开启抓拍图片上传mqtt,开启之后图片是通过道闸识别topic /device/message/up/ivs_result 进行base64上传 对应字段full_image_content
然后保存确定
测试
找一个车牌图片,打开道闸后台对准摄像头 按下模拟雷达开关触发
这个时候会自动创建一个设备
设备详情遥测