114 lines
2.6 KiB
Go

package main
import (
"encoding/xml"
goonvif "github.com/IOTechSystems/onvif"
"github.com/IOTechSystems/onvif/device"
"github.com/IOTechSystems/onvif/event"
"github.com/IOTechSystems/onvif/gosoap"
"github.com/IOTechSystems/onvif/xsd"
"io"
"net/http"
)
type Connection struct {
Params DeviceParams `json:"params"`
Device *goonvif.Device `json:"device"`
}
type DeviceParams struct {
Xaddr string `json:"xaddr"`
EndpointRefAddress string `json:"endpointRefAddress"`
Username string `json:"username"`
Password string `json:"password"`
AuthMode string `json:"authMode"`
}
func readResponse(resp *http.Response) (string, error) {
b, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(b), nil
}
func unmarshalResponse(resp *http.Response, target any) error {
b, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
if err = xml.Unmarshal(b, gosoap.NewSOAPEnvelope(target)); err != nil {
return err
}
return nil
}
func NewConnection(addr string, username string, password string) (*Connection, error) {
dev, err := goonvif.NewDevice(goonvif.DeviceParams{
Xaddr: addr,
Username: username,
Password: password,
//AuthMode: goonvif.UsernameTokenAuth,
})
if err != nil {
return nil, err
}
return &Connection{
Params: DeviceParams{
Xaddr: dev.GetDeviceParams().Xaddr,
EndpointRefAddress: dev.GetDeviceParams().EndpointRefAddress,
Username: dev.GetDeviceParams().Username,
Password: dev.GetDeviceParams().Password,
AuthMode: dev.GetDeviceParams().AuthMode,
},
Device: dev,
}, nil
}
func (c *Connection) GetDeviceInformation() (*device.GetDeviceInformationResponse, error) {
resp, err := c.Device.CallMethod(device.GetDeviceInformation{})
if err != nil {
return nil, err
}
result := &device.GetDeviceInformationResponse{}
err = unmarshalResponse(resp, result)
if err != nil {
return nil, err
}
return result, nil
}
func (c *Connection) SubscribeEvents(
consumerAddress event.AttributedURIType,
terminationTime xsd.String, // PT60S
) (*event.SubscribeResponse, error) {
resp, err := c.Device.CallMethod(event.Subscribe{
ConsumerReference: &event.EndpointReferenceType{
Address: consumerAddress,
},
Filter: &event.FilterType{
TopicExpression: &event.TopicExpressionType{
TopicKinds: "tns1:VideoSource//.",
},
},
TerminationTime: &terminationTime,
})
if err != nil {
return nil, err
}
result := &event.SubscribeResponse{}
err = unmarshalResponse(resp, result)
if err != nil {
return nil, err
}
return result, nil
}