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
然后保存确定
测试
找一个车牌图片,打开道闸后台对准摄像头 按下模拟雷达开关触发
这个时候会自动创建一个设备
设备详情遥测