Skip to content

Commit

Permalink
Dahua: NVR channel selection, event filter
Browse files Browse the repository at this point in the history
  • Loading branch information
toxuin committed Sep 20, 2022
1 parent d68f940 commit f485aca
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 10 deletions.
19 changes: 19 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/spf13/viper"
"github.com/toxuin/alarmserver/servers/dahua"
"github.com/toxuin/alarmserver/servers/hikvision"
"strings"
)

type Config struct {
Expand Down Expand Up @@ -219,12 +220,30 @@ func (c *Config) Load() *Config {
url += "http://"
}
url += camConfig.GetString("address")
var eventsFilter []string = nil
if camConfig.IsSet("events") {
allEvents := strings.Split(camConfig.GetString("events"), ",")
if len(allEvents) > 0 {
eventsFilter = make([]string, 0)
for _, eventName := range allEvents {
if eventName != "" {
eventsFilter = append(eventsFilter, strings.TrimSpace(eventName))
}
}
}
}
channel := ""
if camConfig.IsSet("channel") {
channel = camConfig.GetString("channel")
}
camera := dahua.DhCamera{
Debug: myConfig.Debug,
Name: camName,
Url: url,
Username: camConfig.GetString("username"),
Password: camConfig.GetString("password"),
Channel: channel,
Events: eventsFilter,
}

if myConfig.Debug {
Expand Down
4 changes: 4 additions & 0 deletions docs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ dahua:
https: false
username: admin
password: admin1234
# USE channel FOR NVRs TO SELECT THE CAMERA, IF NOT USED - DELETE OR COMMENT
channel: 1
# IF ALL EVENTS ARE NEEDED - DELETE OR COMMENT FOLLOWING LINE
events: VideoMotion,CrossLineDetection,AlarmLocal,VideoLoss,VideoBlind

ftp:
enabled: true
Expand Down
34 changes: 25 additions & 9 deletions servers/dahua/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (

type DhCamera struct {
Debug bool
Name string `json:"name"`
Url string `json:"url"`
Username string `json:"username"`
Password string `json:"password"`
Name string `json:"name"`
Url string `json:"url"`
Username string `json:"username"`
Password string `json:"password"`
Channel string `json:"channel"`
Events []string `json:"events"`
client *http.Client
}

Expand All @@ -44,7 +46,16 @@ type Event struct {
}

func (camera *DhCamera) readEvents(channel chan<- DhEvent, callback func()) {
request, err := http.NewRequest("GET", camera.Url+"/cgi-bin/eventManager.cgi?action=attach&codes=[All]", nil)
eventUrlSuffix := "/cgi-bin/eventManager.cgi?action=attach&heartbeat=10"
if camera.Channel != "" {
eventUrlSuffix += "&channel=" + camera.Channel
}
if camera.Events != nil && len(camera.Events) > 0 {
eventUrlSuffix += "&codes=[" + strings.Join(camera.Events, ",") + "]"
} else {
eventUrlSuffix += "&codes=[All]"
}
request, err := http.NewRequest("GET", camera.Url+eventUrlSuffix, nil)
if err != nil {
fmt.Printf("DAHUA: Error: Could not connect to camera %s\n", camera.Name)
fmt.Println("DAHUA: Error", err)
Expand Down Expand Up @@ -94,14 +105,16 @@ func (camera *DhCamera) readEvents(channel chan<- DhEvent, callback func()) {
multipartReader := multipart.NewReader(response.Body, multipartBoundary)
for {
part, err := multipartReader.NextPart()
contentLength, _ := strconv.Atoi(part.Header.Get("Content-Length"))
if err == io.EOF {
return
break
}
if err != nil {
fmt.Println(err)
continue
}
body, err := io.ReadAll(part)
body := make([]byte, contentLength)
_, err = part.Read(body)
if err != nil {
fmt.Println(err)
continue
Expand All @@ -113,12 +126,15 @@ func (camera *DhCamera) readEvents(channel chan<- DhEvent, callback func()) {

// EXAMPLE: "Code=VideoMotion; action=Start; index=0\r\n\r\n"
line := strings.Trim(string(body), " \n\r")
items := strings.Split(line, "; ")
if line == "Heartbeat" {
continue
}
items := strings.Split(line, ";")
keyValues := make(map[string]string, len(items))
for _, item := range items {
parts := strings.Split(item, "=")
if len(parts) > 0 {
keyValues[parts[0]] = parts[1]
keyValues[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
}
}
// EXAMPLE: { Code: VideoMotion, action: Start, index: 0 }
Expand Down
2 changes: 1 addition & 1 deletion servers/hikvision/httpEventReader.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (eventReader *HttpEventReader) ReadEvents(camera *HikCamera, channel chan<-
for {
part, err := multipartReader.NextPart()
if err == io.EOF {
return
break
}
if err != nil {
fmt.Println(err)
Expand Down

0 comments on commit f485aca

Please sign in to comment.