CF-IOT云端通讯协议调试

概述

设备与服务器通讯使用 WebSocket 或 MQTT 协议,数据采用 json 格式,可直接解析, WebSocket 服务器后台使用“/CloudEmbeddedSDKWebsocket/(设备号)”接口,接收设备 发出的 Websocket 请求,并按该文档定义的 json 格式处理数据。

开发者对接该协议,需要向我司申请开发者密钥,密钥由服务器 IP 或域名按一定的算 法生成,考虑到项目安全性,开发者可以提交多个备用域名,申请多个开发者密钥,当新增 或变更服务器,需要对设备下发产品认证指令。

设备开机会检测产品激活码,如果本地没有激活码,会主动向我司产品认证服务器申请 激活码,激活成功后,除主动下发产品认证,不会跟我司服务器有任何通信。

设备与服务器通信需要鉴权,设备连接成功,首先会发出开发者密钥请求,服务器应答 开发者密钥,设备收到开发者密钥进行鉴权,鉴权结果会上行服务器,只有鉴权成功,设备 才会维持正常的通信链路。

由设备发往服务器的数据,遵循设备上行协议,由服务器发往设备的数据,遵循设备下 行协议。

稳定性保障

设备固件运行期间,有守护进程、看门狗进程提供稳定性保障措施,守护进程定时监测设备固件是否存在,如果发现未运行,则尝试启动,看门狗进程主要起监测固件是否正常运行(定时发送喂狗信号),以及与后台通信是否正常的作用。

在web配置界面,我们可以启用和关闭看门狗,当启用看门狗功能,固件每隔5分钟发送喂狗信号到用户后台,用户后台需返回上行数据,设备收到该信号,才会通过管道发送喂狗信号给看门狗进程,从而起到监测固件正常运行和网络通讯正常双重作用,如果关闭看门狗功能,固件则每隔5分钟直接通过管道发送喂狗信号给看门狗进程,可以起到监测固件正常运行的作用。

通讯方式

WebSocket

首先我们进入设备的web配置界面,将协议类型设置为WebSocket,然后保存设置,再重启设备,设备便会以WebSocket通讯方式接入用户后台,WebSocket 服务器后台使用“/CloudEmbeddedSDKWebsocket/(设备号)”接口对接设备。

MQTT

进入设备的web配置界面,将协议类型设置为MQTT,可使用默认的发布主题、注册主题以及客户端ID,然后保存设置,再重启设备,设备便会以MQTT通讯方式接入用户后台,用户后台订阅以上发布主题接收设备上行数据,用户后台下发数据到设备,需要指定以上注册主题。

通讯参数

上传时间间隔:gps数据定时上报的时间间隔,单位秒,gps数据无效时,停止上报。

心跳间隔:心跳包定时上报的时间间隔,单位秒,心跳包主要起维持链路作用,用户后台可根据心跳到达时间与当前时间差,判断设备链路是否读超时,可作为释放链接资源的判断条件。

读超时:固件允许用户后台下行数据时间与当前时间差的最大值,单位秒,设备固件根据读超时判断设备链路是否正常,若超时,固件会释放旧连接资源,并创建新的连接。若新连接创建失败,则会等一个读超时的时间,继续创建连接,直至连接创建成功。

设备配置

设备支持网页、短信、下行指令修改相关参数,下行指令主要由用户后台发起,我们放在后续章节详细讲解,下面主要介绍网页和短信修改参数。

网页配置

设备网页地址:http://192.168.100.1

默认用户名:admin,密码:123456

短信指令

短信指令功能
Upgrading
系统升级
Reboot
系统重启
Refresh DeviceActivationCode
请求设备刷新激活码
Server api.uddgps.com 80 10 3 60 300

服务器域名:api.uddgps.com

服务器端口:80

回传间隔:10秒协议类型:3(websocket),4(mqtt)

心跳间隔:60秒

读超时:300秒 

MQTT ClientID UserName Password
设置mqtt服务器登录信息
LuaVM_Upgrading http://www.***/lua.zip
升级lua脚本
LuaVM_Load
启动虚拟机
LuaVM_Stop
停止虚拟机
LuaVM_Clear
清除lua脚本

协议调试

为了方便调试,我们将设备协议类型设置为MQTT,采用一台免费并可网页调试的MQTT服务器来完成相关功能测试。

MQTT调试网址:MQTT Websocket Client

CF-IOT云端通讯协议:CF-IOT云端通讯协议_物联网平台研发的博客-CSDN博客_cf协议

进入该调试界面,我们点连接按钮后,网页端会创建一个websocket连接,如果与MQTT服务器连接成功,我们便可通过mqtt.p2hp.com这台服务器与设备进行双向通信,在与设备通信前,我们要订阅主题,并设置发布主题。

通常在这个界面我们订阅的主题,对应设备发布主题,设置的发布主题,对应设备的注册主题。

密钥、鉴权、激活码

设备创建链路后,首先发的第一个JSON数据包便是密钥请求,如果用户后台不应答开发者密钥进行鉴权,设备会按心跳间隔重复发此包,直至鉴权成功。

↑密钥请求

{
	"channel": "ServerKey_Request",
	"DeviceNo": "864977047765106",
	"Data": null
}

↓密钥应答

{
	"channel": "ServerKey_Response",
	"DeviceNo": "864977047765106",
	"Data": {
		"ServerKey": "0F3EFB4E40C69C7A39C90E319732D6A3"
	}
}

↑鉴权结果

{
	"channel": "Authentication",
	"DeviceNo": "864977047765106",
	"Data": {
		"Result": true
	}
}

↑设备激活码请求

{
	"channel": "DeviceActivationCode_Request",
	"DeviceNo": "864977047765106",
	"Data": null
}

设备第一次请求激活码,是从我司服务器申请,若请求成功,会将激活码保存本地,并上报一条包含激活码的固件信息到用户后台,用户后台应将该激活码保存,当设备数据文件损坏,我司授权服务器不能正常访问时,设备会发送该激活码请求包,用户后台应下发一条包含设备激活码的固件设置指令。

固件信息

↓查询固件

{
	"channel": "Parameters_Request",
	"DeviceNo": "864977047765106",
	"Data": {
		"ParameterName": "Firmware",
		"Filter": ""
	}
}

↑固件信息

{
	"channel": "Firmware_Parameters_Response",
	"DeviceNo": "864977047765106",
	"Data": {
		"ModuleState": {
			"IMEI": "864977047765106",
			"CCID": "89860318245512075960",
			"CSQ": "25,99",
			"CSQtime": "2020-11-12 19:36:31",
			"Revision": "EC20CEFILGR06A03M1G_OCPU_BETA0628"
		},
		"FunctionSwitch": {
			"Watchdog": false,
			"GPS": false
		},
		"DeviceActivationCode": ",E4DFE403DC960AC21DEDA29B4DDC2548,F63FBF4299C4F546B6B36D50F8CB47F6,9F069D3D4F7B29FE35EF9910898AC373,",
		"Revision": "HeFeiQILIAN_miniCFIOT_v1.3.5.1.2_20201109"
	}
}

↓设置固件

{
	"channel": "Firmware_Settings",
	"DeviceNo": "864977047765106",
	"Data": {
		"Switch_Watchdog": 1,
		"Switch_GPS": 1,
		"DeviceActivationCode": ""
	}
}

↑心跳包

{
	"channel": "H",
	"DeviceNo": "864977047765106",
	"Data": null
}

位置测试

↑GPS数据

{
	"channel": "GPS",
	"DeviceNo": "864977047765106",
	"Data": {
		"Longitude": 117.2304914,
		"Latitude": 31.842440516666667,
		"N_S": "N",
		"E_W": "E",
		"Speed": 0,
		"Direction": 164.2,
		"Mode": "A",
		"DateTime": "2020-11-09 16:43:22.00"
	}
}

↓按需秒刷新

用户后台定时下发该信号,设备在GPS数据有效时,自动秒传GPS数据,当停止下发该信号超过30秒,设备会自动关闭秒传GPS功能。

{
	"channel": "UpdateSendNowForGPSSignal",
	"DeviceNo": "864977047765106",
	"Data": null
}

↑GPS刷新数据

{
	"channel": "GPS_Refresh_GPRMC",
	"DeviceNo": "864977047765106",
	"Data": "GPRMC,164826.00,A,3150.563094,N,11713.823810,E,0.0,341.0,091120,4.4,W,A"
}

串口调试

↓串口初始化

{
	"channel": "Serial_Open",
	"DeviceNo": "862607059109339",
	"Data": {
		"portName": "Serial1",
		"Baud": 9600,
		"DataBits": 8,
		"Parity": "None",
		"StopBits": 1

	}
}

↑串口连接事件

{
	"channel": "Hardware_onEvent",
	"DeviceNo": "862607059109339",
	"Data": {
		"EventName": "Serial_Open_Success",
		"portName": "Serial1",
		"Message": ""
	}
}

↓写串口

{
	"channel": "Serial_writeData",
	"DeviceNo": "862607059109339",
	"Data": {
		"portName": "Serial1",
		"Data": "ff 05 00 00 00 00 d8 14"
	}
}

↑读串口

{
	"channel": "Serial_onData",
	"DeviceNo": "862607059109339",
	"Data": {
		"portName": "Serial1",
		"Data": "ff 05 00 00 00 00 d8 14"
	}
}

摄像机调试

↓摄像机搜索

固件每隔三分钟通过udp广播方式搜索摄像机、更新状态,网页配置界面里也可以手动搜索摄像机,用户后台可以下发摄像机搜索指令,实现主动搜索摄像机并更新摄像机状态。

{
	"channel": "SearchAllIPCamera",
	"DeviceNo": "864977047765106",
	"Data": null
}

↓查询摄像机信息

{
	"channel": "Parameters_Request",
	"DeviceNo": "864977047765106",
	"Data": {
		"ParameterName": "IPCameraParameters",
		"Filter": ""
	}
}

Filter字段可指定摄像机IP

↑摄像机信息

{
	"channel": "IPCamera_Parameters_Response",
	"DeviceNo": "864977047765106",
	"Data": {
		"192.168.100.48": {
			"IP": "192.168.100.48",
			"SerialNumber": "fe5002562668",
			"UserName": "",
			"Password": "",
			"MediaArray": [{
				"ProfileToken": "stream0_0",
				"Width": 1920,
				"Height": 1080,
				"RtspUrl": "rtsp://192.168.100.48/live/ch00_1"
			}, {
				"ProfileToken": "stream0_1",
				"Width": 640,
				"Height": 480,
				"RtspUrl": "rtsp://192.168.100.48/live/ch00_0"
			}],
			"SelectMediaKey": "",
			"StreamUrl": "",
			"HLSurl": "",
			"RTMPurl": "",
			"Flvurl": "",
			"TimeRange": {}
		},
		"192.168.100.75": {
			"IP": "192.168.100.75",
			"SerialNumber": "",
			"UserName": "",
			"Password": "",
			"MediaArray": [],
			"SelectMediaKey": "",
			"StreamUrl": "",
			"HLSurl": "",
			"RTMPurl": "",
			"Flvurl": "",
			"TimeRange": {}
		}
	}
}

从以上返回的摄像机列表里,IP为192.168.100.75的摄像机码流是空的,这是因为该摄像机启用了onvif鉴权,我们要给该摄像机配置用户名和密码,固件才能获取到码流信息。

↓摄像机鉴权

{
	"channel": "IPCamera_Settings",
	"DeviceNo": "864977047765106",
	"Data": {
		"Type": 0,
		"Data": {
			"IP": "192.168.100.75",
			"UserName": "admin",
			"Password": "admin"
		}
	}
}

通过以上鉴权设置后,我们下发摄像机搜索指令,并查询摄像机,便可以获取到该摄像机码流信息了。

{
	"channel": "IPCamera_Parameters_Response",
	"DeviceNo": "864977047765106",
	"Data": {
		"192.168.100.75": {
			"IP": "192.168.100.75",
			"SerialNumber": "007D50117625",
			"UserName": "admin",
			"Password": "admin",
			"MediaArray": [{
				"ProfileToken": "MainStreamProfileToken",
				"Width": 1920,
				"Height": 1080,
				"RtspUrl": "rtsp://192.168.100.75:554/11"
			}, {
				"ProfileToken": "SecondStreamProfileToken",
				"Width": 640,
				"Height": 352,
				"RtspUrl": "rtsp://192.168.100.75:554/12"
			}],
			"SelectMediaKey": "",
			"StreamUrl": "",
			"HLSurl": "",
			"RTMPurl": "",
			"Flvurl": "",
			"TimeRange": {}
		}
	}
}

↓图像采集

{
	"channel": "Media_Screenshot",
	"DeviceNo": "864977047765106",
	"Data": {
		"SerialNumber": "007D50117625",
		"MediaKey": "SecondStreamProfileToken_640_352",
		"FileName": "testScreenshot",
		"FtpPath": "/Media"
	}
}

摄像机拍照操作,会上报相关通知事件

↑拍照成功事件

{
	"channel": "Media_onEvent",
	"DeviceNo": "864977047765106",
	"Data": {
		"EventName": "Media_Screenshot_Success",
		"Message": "",
		"FileName": "/Media/testScreenshot.jpg"
	}
}

 ↑ftp上传成功事件

{
	"channel": "Ftp_onEvent",
	"DeviceNo": "864977047765106",
	"Data": {
		"EventName": "FTP_Upload_Success",
		"Message": "",
		"FileName": "/Media/testScreenshot.jpg"
	}
}

↓视频录制

{
	"channel": "Media_VideoRecording",
	"DeviceNo": "864977047765106",
	"Data": {
		"SerialNumber": "007D50117625",
		"MediaKey": "SecondStreamProfileToken_640_352",
		"FileName": "testVideoRecording",
		"FtpPath": "/Media",
		"Duration": 10,
		"MediaType": "flv"
	}
}

摄像机录制操作,会上报相关通知事件

↑录制成功事件

{
	"channel": "Media_onEvent",
	"DeviceNo": "864977047765106",
	"Data": {
		"EventName": "Media_VideoRecording_Success",
		"Message": "",
		"FileName": "/Media/testVideoRecording.flv"
	}
}

 ↑ftp上传成功事件

{
	"channel": "Ftp_onEvent",
	"DeviceNo": "864977047765106",
	"Data": {
		"EventName": "FTP_Upload_Success",
		"Message": "",
		"FileName": "/Media/testVideoRecording.flv"
	}
}

↓查询摄像机状态

{
	"channel": "Parameters_Request",
	"DeviceNo": "864977047765106",
	"Data": {
		"ParameterName": "IPCameraState",
		"Filter": ""
	}
}

 ↑摄像机状态信息

{
	"channel": "IPCameraState_Response",
	"DeviceNo": "864977047765106",
	"Data": [{
		"IP": "192.168.100.75",
		"OnVifServiceUrl": "http://192.168.100.75:8080/onvif/device_service",
		"Manufacturer": "IPCAM",
		"FirmwareVersion": "V20.1.41.16.3-20200430",
		"SerialNumber": "007D50117625",
		"MediaArray": [{
			"ProfileToken": "MainStreamProfileToken",
			"Width": 1920,
			"Height": 1080,
			"MainStream": false,
			"RtspUrl": "rtsp://192.168.100.75:554/11",
			"SnapshotUri": "http://192.168.100.75:80/tmpfs/auto.jpg",
			"PushStream": {
				"State": false,
				"HeartbeatTime": "0001-01-01T00:00:00Z",
				"StreamUrl": "",
				"HLSurl": "",
				"RTMPurl": "",
				"Flvurl": ""
			},
			"Screenshot": "",
			"InUse": false
		}, {
			"ProfileToken": "SecondStreamProfileToken",
			"Width": 640,
			"Height": 352,
			"MainStream": false,
			"RtspUrl": "rtsp://192.168.100.75:554/12",
			"SnapshotUri": "http://192.168.100.75:80/tmpfs/auto.jpg",
			"PushStream": {
				"State": false,
				"HeartbeatTime": "0001-01-01T00:00:00Z",
				"StreamUrl": "",
				"HLSurl": "",
				"RTMPurl": "",
				"Flvurl": ""
			},
			"Screenshot": "",
			"InUse": false
		}],
		"State": true,
		"PlayState": false
	}]
}

摄像机推流

设备支持按需推流、定时推流,并且两种推流方式可互补使用,如果在摄像机信息里设置了定时推流时间段,当处在非定时推流时间段,我们可以从用户后台定时下发按需推流指令来控制摄像机推流,在摄像机状态信息中,每路摄像机码流都有一个推流结构体,该结构体执行最终的推流操作,我们将推流操作加锁,这就意味着定时推流和按需推流具有互斥性,可以起到互补作用。

定时推流

在摄像机信息里,我们可以为摄像机的某个码流设置推流时间段,目前一个摄像机只能设置一路码流定时推流,并且支持网页和下发指令设置推流属性。

↓设置推流

{
	"channel": "IPCamera_Settings",
	"DeviceNo": "864977047765106",
	"Data": {
		"Type": 1,
		"Data": {
			"IP": "192.168.100.75",
			"SelectMediaKey": "SecondStreamProfileToken_640_352",
			"StreamUrl": "rtmp://tx.direct.huya.com/huyalive/*********",
			"HLSurl": "",
			"RTMPurl": "",
			"Flvurl": ""
		}
	}
}

↓设置推流时间段

{
	"channel": "IPCamera_Settings",
	"DeviceNo": "864977047765106",
	"Data": {
		"Type": 2,
		"Data": {
			"IP": "192.168.100.75",
			"TimeRange": {
				"Friday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}],
				"Monday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}],
				"Saturday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}],
				"Sunday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}],
				"Thursday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}],
				"Tuesday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}],
				"Wednesday": [{
					"StartTime": "06:00:00",
					"EndTime": "18:00:00",
					"StartTime1": 21600,
					"EndTime1": 64800
				}, {
					"StartTime": "19:00:00",
					"EndTime": "20:00:00",
					"StartTime1": 68400,
					"EndTime1": 72000
				}]
			}
		}
	}
}

↓按需推流

{
	"channel": "StartPushStream",
	"DeviceNo": "864977047765106",
	"Data": {
		"SerialNumber": "007D50117625",
		"MediaKey": "SecondStreamProfileToken_640_352",
		"StreamUrl": "rtmp://tx.direct.huya.com/huyalive/1199558764847-1199558764847-6888343667394952147-2399117653150-10057-A-1603817515-1?seq=1605155499051&type=simple",
		"HLSurl": "",
		"RTMPurl": "",
		"Flvurl": ""
	}
}

用户后台需要定时下发推流指令,才能维持推流过程,当停止下发该推流指令,30秒后自动停止推流。

LUA虚拟机

脚本升级

{
	"channel": "LuaVM_Upgrading",
	"DeviceNo": "864977047765106",
	"Data": {
		"URL": "http://www.***/lua.zip"
	}
}

启动虚拟机

{
	"channel": "LuaVM_Load",
	"DeviceNo": "864977047765106",
	"Data": null
}

停止虚拟机

{
	"channel": "LuaVM_Stop",
	"DeviceNo": "864977047765106",
	"Data": null
}

清除脚本

{
	"channel": "LuaVM_Clear",
	"DeviceNo": "864977047765106",
	"Data": null
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值