b4e4982876
- Adjusted formatting in XML response strings for consistency in device_extended_test.go and device_security_test.go. - Improved readability by aligning XML declaration and body content. - Updated mock server responses to ensure proper handling of various ONVIF operations. Enhance device security and storage handling - Refactored struct field declarations in device_security.go and device_storage_test.go for improved clarity. - Ensured consistent formatting across struct definitions and XML tags. Standardize whitespace and formatting across multiple files - Removed unnecessary blank lines and adjusted indentation in discovery, imaging, media, and PTZ server files. - Improved overall code readability and maintainability by ensuring consistent formatting. Update example applications for better readability - Cleaned up whitespace in example applications to enhance code clarity. - Ensured consistent formatting in main.go files across various examples. Refactor server and SOAP handler code for consistency - Standardized struct field declarations and XML tag formatting in server and SOAP handler files. - Improved readability by aligning struct fields and ensuring consistent use of whitespace. General code cleanup and formatting adjustments - Applied consistent formatting across various files, including types.go and test files. - Enhanced readability by aligning struct fields and removing unnecessary blank lines.
155 lines
3.7 KiB
Go
155 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/0x524a/onvif-go"
|
|
)
|
|
|
|
func main() {
|
|
// Camera connection details
|
|
endpoint := "http://192.168.1.100/onvif/device_service"
|
|
username := "admin"
|
|
password := "password"
|
|
|
|
fmt.Println("Connecting to ONVIF camera...")
|
|
|
|
// Create a new ONVIF client
|
|
client, err := onvif.NewClient(
|
|
endpoint,
|
|
onvif.WithCredentials(username, password),
|
|
onvif.WithTimeout(30*time.Second),
|
|
)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create client: %v", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
// Initialize client
|
|
if err := client.Initialize(ctx); err != nil {
|
|
log.Fatalf("Failed to initialize client: %v", err)
|
|
}
|
|
|
|
// Get profiles
|
|
profiles, err := client.GetProfiles(ctx)
|
|
if err != nil {
|
|
log.Fatalf("Failed to get profiles: %v", err)
|
|
}
|
|
|
|
if len(profiles) == 0 {
|
|
log.Fatal("No profiles found")
|
|
}
|
|
|
|
profileToken := profiles[0].Token
|
|
fmt.Printf("Using profile: %s\n\n", profiles[0].Name)
|
|
|
|
// Demonstrate PTZ controls
|
|
demonstratePTZ(ctx, client, profileToken)
|
|
}
|
|
|
|
func demonstratePTZ(ctx context.Context, client *onvif.Client, profileToken string) {
|
|
// Get current PTZ status
|
|
fmt.Println("Getting current PTZ status...")
|
|
status, err := client.GetStatus(ctx, profileToken)
|
|
if err != nil {
|
|
log.Printf("Warning: Failed to get PTZ status: %v\n", err)
|
|
} else {
|
|
fmt.Printf("Current Position:\n")
|
|
if status.Position != nil {
|
|
if status.Position.PanTilt != nil {
|
|
fmt.Printf(" Pan/Tilt: X=%.2f, Y=%.2f\n",
|
|
status.Position.PanTilt.X,
|
|
status.Position.PanTilt.Y)
|
|
}
|
|
if status.Position.Zoom != nil {
|
|
fmt.Printf(" Zoom: %.2f\n", status.Position.Zoom.X)
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
// Get presets
|
|
fmt.Println("Getting PTZ presets...")
|
|
presets, err := client.GetPresets(ctx, profileToken)
|
|
if err != nil {
|
|
log.Printf("Warning: Failed to get presets: %v\n", err)
|
|
} else {
|
|
fmt.Printf("Found %d preset(s):\n", len(presets))
|
|
for _, preset := range presets {
|
|
fmt.Printf(" - %s (Token: %s)\n", preset.Name, preset.Token)
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
// Continuous move right for 2 seconds
|
|
fmt.Println("Moving camera right...")
|
|
velocity := &onvif.PTZSpeed{
|
|
PanTilt: &onvif.Vector2D{
|
|
X: 0.5, // Move right
|
|
Y: 0.0,
|
|
},
|
|
}
|
|
timeout := "PT2S" // 2 seconds
|
|
if err := client.ContinuousMove(ctx, profileToken, velocity, &timeout); err != nil {
|
|
log.Printf("Failed to move: %v\n", err)
|
|
} else {
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
|
|
// Stop movement
|
|
fmt.Println("Stopping camera movement...")
|
|
if err := client.Stop(ctx, profileToken, true, false); err != nil {
|
|
log.Printf("Failed to stop: %v\n", err)
|
|
}
|
|
|
|
// Relative move
|
|
fmt.Println("\nPerforming relative move (up and zoom in)...")
|
|
translation := &onvif.PTZVector{
|
|
PanTilt: &onvif.Vector2D{
|
|
X: 0.0,
|
|
Y: 0.1, // Move up
|
|
},
|
|
Zoom: &onvif.Vector1D{
|
|
X: 0.1, // Zoom in
|
|
},
|
|
}
|
|
if err := client.RelativeMove(ctx, profileToken, translation, nil); err != nil {
|
|
log.Printf("Failed to relative move: %v\n", err)
|
|
} else {
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
|
|
// Absolute move to home position
|
|
fmt.Println("\nMoving to home position...")
|
|
homePosition := &onvif.PTZVector{
|
|
PanTilt: &onvif.Vector2D{
|
|
X: 0.0,
|
|
Y: 0.0,
|
|
},
|
|
Zoom: &onvif.Vector1D{
|
|
X: 0.0,
|
|
},
|
|
}
|
|
if err := client.AbsoluteMove(ctx, profileToken, homePosition, nil); err != nil {
|
|
log.Printf("Failed to absolute move: %v\n", err)
|
|
} else {
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
|
|
// Go to preset if available
|
|
if len(presets) > 0 {
|
|
fmt.Printf("\nGoing to preset: %s\n", presets[0].Name)
|
|
if err := client.GotoPreset(ctx, profileToken, presets[0].Token, nil); err != nil {
|
|
log.Printf("Failed to go to preset: %v\n", err)
|
|
} else {
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
}
|
|
|
|
fmt.Println("\nPTZ demonstration complete!")
|
|
}
|