ant-thomas / zsgx1hacks

Hacks for ZS-GX1 IP Camera and various Goke GK7102 based IP Cameras
368 stars 101 forks source link

Domoticz integration #67

Open roleoroleo opened 6 years ago

roleoroleo commented 6 years ago

I would like to share a small program that I wrote. My goal is to improve the camera integration in Domiticz as the ONVIF protocol is not well supported. Looking for a solution for the snapshot https://github.com/ant-thomas/zsgx1hacks/issues/64 I noticed that there is a TCP socket that exposes the p2pcam log (the same one that is present in stdout) and that a log line is published when the camera detects a movement or a sound. So I wrote a program that reads from socket 127.0.0.1:3201 and sends a message to an MQTT broker when it detects a motion or sound event. The syntax of the message is the one used by Domoticz. The program has a configuration file where you can configure some parameters.

https://repository.ilpuntotecnico.com/files/roleo/public/guudgo_gd-sc03/event_detect.tgz

Archive content:

deorder commented 6 years ago

I did exactly that. It works well

Cruiser79 commented 6 years ago

Nice idea: I could also open a socket to this port and recognized "EVENT: MOTION detect." messages. It also works from another server in the same network to access the 3201 port, so my go program runs on my server and is connected to the cam to detect the events.

Cruiser79 commented 6 years ago

Maybe someone need some simple example code. A very simple proof-of-concept go program looks like this:

package main

import (
        "fmt"
        "github.com/eclipse/paho.mqtt.golang"
        "net"
        "bufio"
        "os"
        "strings"
)

func main() {
        connOpts := mqtt.NewClientOptions().AddBroker("tcp://[MQTT-SERVER-IP]:1883").SetClientID("12345678").SetCleanSession(true)

        client := mqtt.NewClient(connOpts)
        if token := client.Connect(); token.Wait() && token.Error() != nil {
                fmt.Println(token.Error())
                return
        }

        conn, err := net.Dial("tcp", "[CAM-IP]:3201")
        if err != nil {
                fmt.Printf("Error on dial: %+v\r\n", err)
                return
        }
        for {
                status, err := bufio.NewReader(conn).ReadString('\n')
                if err != nil {
                        fmt.Printf("Error on readString: %+v\r\n", err)
                        os.Exit(0)
                }
                fmt.Printf("Read: %s", status)
                if (strings.HasPrefix(status, "EVENT: MOTION detect.")) {
                        fmt.Println("EVENT MOTION detected")
                        var qos byte
                        qos = 0
                        client.Publish("[MQTT-TOPIC]", qos, false, "detected")
                }
        }
}
edsub commented 6 years ago

I am working on a solution with the same purpose. I chose a solution the other way around: Based on the logging of an EVENT, the Domoticz webservice is triggered so a (virtual) sensor is updated. Advantage: My Domoticz server has a fixed ip. The camera has a dynamic ip. All done from a modified start.sh and some scripting. See https://github.com/ant-thomas/zsgx1hacks/issues/84 for progress. Will post once it allworks reliably. I notice the signalling of EVENTS is not consistent. Wondering which config to change to improve.....