Go语言实现Onvif客户端:2、获取设备信息
1、思路
- 搜索设备
- 获取设备能力
- 通过设备能力的设备接口读取设备信息
我们上节说了,主要是通过设备信息中的内容来区分同一局域网下各个支持Onvif协议的设备,通过设备信息可以获取的设备信息包括:
Manufacturer string
Model string
FirmwareVersion string
SerialNumber string
HardwareId string
- 厂家信息
- 设备类型
- 固件版本
- 设备序列号
- 固件ID
2、代码
发送请求:
/**
* @Description: 获取设备信息
* @time: 2021-03-26 10:54:27
* @receiver client
* @return returnInfo
*/
func (client *GoOnvifClient) GetDeviceInfo() returnInfo {
getDevInfoReq := device.GetDeviceInformation{}
res := client.sendReqGetResp(GetDeviceInfoErr, getDevInfoReq)
return client.getDeviceInfoFromXml(res.Info)
}
接受response:
/**
* @Description: 读取response结果
* @time: 2021-03-25 14:51:36
* @param resp
* @return string
*/
func readResponse(resp *http.Response) string {
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err.Error()
}
return string(b)
}
/**
* @Description: 进行onvif客户端请求发送和response读取处理
* @time: 2021-03-26 09:26:50
* @param client: 封装的onvif客户端相关信息
* @param errCode:出错时的错误码
* @param method:要产生的request请求的处理方法
* @return returnInfo:包含错误码和错误信息的结构体
*/
func (client *GoOnvifClient) sendReqGetResp(errCode Code, method interface{}) returnInfo {
resp, err := client.Dev.CallMethod(method)
message := ""
if err != nil {
return returnInfo{errCode, err.Error()}
} else {
message = readResponse(resp)
if client.IsPrintRespSoap {
fmt.Println(gosoap.SoapMessage(message).StringIndent())
}
}
return returnInfo{OK, gosoap.SoapMessage(message).StringIndent()}
}
解析response中的xml内容:
/**
* @Description: 从xml文件中读取设备信息
* @time: 2021-03-26 10:58:06
* @receiver client
* @param message
* @return returnInfo
*/
func (client *GoOnvifClient) getDeviceInfoFromXml(message string) returnInfo {
doc := etree.NewDocument()
if err := doc.ReadFromString(message); err != nil {
return returnInfo{GetDeviceInfoErr, "read device xml info failed."}
}
root := doc.SelectElement("Envelope")
if root == nil {
return returnInfo{GetDeviceInfoErr, "read device xml info failed."}
}
modelNode := root.FindElement("./Body/GetDeviceInformationResponse/Model")
if modelNode != nil {
client.devInfo.Model = modelNode.Text()
}
SNNode := root.FindElement("./Body/GetDeviceInformationResponse/SerialNumber")
if SNNode != nil {
client.devInfo.SN = SNNode.Text()
}
if client.devInfo.SN == "" && client.devInfo.Model == "" {
return returnInfo{GetNetWorkInfoErr, "read network xml info failed."}
}
return returnInfo{OK, "get device info success"}
}
之后就是获取其它能力需要的各种Profiles文件了。