diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 23e7dd9..b8a5b2e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,8 +29,8 @@ jobs: goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} goversion: "https://dl.google.com/go/go1.19.1.linux-amd64.tar.gz" - project_path: "./cmd/motion-poll" - binary_name: "motion-poll" + project_path: "./cmd/onvif-motion-poll" + binary_name: "onvif-motion-poll" extra_files: LICENSE.txt README.md - name: release set-time uses: wangyoucao577/go-release-action@v1 @@ -39,18 +39,18 @@ jobs: goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} goversion: "https://dl.google.com/go/go1.19.1.linux-amd64.tar.gz" - project_path: "./cmd/set-time" - binary_name: "set-time" + project_path: "./cmd/onvif-set-time" + binary_name: "onvif-set-time" extra_files: LICENSE.txt README.md - - name: release set-preset + - name: release onvif-set-preset uses: wangyoucao577/go-release-action@v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} goversion: "https://dl.google.com/go/go1.19.1.linux-amd64.tar.gz" - project_path: "./cmd/set-preset" - binary_name: "set-preset" + project_path: "./cmd/onvif-set-preset" + binary_name: "onvif-set-preset" extra_files: LICENSE.txt README.md - name: release goto-preset uses: wangyoucao577/go-release-action@v1 @@ -59,6 +59,16 @@ jobs: goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} goversion: "https://dl.google.com/go/go1.19.1.linux-amd64.tar.gz" - project_path: "./cmd/goto-preset" - binary_name: "goto-preset" + project_path: "./cmd/onvif-goto-preset" + binary_name: "onvif-goto-preset" + extra_files: LICENSE.txt README.md + - name: release discover-all + uses: wangyoucao577/go-release-action@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + goos: ${{ matrix.goos }} + goarch: ${{ matrix.goarch }} + goversion: "https://dl.google.com/go/go1.19.1.linux-amd64.tar.gz" + project_path: "./cmd/discover-all" + binary_name: "onvif-discover-all" extra_files: LICENSE.txt README.md diff --git a/Makefile b/Makefile index 07c5117..b9bf347 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ install: ## run go install go install ./... ## create system-wide symlink to executables - bash ./install_scripts/create_symlinks.sh motion-poll set-preset goto-preset set-time + bash ./install_scripts/create_symlinks.sh onvif-motion-poll onvif-set-preset onvif-goto-preset onvif-set-time onvif-discover-all ## create config folder bash ./install_scripts/create_service_templates.sh diff --git a/cmd/onvif-discover-all/main.go b/cmd/onvif-discover-all/main.go new file mode 100644 index 0000000..74a2b0b --- /dev/null +++ b/cmd/onvif-discover-all/main.go @@ -0,0 +1,61 @@ +package main + +import ( + "fmt" + "github.com/jessevdk/go-flags" + "github.com/path-variable/onvif-cam-poll/pkg/model" + "github.com/path-variable/onvif-cam-poll/pkg/utils" + "github.com/use-go/onvif" + "os" + "strings" + "time" +) + +const commandName = "onvif-discover-all" + +func main() { + var opts discoverAllOptions + _, err := flags.ParseArgs(&opts, os.Args) + + if err != nil { + fmt.Printf(utils.ArgParseError, err) + return + } + + for { + fmt.Printf(utils.CommandSend, commandName) + res, err := onvif.GetAvailableDevicesAtSpecificEthernetInterface(opts.Interface) + if err != nil { + fmt.Printf(utils.CommandError, commandName, err) + return + } + + fmt.Printf("Discovered %d devices on interface %s\n", len(res), opts.Interface) + + for i := 0; i < len(res); i++ { + dev := res[i] + fmt.Printf("Device at %s\n", getAddressFromServices(dev)) + } + + fmt.Printf(utils.SleepTemplate, opts.CooldownTimer) + time.Sleep(time.Duration(opts.CooldownTimer) * time.Second) + } + +} + +func getAddressFromServices(device onvif.Device) string { + val, found := device.GetServices()["device"] + if found { + return getAddressFromUrl(val) + } + return "" +} + +func getAddressFromUrl(url string) string { + return strings.Split(url, ":")[1][2:] +} + +type discoverAllOptions struct { + model.CooldownParameters + model.InterfaceParameters +} diff --git a/cmd/goto-preset/main.go b/cmd/onvif-goto-preset/main.go similarity index 89% rename from cmd/goto-preset/main.go rename to cmd/onvif-goto-preset/main.go index d19de4f..24c7586 100644 --- a/cmd/goto-preset/main.go +++ b/cmd/onvif-goto-preset/main.go @@ -16,7 +16,7 @@ import ( token "github.com/use-go/onvif/xsd/onvif" ) -const commandName = "goto-preset" +const commandName = "onvif-goto-preset" /** Sends the camera to the target preset @@ -38,10 +38,10 @@ func main() { PresetToken: token.ReferenceToken(opts.PositionPreset), ProfileToken: token.ReferenceToken(opts.Profile), } - fmt.Printf(utils.CommandSend, commandName) + fmt.Printf(utils.CommandSend, commandName) _, err := sdk_ptz.Call_GotoPreset(context.TODO(), cam, gtreq) if err != nil { - fmt.Printf(utils.CommandError,commandName, err) + fmt.Printf(utils.CommandError, commandName, err) return } fmt.Printf(utils.SleepTemplate, opts.CooldownTimer) diff --git a/cmd/motion-poll/main.go b/cmd/onvif-motion-poll/main.go similarity index 91% rename from cmd/motion-poll/main.go rename to cmd/onvif-motion-poll/main.go index b7b804d..11f711c 100644 --- a/cmd/motion-poll/main.go +++ b/cmd/onvif-motion-poll/main.go @@ -25,6 +25,7 @@ Script for polling an ONVIF camera and getting motion events - specifically desi */ const ssErrorTemplate = "Error while getting snapshot %s\n" +const commandName = "onvif-motion-poll" func main() { var opts options @@ -38,7 +39,7 @@ func main() { // make initial pull point subscription cam, _ := onvif.NewDevice(onvif.DeviceParams{Xaddr: opts.Address, Username: opts.Username, Password: opts.Password}) res := &event.CreatePullPointSubscription{SubscriptionPolicy: event.SubscriptionPolicy{ChangedOnly: true}, - InitialTerminationTime: event.AbsoluteOrRelativeTimeType { + InitialTerminationTime: event.AbsoluteOrRelativeTimeType{ Duration: "PT300S", }} _, err = cam.CallMethod(res) @@ -56,7 +57,12 @@ func main() { // continue polling for motion events. if motion is detected, send Slack notification for { - r2, _ := cam.CallMethod(event.PullMessages{}) + fmt.Printf(utils.CommandSend, commandName) + r2, err := cam.CallMethod(event.PullMessages{}) + if err != nil { + fmt.Printf(utils.CommandError, commandName, err) + return + } bodyBytes, _ := io.ReadAll(r2.Body) bodyS := string(bodyBytes) if strings.Contains(bodyS, "") { diff --git a/cmd/set-preset/main.go b/cmd/onvif-set-preset/main.go similarity index 92% rename from cmd/set-preset/main.go rename to cmd/onvif-set-preset/main.go index ae553a7..7c7ea93 100644 --- a/cmd/set-preset/main.go +++ b/cmd/onvif-set-preset/main.go @@ -15,7 +15,7 @@ import ( token "github.com/use-go/onvif/xsd/onvif" ) -const commandName = "set-preset" +const commandName = "onvif-set-preset" /** Records the current camera position on the passed preset token @@ -42,7 +42,7 @@ func main() { fmt.Printf(utils.CommandSend, commandName) _, err = sdk_ptz.Call_SetPreset(context.TODO(), cam, gtreq) if err != nil { - fmt.Printf(utils.CommandError,commandName, err) + fmt.Printf(utils.CommandError, commandName, err) return } diff --git a/cmd/set-time/main.go b/cmd/onvif-set-time/main.go similarity index 95% rename from cmd/set-time/main.go rename to cmd/onvif-set-time/main.go index 89494c5..87fedd8 100644 --- a/cmd/set-time/main.go +++ b/cmd/onvif-set-time/main.go @@ -19,7 +19,8 @@ import ( onvif2 "github.com/use-go/onvif/xsd/onvif" ) -const commandName = "set-time" +const commandName = "onvif-set-time" + /* * Script for setting the date and time on an ONVIF camera- specifically designed for Hisseu cameras @@ -47,7 +48,7 @@ func main() { fmt.Printf(utils.CommandSend, commandName) _, err := sdk.Call_SetSystemDateAndTime(context.TODO(), cam, req) if err != nil { - fmt.Printf(utils.CommandError,commandName, err) + fmt.Printf(utils.CommandError, commandName, err) return } fmt.Printf(utils.SleepTemplate, opts.CooldownTimer) diff --git a/install_scripts/create_symlinks.sh b/install_scripts/create_symlinks.sh index aabd312..0f328cb 100644 --- a/install_scripts/create_symlinks.sh +++ b/install_scripts/create_symlinks.sh @@ -1,6 +1,6 @@ function create_symlink() { - sudo rm "/usr/bin/$1" - sudo ln -s "$GOPATH/$1" "/usr/bin/$1" + sudo rm "/usr/bin/$1" || true + sudo ln -s "$GOPATH/bin/$1" "/usr/bin/$1" } for var in "$@" diff --git a/motion@.service b/motion@.service deleted file mode 100644 index e0a9950..0000000 --- a/motion@.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -DefaultDependencies=no -After=network.target - -[Service] -Type=simple -EnvironmentFile=/home/isaric/.config/onvif-cam-poll/%i.env -Restart=always -RestartSec=3 -User=isaric -Group=isaric -ExecStart=/bin/bash /home/isaric/.config/onvif-cam-poll/motion.sh -TimeoutStartSec=0 - -[Install] -WantedBy=default.target diff --git a/pkg/model/types.go b/pkg/model/types.go index d570f64..d9f4bdb 100644 --- a/pkg/model/types.go +++ b/pkg/model/types.go @@ -1,10 +1,10 @@ package model type BasicParameters struct { - Username string `short:"u" long:"user" description:"The username for authenticating to the ONVIF device" required:"true"` - Password string `short:"p" long:"password" description:"The password for authenticating to the ONVIF device" required:"true"` - Address string `short:"a" long:"address" description:"The address of the ONVIF device and its port separated by semicolon" required:"true"` - Profile string `short:"r" long:"profile" description:"The onvif profile to be used" required:"false" default:"000"` + Username string `short:"u" long:"user" description:"The username for authenticating to the ONVIF device" required:"true"` + Password string `short:"p" long:"password" description:"The password for authenticating to the ONVIF device" required:"true"` + Address string `short:"a" long:"address" description:"The address of the ONVIF device and its port separated by semicolon" required:"true"` + Profile string `short:"r" long:"profile" description:"The onvif profile to be used" required:"false" default:"000"` } type SlackParameters struct { @@ -18,9 +18,13 @@ type PresetParameters struct { } type CooldownParameters struct { - CooldownTimer int `short:"t" long:"cooldown" description:"The integer value of the number of seconds after an event has occurred before polling resumes" required:"false" default:"60"` + CooldownTimer int `short:"t" long:"cooldown" description:"The integer value of the number of seconds after an event has occurred before polling resumes" required:"false" default:"60"` } type CameraNameParameters struct { - CameraName string `short:"n" long:"name" description:"The name or location of the ONVIF device that will appear in all notifications" required:"true"` -} \ No newline at end of file + CameraName string `short:"n" long:"name" description:"The name or location of the ONVIF device that will appear in all notifications" required:"true"` +} + +type InterfaceParameters struct { + Interface string `short:"i" long:"interface" description:"Prints a list of all discovered ONVIF devices on the specified interface" required:"true"` +} diff --git a/time@.service b/time@.service deleted file mode 100644 index 604aac6..0000000 --- a/time@.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -DefaultDependencies=no -After=network.target - -[Service] -Type=simple -EnvironmentFile=/home/isaric/.config/onvif-cam-poll/%i.env -Restart=always -RestartSec=3 -User=isaric -Group=isaric -ExecStart=/bin/bash /home/isaric/.config/onvif-cam-poll/time.sh -TimeoutStartSec=0 - -[Install] -WantedBy=default.target