Setup repeat camera down notifications #24
This commit is contained in:
parent
7b24dad5b9
commit
8e99fb8022
|
@ -4,12 +4,12 @@ import "os"
|
||||||
|
|
||||||
import "gopkg.in/yaml.v3"
|
import "gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Cameras map[string]string `yaml:"cameras"`
|
Cameras map[string]string `yaml:"cameras"`
|
||||||
PingIntervalSeconds int64 `yaml:"ping_interval_s"`
|
PingIntervalSeconds int64 `yaml:"ping_interval_s"`
|
||||||
PingTimeoutSeconds int64 `yaml:"ping_timeout_s"`
|
PingTimeoutSeconds int64 `yaml:"ping_timeout_s"`
|
||||||
ConsecutiveDownThreshold int `yaml:"consecutive_down_threshold"`
|
ConsecutiveDownThreshold int `yaml:"consecutive_down_threshold"`
|
||||||
|
NotificationRepeatThreshold int `yaml:"notification_repeat_threshold"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadConfig(configFilename string) Config {
|
func ReadConfig(configFilename string) Config {
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
cameras:
|
cameras:
|
||||||
back_door: 'rtsp://frigate:8554/back_door'
|
back_door: 'rtsp://frigate:8554/back_door'
|
||||||
doorbell: 'rtsp://frigate:8554/doorbell'
|
doorbell: 'rtsp://frigate:8554/doorbell'
|
||||||
front_door: 'rtsp://frigate:8554/front_door'
|
|
||||||
garage: 'rtsp://frigate:8554/garage'
|
garage: 'rtsp://frigate:8554/garage'
|
||||||
ping_interval_s: 60
|
ping_interval_s: 60
|
||||||
ping_timeout_s: 30
|
ping_timeout_s: 30
|
||||||
consecutive_down_threshold: 3
|
consecutive_down_threshold: 3
|
||||||
|
notification_repeat_threshold: 30
|
||||||
|
|
|
@ -12,6 +12,6 @@ func main() {
|
||||||
var pingInterval = time.Duration(uptimeConfig.PingIntervalSeconds * int64(time.Second))
|
var pingInterval = time.Duration(uptimeConfig.PingIntervalSeconds * int64(time.Second))
|
||||||
var pingTimeout = time.Duration(uptimeConfig.PingTimeoutSeconds * int64(time.Second))
|
var pingTimeout = time.Duration(uptimeConfig.PingTimeoutSeconds * int64(time.Second))
|
||||||
|
|
||||||
var cameraMonitor CameraMonitor = NewCameraMonitor(pingInterval, pingTimeout, uptimeConfig.ConsecutiveDownThreshold, notify.NewNtfyNotifier())
|
var cameraMonitor CameraMonitor = NewCameraMonitor(pingInterval, pingTimeout, uptimeConfig.ConsecutiveDownThreshold, uptimeConfig.NotificationRepeatThreshold, notify.NewNtfyNotifier())
|
||||||
cameraMonitor.Run(uptimeConfig.Cameras)
|
cameraMonitor.Run(uptimeConfig.Cameras)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,41 +16,37 @@ type CameraMonitor struct {
|
||||||
pingInterval time.Duration
|
pingInterval time.Duration
|
||||||
pingTimeout time.Duration
|
pingTimeout time.Duration
|
||||||
consecutiveDownThreshold int
|
consecutiveDownThreshold int
|
||||||
|
notificationRepeatThreshold int
|
||||||
downtime map[string]int
|
downtime map[string]int
|
||||||
notify.Notifier
|
notify.Notifier
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCameraMonitor(pingInterval time.Duration, pingTimeout time.Duration, consecutiveDownThreshold int, notifier notify.Notifier) CameraMonitor {
|
func NewCameraMonitor(pingInterval time.Duration, pingTimeout time.Duration, consecutiveDownThreshold int, notificationRepeatThreshold int, notifier notify.Notifier) CameraMonitor {
|
||||||
return CameraMonitor{
|
return CameraMonitor{
|
||||||
pingInterval: pingInterval,
|
pingInterval: pingInterval,
|
||||||
pingTimeout: pingTimeout,
|
pingTimeout: pingTimeout,
|
||||||
consecutiveDownThreshold: consecutiveDownThreshold,
|
consecutiveDownThreshold: consecutiveDownThreshold,
|
||||||
|
notificationRepeatThreshold: notificationRepeatThreshold,
|
||||||
downtime: make(map[string]int),
|
downtime: make(map[string]int),
|
||||||
Notifier: notifier,
|
Notifier: notifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c CameraMonitor) onCameraUp(camera string) {
|
|
||||||
c.SendNotification(camera, true)
|
|
||||||
slog.Info(fmt.Sprintf("%s camera is back online!", camera))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c CameraMonitor) onCameraDown(camera string) {
|
|
||||||
c.SendNotification(camera, false)
|
|
||||||
slog.Info(fmt.Sprintf("%s camera is offline!", camera))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c CameraMonitor) onCameraPingResult(camera string, online bool) {
|
func (c CameraMonitor) onCameraPingResult(camera string, online bool) {
|
||||||
if online {
|
if online {
|
||||||
if c.downtime[camera] >= c.consecutiveDownThreshold {
|
if c.downtime[camera] >= c.consecutiveDownThreshold {
|
||||||
c.onCameraUp(camera)
|
c.SendNotification(camera, true)
|
||||||
|
slog.Info(fmt.Sprintf("%s camera is back online!", camera))
|
||||||
}
|
}
|
||||||
c.downtime[camera] = 0
|
c.downtime[camera] = 0
|
||||||
} else {
|
} else {
|
||||||
c.downtime[camera] += 1
|
c.downtime[camera] += 1
|
||||||
if c.downtime[camera] == c.consecutiveDownThreshold {
|
if c.downtime[camera] == c.consecutiveDownThreshold {
|
||||||
c.onCameraDown(camera)
|
c.SendNotification(camera, false)
|
||||||
|
slog.Info(fmt.Sprintf("%s camera is offline!", camera))
|
||||||
|
} else if c.notificationRepeatThreshold >= c.consecutiveDownThreshold && c.downtime[camera]%c.notificationRepeatThreshold == c.consecutiveDownThreshold {
|
||||||
|
c.SendNotification(camera, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Notifier interface {
|
type Notifier interface {
|
||||||
SendNotification(camera string, online bool)
|
SendNotification(camera string, online bool)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package notify
|
package notify
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type NtfyNotifier struct {
|
type NtfyNotifier struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ping
|
||||||
|
|
||||||
import "os/exec"
|
import "os/exec"
|
||||||
|
|
||||||
|
|
||||||
func IPPing(host string) bool {
|
func IPPing(host string) bool {
|
||||||
var cmd = exec.Command("ping", "-w", "3", "-c", "1", host)
|
var cmd = exec.Command("ping", "-w", "3", "-c", "1", host)
|
||||||
var err = cmd.Run()
|
var err = cmd.Run()
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ping
|
||||||
|
|
||||||
import "os/exec"
|
import "os/exec"
|
||||||
|
|
||||||
|
|
||||||
func VideoPing(url string) bool {
|
func VideoPing(url string) bool {
|
||||||
var cmd = exec.Command("ffprobe", "-rtsp_transport", "tcp", "-i", url, "-timeout", "10000000")
|
var cmd = exec.Command("ffprobe", "-rtsp_transport", "tcp", "-i", url, "-timeout", "10000000")
|
||||||
var err = cmd.Run()
|
var err = cmd.Run()
|
||||||
|
|
Loading…
Reference in New Issue