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 }