mirror of
https://github.com/kerberos-io/agent.git
synced 2025-10-26 01:30:22 +08:00
add onvif verify option + improve streaming logic + reconnect websocket
This commit is contained in:
@@ -244,6 +244,40 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/onvif/verify": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Bearer": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Will verify the ONVIF connectivity.",
|
||||||
|
"tags": [
|
||||||
|
"config"
|
||||||
|
],
|
||||||
|
"summary": "Will verify the ONVIF connectivity.",
|
||||||
|
"operationId": "verify-onvif",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Camera Config",
|
||||||
|
"name": "cameraConfig",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.IPCamera"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/persistence/verify": {
|
"/api/persistence/verify": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -347,9 +381,15 @@ const docTemplate = `{
|
|||||||
"ipcamera": {
|
"ipcamera": {
|
||||||
"$ref": "#/definitions/models.IPCamera"
|
"$ref": "#/definitions/models.IPCamera"
|
||||||
},
|
},
|
||||||
|
"liveview": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"maxlengthrecording": {
|
"maxlengthrecording": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"motion": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -365,6 +405,12 @@ const docTemplate = `{
|
|||||||
"raspicamera": {
|
"raspicamera": {
|
||||||
"$ref": "#/definitions/models.RaspiCamera"
|
"$ref": "#/definitions/models.RaspiCamera"
|
||||||
},
|
},
|
||||||
|
"recording": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"snapshots": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"transcodingresolution": {
|
"transcodingresolution": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -391,6 +437,12 @@ const docTemplate = `{
|
|||||||
"condition_uri": {
|
"condition_uri": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"dropbox": {
|
||||||
|
"$ref": "#/definitions/models.Dropbox"
|
||||||
|
},
|
||||||
|
"friendly_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"heartbeaturi": {
|
"heartbeaturi": {
|
||||||
"description": "obsolete",
|
"description": "obsolete",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -434,6 +486,9 @@ const docTemplate = `{
|
|||||||
"region": {
|
"region": {
|
||||||
"$ref": "#/definitions/models.Region"
|
"$ref": "#/definitions/models.Region"
|
||||||
},
|
},
|
||||||
|
"remove_after_upload": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"s3": {
|
"s3": {
|
||||||
"$ref": "#/definitions/models.S3"
|
"$ref": "#/definitions/models.S3"
|
||||||
},
|
},
|
||||||
@@ -477,6 +532,17 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"models.Dropbox": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"access_token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"directory": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"models.IPCamera": {
|
"models.IPCamera": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -484,7 +550,7 @@ const docTemplate = `{
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"onvif": {
|
"onvif": {
|
||||||
"type": "boolean"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"onvif_password": {
|
"onvif_password": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|||||||
@@ -236,6 +236,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/onvif/verify": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Bearer": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Will verify the ONVIF connectivity.",
|
||||||
|
"tags": [
|
||||||
|
"config"
|
||||||
|
],
|
||||||
|
"summary": "Will verify the ONVIF connectivity.",
|
||||||
|
"operationId": "verify-onvif",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Camera Config",
|
||||||
|
"name": "cameraConfig",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.IPCamera"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/persistence/verify": {
|
"/api/persistence/verify": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -339,9 +373,15 @@
|
|||||||
"ipcamera": {
|
"ipcamera": {
|
||||||
"$ref": "#/definitions/models.IPCamera"
|
"$ref": "#/definitions/models.IPCamera"
|
||||||
},
|
},
|
||||||
|
"liveview": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"maxlengthrecording": {
|
"maxlengthrecording": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"motion": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -357,6 +397,12 @@
|
|||||||
"raspicamera": {
|
"raspicamera": {
|
||||||
"$ref": "#/definitions/models.RaspiCamera"
|
"$ref": "#/definitions/models.RaspiCamera"
|
||||||
},
|
},
|
||||||
|
"recording": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"snapshots": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"transcodingresolution": {
|
"transcodingresolution": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -383,6 +429,12 @@
|
|||||||
"condition_uri": {
|
"condition_uri": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"dropbox": {
|
||||||
|
"$ref": "#/definitions/models.Dropbox"
|
||||||
|
},
|
||||||
|
"friendly_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"heartbeaturi": {
|
"heartbeaturi": {
|
||||||
"description": "obsolete",
|
"description": "obsolete",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -426,6 +478,9 @@
|
|||||||
"region": {
|
"region": {
|
||||||
"$ref": "#/definitions/models.Region"
|
"$ref": "#/definitions/models.Region"
|
||||||
},
|
},
|
||||||
|
"remove_after_upload": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"s3": {
|
"s3": {
|
||||||
"$ref": "#/definitions/models.S3"
|
"$ref": "#/definitions/models.S3"
|
||||||
},
|
},
|
||||||
@@ -469,6 +524,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"models.Dropbox": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"access_token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"directory": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"models.IPCamera": {
|
"models.IPCamera": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -476,7 +542,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"onvif": {
|
"onvif": {
|
||||||
"type": "boolean"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"onvif_password": {
|
"onvif_password": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|||||||
@@ -44,8 +44,12 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
ipcamera:
|
ipcamera:
|
||||||
$ref: '#/definitions/models.IPCamera'
|
$ref: '#/definitions/models.IPCamera'
|
||||||
|
liveview:
|
||||||
|
type: string
|
||||||
maxlengthrecording:
|
maxlengthrecording:
|
||||||
type: integer
|
type: integer
|
||||||
|
motion:
|
||||||
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
pixelChangeThreshold:
|
pixelChangeThreshold:
|
||||||
@@ -56,6 +60,10 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
raspicamera:
|
raspicamera:
|
||||||
$ref: '#/definitions/models.RaspiCamera'
|
$ref: '#/definitions/models.RaspiCamera'
|
||||||
|
recording:
|
||||||
|
type: string
|
||||||
|
snapshots:
|
||||||
|
type: string
|
||||||
transcodingresolution:
|
transcodingresolution:
|
||||||
type: integer
|
type: integer
|
||||||
transcodingwebrtc:
|
transcodingwebrtc:
|
||||||
@@ -73,6 +81,10 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
condition_uri:
|
condition_uri:
|
||||||
type: string
|
type: string
|
||||||
|
dropbox:
|
||||||
|
$ref: '#/definitions/models.Dropbox'
|
||||||
|
friendly_name:
|
||||||
|
type: string
|
||||||
heartbeaturi:
|
heartbeaturi:
|
||||||
description: obsolete
|
description: obsolete
|
||||||
type: string
|
type: string
|
||||||
@@ -102,6 +114,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
region:
|
region:
|
||||||
$ref: '#/definitions/models.Region'
|
$ref: '#/definitions/models.Region'
|
||||||
|
remove_after_upload:
|
||||||
|
type: string
|
||||||
s3:
|
s3:
|
||||||
$ref: '#/definitions/models.S3'
|
$ref: '#/definitions/models.S3'
|
||||||
stunuri:
|
stunuri:
|
||||||
@@ -130,12 +144,19 @@ definitions:
|
|||||||
"y":
|
"y":
|
||||||
type: number
|
type: number
|
||||||
type: object
|
type: object
|
||||||
|
models.Dropbox:
|
||||||
|
properties:
|
||||||
|
access_token:
|
||||||
|
type: string
|
||||||
|
directory:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
models.IPCamera:
|
models.IPCamera:
|
||||||
properties:
|
properties:
|
||||||
fps:
|
fps:
|
||||||
type: string
|
type: string
|
||||||
onvif:
|
onvif:
|
||||||
type: boolean
|
type: string
|
||||||
onvif_password:
|
onvif_password:
|
||||||
type: string
|
type: string
|
||||||
onvif_username:
|
onvif_username:
|
||||||
@@ -414,6 +435,27 @@ paths:
|
|||||||
summary: Get Authorization token.
|
summary: Get Authorization token.
|
||||||
tags:
|
tags:
|
||||||
- authentication
|
- authentication
|
||||||
|
/api/onvif/verify:
|
||||||
|
post:
|
||||||
|
description: Will verify the ONVIF connectivity.
|
||||||
|
operationId: verify-onvif
|
||||||
|
parameters:
|
||||||
|
- description: Camera Config
|
||||||
|
in: body
|
||||||
|
name: cameraConfig
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.IPCamera'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.APIResponse'
|
||||||
|
security:
|
||||||
|
- Bearer: []
|
||||||
|
summary: Will verify the ONVIF connectivity.
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
/api/persistence/verify:
|
/api/persistence/verify:
|
||||||
post:
|
post:
|
||||||
description: Will verify the persistence.
|
description: Will verify the persistence.
|
||||||
|
|||||||
@@ -273,7 +273,8 @@ loop:
|
|||||||
// We'll check which mode is enabled for the camera.
|
// We'll check which mode is enabled for the camera.
|
||||||
onvifEnabled := "false"
|
onvifEnabled := "false"
|
||||||
if config.Capture.IPCamera.ONVIFXAddr != "" {
|
if config.Capture.IPCamera.ONVIFXAddr != "" {
|
||||||
device, err := onvif.ConnectToOnvifDevice(configuration)
|
cameraConfiguration := configuration.Config.Capture.IPCamera
|
||||||
|
device, err := onvif.ConnectToOnvifDevice(&cameraConfiguration)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
capabilities := onvif.GetCapabilitiesFromDevice(device)
|
capabilities := onvif.GetCapabilitiesFromDevice(device)
|
||||||
for _, v := range capabilities {
|
for _, v := range capabilities {
|
||||||
|
|||||||
@@ -85,9 +85,6 @@ func Bootstrap(configuration *models.Configuration, communication *models.Commun
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// We will reconfigure or restart the agent, we will mark the agent as not connected.
|
|
||||||
communication.CameraConnected = false
|
|
||||||
|
|
||||||
// We will re open the configuration, might have changed :O!
|
// We will re open the configuration, might have changed :O!
|
||||||
OpenConfig(configuration)
|
OpenConfig(configuration)
|
||||||
|
|
||||||
@@ -224,9 +221,6 @@ func RunAgent(configuration *models.Configuration, communication *models.Communi
|
|||||||
subQueue.WriteHeader(subStreams)
|
subQueue.WriteHeader(subStreams)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reach this point, we have a working RTSP connection.
|
|
||||||
communication.CameraConnected = true
|
|
||||||
|
|
||||||
// Handle the camera stream
|
// Handle the camera stream
|
||||||
go capture.HandleStream(infile, queue, communication)
|
go capture.HandleStream(infile, queue, communication)
|
||||||
|
|
||||||
@@ -273,12 +267,18 @@ func RunAgent(configuration *models.Configuration, communication *models.Communi
|
|||||||
// Handle ONVIF actions
|
// Handle ONVIF actions
|
||||||
go onvif.HandleONVIFActions(configuration, communication)
|
go onvif.HandleONVIFActions(configuration, communication)
|
||||||
|
|
||||||
|
// If we reach this point, we have a working RTSP connection.
|
||||||
|
communication.CameraConnected = true
|
||||||
|
|
||||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
// This will go into a blocking state, once this channel is triggered
|
// This will go into a blocking state, once this channel is triggered
|
||||||
// the agent will cleanup and restart.
|
// the agent will cleanup and restart.
|
||||||
|
|
||||||
status = <-communication.HandleBootstrap
|
status = <-communication.HandleBootstrap
|
||||||
|
|
||||||
|
// If we reach this point, we are stopping the stream.
|
||||||
|
communication.CameraConnected = false
|
||||||
|
|
||||||
// Cancel the main context, this will stop all the other goroutines.
|
// Cancel the main context, this will stop all the other goroutines.
|
||||||
(*communication.CancelContext)()
|
(*communication.CancelContext)()
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
type APIResponse struct {
|
type APIResponse struct {
|
||||||
Data interface{} `json:"data" bson:"data"`
|
Data interface{} `json:"data" bson:"data"`
|
||||||
Message interface{} `json:"message" bson:"message"`
|
Message interface{} `json:"message" bson:"message"`
|
||||||
|
PTZFunctions interface{} `json:"ptz_functions" bson:"ptz_functions"`
|
||||||
|
CanZoom bool `json:"can_zoom" bson:"can_zoom"`
|
||||||
|
CanPanTilt bool `json:"can_pan_tilt" bson:"can_pan_tilt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OnvifCredentials struct {
|
type OnvifCredentials struct {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/kerberos-io/agent/machinery/src/log"
|
"github.com/kerberos-io/agent/machinery/src/log"
|
||||||
"github.com/kerberos-io/agent/machinery/src/models"
|
"github.com/kerberos-io/agent/machinery/src/models"
|
||||||
"github.com/kerberos-io/onvif/media"
|
"github.com/kerberos-io/onvif/media"
|
||||||
@@ -31,7 +32,8 @@ func HandleONVIFActions(configuration *models.Configuration, communication *mode
|
|||||||
json.Unmarshal(b, &ptzAction)
|
json.Unmarshal(b, &ptzAction)
|
||||||
|
|
||||||
// Connect to Onvif device
|
// Connect to Onvif device
|
||||||
device, err := ConnectToOnvifDevice(configuration)
|
cameraConfiguration := configuration.Config.Capture.IPCamera
|
||||||
|
device, err := ConnectToOnvifDevice(&cameraConfiguration)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
// Get token from the first profile
|
// Get token from the first profile
|
||||||
@@ -39,7 +41,7 @@ func HandleONVIFActions(configuration *models.Configuration, communication *mode
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
// Get the configurations from the device
|
// Get the configurations from the device
|
||||||
configurations, err := GetConfigurationsFromDevice(device)
|
configurations, err := GetPTZConfigurationsFromDevice(device)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
@@ -100,16 +102,13 @@ func HandleONVIFActions(configuration *models.Configuration, communication *mode
|
|||||||
log.Log.Debug("HandleONVIFActions: finished")
|
log.Log.Debug("HandleONVIFActions: finished")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConnectToOnvifDevice(configuration *models.Configuration) (*onvif.Device, error) {
|
func ConnectToOnvifDevice(cameraConfiguration *models.IPCamera) (*onvif.Device, error) {
|
||||||
log.Log.Debug("ConnectToOnvifDevice: started")
|
log.Log.Debug("ConnectToOnvifDevice: started")
|
||||||
|
|
||||||
config := configuration.Config
|
|
||||||
|
|
||||||
// Get the capabilities of the ONVIF device
|
|
||||||
device, err := onvif.NewDevice(onvif.DeviceParams{
|
device, err := onvif.NewDevice(onvif.DeviceParams{
|
||||||
Xaddr: config.Capture.IPCamera.ONVIFXAddr,
|
Xaddr: cameraConfiguration.ONVIFXAddr,
|
||||||
Username: config.Capture.IPCamera.ONVIFUsername,
|
Username: cameraConfiguration.ONVIFUsername,
|
||||||
Password: config.Capture.IPCamera.ONVIFPassword,
|
Password: cameraConfiguration.ONVIFPassword,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -154,11 +153,11 @@ func GetTokenFromProfile(device *onvif.Device, profileId int) (xsd.ReferenceToke
|
|||||||
return profileToken, err
|
return profileToken, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConfigurationsFromDevice(device *onvif.Device) (ptz.GetConfigurationsResponse, error) {
|
func GetPTZConfigurationsFromDevice(device *onvif.Device) (ptz.GetConfigurationsResponse, error) {
|
||||||
// We'll try to receive the PTZ configurations from the server
|
// We'll try to receive the PTZ configurations from the server
|
||||||
var configurations ptz.GetConfigurationsResponse
|
var configurations ptz.GetConfigurationsResponse
|
||||||
|
|
||||||
// Get the configurations from the device
|
// Get the PTZ configurations from the device
|
||||||
resp, err := device.CallMethod(ptz.GetConfigurations{})
|
resp, err := device.CallMethod(ptz.GetConfigurations{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@@ -167,11 +166,11 @@ func GetConfigurationsFromDevice(device *onvif.Device) (ptz.GetConfigurationsRes
|
|||||||
stringBody := string(b)
|
stringBody := string(b)
|
||||||
decodedXML, et, err := getXMLNode(stringBody, "GetConfigurationsResponse")
|
decodedXML, et, err := getXMLNode(stringBody, "GetConfigurationsResponse")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Log.Error("GetConfigurationsFromDevice: " + err.Error())
|
log.Log.Error("GetPTZConfigurationsFromDevice: " + err.Error())
|
||||||
return configurations, err
|
return configurations, err
|
||||||
} else {
|
} else {
|
||||||
if err := decodedXML.DecodeElement(&configurations, et); err != nil {
|
if err := decodedXML.DecodeElement(&configurations, et); err != nil {
|
||||||
log.Log.Error("GetConfigurationsFromDevice: " + err.Error())
|
log.Log.Error("GetPTZConfigurationsFromDevice: " + err.Error())
|
||||||
return configurations, err
|
return configurations, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,3 +316,89 @@ func getXMLNode(xmlBody string, nodeName string) (*xml.Decoder, *xml.StartElemen
|
|||||||
}
|
}
|
||||||
return nil, nil, errors.New("error in NodeName - username and password might be wrong")
|
return nil, nil, errors.New("error in NodeName - username and password might be wrong")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetPTZFunctionsFromDevice(configurations ptz.GetConfigurationsResponse) ([]string, bool, bool) {
|
||||||
|
var functions []string
|
||||||
|
canZoom := false
|
||||||
|
canPanTilt := false
|
||||||
|
|
||||||
|
if configurations.PTZConfiguration.DefaultAbsolutePantTiltPositionSpace != "" {
|
||||||
|
functions = append(functions, "AbsolutePanTiltMove")
|
||||||
|
canPanTilt = true
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultAbsoluteZoomPositionSpace != "" {
|
||||||
|
functions = append(functions, "AbsoluteZoomMove")
|
||||||
|
canZoom = true
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultRelativePanTiltTranslationSpace != "" {
|
||||||
|
functions = append(functions, "RelativePanTiltMove")
|
||||||
|
canPanTilt = true
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultRelativeZoomTranslationSpace != "" {
|
||||||
|
functions = append(functions, "RelativeZoomMove")
|
||||||
|
canZoom = true
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultContinuousPanTiltVelocitySpace != "" {
|
||||||
|
functions = append(functions, "ContinuousPanTiltMove")
|
||||||
|
canPanTilt = true
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultContinuousZoomVelocitySpace != "" {
|
||||||
|
functions = append(functions, "ContinuousZoomMove")
|
||||||
|
canZoom = true
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultPTZSpeed != nil {
|
||||||
|
functions = append(functions, "PTZSpeed")
|
||||||
|
}
|
||||||
|
if configurations.PTZConfiguration.DefaultPTZTimeout != "" {
|
||||||
|
functions = append(functions, "PTZTimeout")
|
||||||
|
}
|
||||||
|
|
||||||
|
return functions, canZoom, canPanTilt
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyOnvifConnection godoc
|
||||||
|
// @Router /api/onvif/verify [post]
|
||||||
|
// @ID verify-onvif
|
||||||
|
// @Security Bearer
|
||||||
|
// @securityDefinitions.apikey Bearer
|
||||||
|
// @in header
|
||||||
|
// @name Authorization
|
||||||
|
// @Tags config
|
||||||
|
// @Param cameraConfig body models.IPCamera true "Camera Config"
|
||||||
|
// @Summary Will verify the ONVIF connectivity.
|
||||||
|
// @Description Will verify the ONVIF connectivity.
|
||||||
|
// @Success 200 {object} models.APIResponse
|
||||||
|
func VerifyOnvifConnection(c *gin.Context) {
|
||||||
|
var cameraConfig models.IPCamera
|
||||||
|
err := c.BindJSON(&cameraConfig)
|
||||||
|
if err == nil {
|
||||||
|
device, err := ConnectToOnvifDevice(&cameraConfig)
|
||||||
|
if err == nil {
|
||||||
|
// Get the list of configurations
|
||||||
|
configurations, err := GetPTZConfigurationsFromDevice(device)
|
||||||
|
if err == nil {
|
||||||
|
|
||||||
|
// Check if can zoom and/or pan/tilt is supported
|
||||||
|
ptzFunctions, canZoom, canPanTilt := GetPTZFunctionsFromDevice(configurations)
|
||||||
|
c.JSON(200, models.APIResponse{
|
||||||
|
Data: device,
|
||||||
|
PTZFunctions: ptzFunctions,
|
||||||
|
CanZoom: canZoom,
|
||||||
|
CanPanTilt: canPanTilt,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
c.JSON(400, models.APIResponse{
|
||||||
|
Message: "Something went wrong while getting the configurations " + err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.JSON(400, models.APIResponse{
|
||||||
|
Message: "Something went wrong while verifying the ONVIF connection " + err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.JSON(400, models.APIResponse{
|
||||||
|
Message: "Something went wrong while receiving the config " + err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ func LoginToOnvif(c *gin.Context) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
device, err := onvif.ConnectToOnvifDevice(configuration)
|
cameraConfiguration := configuration.Config.Capture.IPCamera
|
||||||
|
device, err := onvif.ConnectToOnvifDevice(&cameraConfiguration)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"device": device,
|
"device": device,
|
||||||
@@ -85,7 +86,8 @@ func GetOnvifCapabilities(c *gin.Context) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
device, err := onvif.ConnectToOnvifDevice(configuration)
|
cameraConfiguration := configuration.Config.Capture.IPCamera
|
||||||
|
device, err := onvif.ConnectToOnvifDevice(&cameraConfiguration)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"capabilities": onvif.GetCapabilitiesFromDevice(device),
|
"capabilities": onvif.GetCapabilitiesFromDevice(device),
|
||||||
@@ -128,7 +130,8 @@ func DoOnvifPanTilt(c *gin.Context) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
device, err := onvif.ConnectToOnvifDevice(configuration)
|
cameraConfiguration := configuration.Config.Capture.IPCamera
|
||||||
|
device, err := onvif.ConnectToOnvifDevice(&cameraConfiguration)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Get token from the first profile
|
// Get token from the first profile
|
||||||
@@ -137,13 +140,13 @@ func DoOnvifPanTilt(c *gin.Context) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
// Get the configurations from the device
|
// Get the configurations from the device
|
||||||
configurations, err := onvif.GetConfigurationsFromDevice(device)
|
ptzConfigurations, err := onvif.GetPTZConfigurationsFromDevice(device)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
pan := onvifPanTilt.Pan
|
pan := onvifPanTilt.Pan
|
||||||
tilt := onvifPanTilt.Tilt
|
tilt := onvifPanTilt.Tilt
|
||||||
err := onvif.ContinuousPanTilt(device, configurations, token, pan, tilt)
|
err := onvif.ContinuousPanTilt(device, ptzConfigurations, token, pan, tilt)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.JSON(200, models.APIResponse{
|
c.JSON(200, models.APIResponse{
|
||||||
Message: "Successfully pan/tilted the camera",
|
Message: "Successfully pan/tilted the camera",
|
||||||
@@ -201,7 +204,8 @@ func DoOnvifZoom(c *gin.Context) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
device, err := onvif.ConnectToOnvifDevice(configuration)
|
cameraConfiguration := configuration.Config.Capture.IPCamera
|
||||||
|
device, err := onvif.ConnectToOnvifDevice(&cameraConfiguration)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Get token from the first profile
|
// Get token from the first profile
|
||||||
@@ -209,13 +213,13 @@ func DoOnvifZoom(c *gin.Context) {
|
|||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
// Get the configurations from the device
|
// Get the PTZ configurations from the device
|
||||||
configurations, err := onvif.GetConfigurationsFromDevice(device)
|
ptzConfigurations, err := onvif.GetPTZConfigurationsFromDevice(device)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
zoom := onvifZoom.Zoom
|
zoom := onvifZoom.Zoom
|
||||||
err := onvif.ContinuousZoom(device, configurations, token, zoom)
|
err := onvif.ContinuousZoom(device, ptzConfigurations, token, zoom)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.JSON(200, models.APIResponse{
|
c.JSON(200, models.APIResponse{
|
||||||
Message: "Successfully zoomed the camera",
|
Message: "Successfully zoomed the camera",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
jwt "github.com/appleboy/gin-jwt/v2"
|
jwt "github.com/appleboy/gin-jwt/v2"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/kerberos-io/agent/machinery/src/capture"
|
"github.com/kerberos-io/agent/machinery/src/capture"
|
||||||
|
"github.com/kerberos-io/agent/machinery/src/onvif"
|
||||||
"github.com/kerberos-io/agent/machinery/src/routers/websocket"
|
"github.com/kerberos-io/agent/machinery/src/routers/websocket"
|
||||||
|
|
||||||
"github.com/kerberos-io/agent/machinery/src/cloud"
|
"github.com/kerberos-io/agent/machinery/src/cloud"
|
||||||
@@ -196,6 +197,10 @@ func AddRoutes(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware, configuratio
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
api.POST("/onvif/verify", func(c *gin.Context) {
|
||||||
|
onvif.VerifyOnvifConnection(c)
|
||||||
|
})
|
||||||
|
|
||||||
api.POST("/hub/verify", func(c *gin.Context) {
|
api.POST("/hub/verify", func(c *gin.Context) {
|
||||||
cloud.VerifyHub(c)
|
cloud.VerifyHub(c)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ func WebsocketHandler(c *gin.Context, communication *models.Communication) {
|
|||||||
w := c.Writer
|
w := c.Writer
|
||||||
r := c.Request
|
r := c.Request
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
|
||||||
// error handling here
|
// error handling here
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
@@ -83,28 +84,29 @@ func WebsocketHandler(c *gin.Context, communication *models.Communication) {
|
|||||||
_, exists := sockets[clientID].Cancels["stream-sd"]
|
_, exists := sockets[clientID].Cancels["stream-sd"]
|
||||||
if exists {
|
if exists {
|
||||||
sockets[clientID].Cancels["stream-sd"]()
|
sockets[clientID].Cancels["stream-sd"]()
|
||||||
delete(sockets[clientID].Cancels, "stream-sd")
|
|
||||||
} else {
|
} else {
|
||||||
log.Log.Error("Streaming sd does not exists for " + clientID)
|
log.Log.Error("Streaming sd does not exists for " + clientID)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "stream-sd":
|
case "stream-sd":
|
||||||
startStrean := Message{
|
if communication.CameraConnected {
|
||||||
ClientID: clientID,
|
_, exists := sockets[clientID].Cancels["stream-sd"]
|
||||||
MessageType: "stream-sd",
|
if exists {
|
||||||
Message: map[string]string{
|
log.Log.Info("Already streaming sd for " + clientID)
|
||||||
"message": "Start streaming low resolution",
|
} else {
|
||||||
},
|
startStream := Message{
|
||||||
}
|
ClientID: clientID,
|
||||||
sockets[clientID].WriteJson(startStrean)
|
MessageType: "stream-sd",
|
||||||
|
Message: map[string]string{
|
||||||
|
"message": "Start streaming low resolution",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
sockets[clientID].WriteJson(startStream)
|
||||||
|
|
||||||
_, exists := sockets[clientID].Cancels["stream-sd"]
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
if exists {
|
sockets[clientID].Cancels["stream-sd"] = cancel
|
||||||
log.Log.Info("Already streaming sd for " + clientID)
|
go ForwardSDStream(ctx, clientID, sockets[clientID], communication)
|
||||||
} else {
|
}
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
sockets[clientID].Cancels["stream-sd"] = cancel
|
|
||||||
go ForwardSDStream(ctx, clientID, sockets[clientID], communication)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,5 +175,14 @@ logreader:
|
|||||||
|
|
||||||
frame.Free()
|
frame.Free()
|
||||||
|
|
||||||
|
// Close socket for streaming
|
||||||
|
_, exists := connection.Cancels["stream-sd"]
|
||||||
|
if exists {
|
||||||
|
delete(connection.Cancels, "stream-sd")
|
||||||
|
} else {
|
||||||
|
log.Log.Error("Streaming sd does not exists for " + clientID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send stop streaming message
|
||||||
log.Log.Info("ForwardSDStream: stop sending streaming over websocket")
|
log.Log.Info("ForwardSDStream: stop sending streaming over websocket")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"private": false,
|
"private": false,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@giantmachines/redux-websocket": "^1.5.1",
|
"@giantmachines/redux-websocket": "^1.5.1",
|
||||||
"@kerberos-io/ui": "^1.72.0",
|
"@kerberos-io/ui": "^1.76.0",
|
||||||
"@material-ui/core": "^4.12.4",
|
"@material-ui/core": "^4.12.4",
|
||||||
"@material-ui/icons": "^4.11.3",
|
"@material-ui/icons": "^4.11.3",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "Konfigurieren"
|
"configure": "Konfigurieren"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Speichern"
|
"save": "Speichern",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "Profil",
|
"profile": "Profil",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "Beim überprüfen der Speichereinstellungen ist ein Fehler aufgetreten",
|
"verify_persistence_error": "Beim überprüfen der Speichereinstellungen ist ein Fehler aufgetreten",
|
||||||
"verify_camera": "Überprüfen der Kameraeinstellungen.",
|
"verify_camera": "Überprüfen der Kameraeinstellungen.",
|
||||||
"verify_camera_success": "Die Kameraeinstellungen wurden erfolgreich überprüft.",
|
"verify_camera_success": "Die Kameraeinstellungen wurden erfolgreich überprüft.",
|
||||||
"verify_camera_error": "Beim überprüfen der Kameraeinstellungen ist ein Fehler aufgetreten"
|
"verify_camera_error": "Beim überprüfen der Kameraeinstellungen ist ein Fehler aufgetreten",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "Allgemein",
|
"general": "Allgemein",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "Die Region in der die Aufnahmen gespeichert werden sollen.",
|
"kerberoshub_description_region": "Die Region in der die Aufnahmen gespeichert werden sollen.",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "Der Bucket in dem die Aufnahmen gespeichert werden.",
|
"kerberoshub_description_bucket": "Der Bucket in dem die Aufnahmen gespeichert werden.",
|
||||||
"kerberoshub_username": "Benutzername/Verzeichnis",
|
"kerberoshub_username": "Benutzername/Verzeichnis (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "Der Benutzername des Kerberos Hub Accounts.",
|
"kerberoshub_description_username": "Der Benutzername des Kerberos Hub Accounts.",
|
||||||
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
||||||
"kerberosvault_description_apiurl": "Die Kerberos Vault API URL.",
|
"kerberosvault_description_apiurl": "Die Kerberos Vault API URL.",
|
||||||
"kerberosvault_provider": "Anbieter",
|
"kerberosvault_provider": "Anbieter",
|
||||||
"kerberosvault_description_provider": "Der Anbieter zu dem die Aufnahmen gesendet werden.",
|
"kerberosvault_description_provider": "Der Anbieter zu dem die Aufnahmen gesendet werden.",
|
||||||
"kerberosvault_directory": "Verzeichnis",
|
"kerberosvault_directory": "Verzeichnis (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Das Uneterverzeichnis in dem die Aufnahmen gespeichert werden sollen.",
|
"kerberosvault_description_directory": "Das Uneterverzeichnis in dem die Aufnahmen gespeichert werden sollen.",
|
||||||
"kerberosvault_accesskey": "Zugriffsschlüssel",
|
"kerberosvault_accesskey": "Zugriffsschlüssel",
|
||||||
"kerberosvault_description_accesskey": "Der Zugriffsschlüssel des Kerberos Vault Accounts..",
|
"kerberosvault_description_accesskey": "Der Zugriffsschlüssel des Kerberos Vault Accounts..",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "Configure"
|
"configure": "Configure"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Save"
|
"save": "Save",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "Something went wrong while verifying the persistence",
|
"verify_persistence_error": "Something went wrong while verifying the persistence",
|
||||||
"verify_camera": "Verifying your camera settings.",
|
"verify_camera": "Verifying your camera settings.",
|
||||||
"verify_camera_success": "Camera settings are successfully verified.",
|
"verify_camera_success": "Camera settings are successfully verified.",
|
||||||
"verify_camera_error": "Something went wrong while verifying the camera settings"
|
"verify_camera_error": "Something went wrong while verifying the camera settings",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "General",
|
"general": "General",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "The region we are storing our recordings in.",
|
"kerberoshub_description_region": "The region we are storing our recordings in.",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "The bucket we are storing our recordings in.",
|
"kerberoshub_description_bucket": "The bucket we are storing our recordings in.",
|
||||||
"kerberoshub_username": "Username/Directory",
|
"kerberoshub_username": "Username/Directory (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "The username of your Kerberos Hub account.",
|
"kerberoshub_description_username": "The username of your Kerberos Hub account.",
|
||||||
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
||||||
"kerberosvault_description_apiurl": "The Kerberos Vault API",
|
"kerberosvault_description_apiurl": "The Kerberos Vault API",
|
||||||
"kerberosvault_provider": "Provider",
|
"kerberosvault_provider": "Provider",
|
||||||
"kerberosvault_description_provider": "The provider to which your recordings will be send.",
|
"kerberosvault_description_provider": "The provider to which your recordings will be send.",
|
||||||
"kerberosvault_directory": "Directory",
|
"kerberosvault_directory": "Directory (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Sub directory the recordings will be stored in your provider.",
|
"kerberosvault_description_directory": "Sub directory the recordings will be stored in your provider.",
|
||||||
"kerberosvault_accesskey": "Access key",
|
"kerberosvault_accesskey": "Access key",
|
||||||
"kerberosvault_description_accesskey": "The access key of your Kerberos Vault account.",
|
"kerberosvault_description_accesskey": "The access key of your Kerberos Vault account.",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "Configure"
|
"configure": "Configure"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Save"
|
"save": "Save",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "Perfil",
|
"profile": "Perfil",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "Something went wrong while verifying the persistence",
|
"verify_persistence_error": "Something went wrong while verifying the persistence",
|
||||||
"verify_camera": "Verifying your camera settings.",
|
"verify_camera": "Verifying your camera settings.",
|
||||||
"verify_camera_success": "Camera settings are successfully verified.",
|
"verify_camera_success": "Camera settings are successfully verified.",
|
||||||
"verify_camera_error": "Something went wrong while verifying the camera settings"
|
"verify_camera_error": "Something went wrong while verifying the camera settings",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "General",
|
"general": "General",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "The region we are storing our recordings in.",
|
"kerberoshub_description_region": "The region we are storing our recordings in.",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "The bucket we are storing our recordings in.",
|
"kerberoshub_description_bucket": "The bucket we are storing our recordings in.",
|
||||||
"kerberoshub_username": "Username/Directory",
|
"kerberoshub_username": "Username/Directory (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "The username of your Kerberos Hub account.",
|
"kerberoshub_description_username": "The username of your Kerberos Hub account.",
|
||||||
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
||||||
"kerberosvault_description_apiurl": "The Kerberos Vault API",
|
"kerberosvault_description_apiurl": "The Kerberos Vault API",
|
||||||
"kerberosvault_provider": "Provider",
|
"kerberosvault_provider": "Provider",
|
||||||
"kerberosvault_description_provider": "The provider to which your recordings will be send.",
|
"kerberosvault_description_provider": "The provider to which your recordings will be send.",
|
||||||
"kerberosvault_directory": "Directory",
|
"kerberosvault_directory": "Directory (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Sub directory the recordings will be stored in your provider.",
|
"kerberosvault_description_directory": "Sub directory the recordings will be stored in your provider.",
|
||||||
"kerberosvault_accesskey": "Access key",
|
"kerberosvault_accesskey": "Access key",
|
||||||
"kerberosvault_description_accesskey": "The access key of your Kerberos Vault account.",
|
"kerberosvault_description_accesskey": "The access key of your Kerberos Vault account.",
|
||||||
|
|||||||
@@ -69,7 +69,10 @@
|
|||||||
"verify_persistence_error": "Quelque chose s'est mal déroulé lors de la vérification de la persistance",
|
"verify_persistence_error": "Quelque chose s'est mal déroulé lors de la vérification de la persistance",
|
||||||
"verify_camera": "Vérifier les paramètres de votre caméra.",
|
"verify_camera": "Vérifier les paramètres de votre caméra.",
|
||||||
"verify_camera_success": "Les paramètres de la caméra sont vérifiés avec succès.",
|
"verify_camera_success": "Les paramètres de la caméra sont vérifiés avec succès.",
|
||||||
"verify_camera_error": "Quelque chose s'est mal déroulé lors de la vérification des paramètres de la caméra"
|
"verify_camera_error": "Quelque chose s'est mal déroulé lors de la vérification des paramètres de la caméra",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "Général",
|
"general": "Général",
|
||||||
@@ -186,13 +189,13 @@
|
|||||||
"kerberoshub_description_region": "La région dans laquelle nous stockons vos enregistrements.",
|
"kerberoshub_description_region": "La région dans laquelle nous stockons vos enregistrements.",
|
||||||
"kerberoshub_bucket": "Compartiment",
|
"kerberoshub_bucket": "Compartiment",
|
||||||
"kerberoshub_description_bucket": "Le compartiment dans lequel nous stockons vos enregistrements.",
|
"kerberoshub_description_bucket": "Le compartiment dans lequel nous stockons vos enregistrements.",
|
||||||
"kerberoshub_username": "Utilisateur/Répertoire",
|
"kerberoshub_username": "Utilisateur/Répertoire (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "Le nom d'utilisateur de votre compte Kerberos Hub.",
|
"kerberoshub_description_username": "Le nom d'utilisateur de votre compte Kerberos Hub.",
|
||||||
"kerberosvault_apiurl": "URL de l'API Kerberos Vault",
|
"kerberosvault_apiurl": "URL de l'API Kerberos Vault",
|
||||||
"kerberosvault_description_apiurl": "L'API Kerberos Vault",
|
"kerberosvault_description_apiurl": "L'API Kerberos Vault",
|
||||||
"kerberosvault_provider": "Fournisseur",
|
"kerberosvault_provider": "Fournisseur",
|
||||||
"kerberosvault_description_provider": "Le fournisseur auquel vos enregistrements seront envoyés.",
|
"kerberosvault_description_provider": "Le fournisseur auquel vos enregistrements seront envoyés.",
|
||||||
"kerberosvault_directory": "Répertoire",
|
"kerberosvault_directory": "Répertoire (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Le sous-répertoire dans lequel les enregistrements seront stockés chez votre fournisseur.",
|
"kerberosvault_description_directory": "Le sous-répertoire dans lequel les enregistrements seront stockés chez votre fournisseur.",
|
||||||
"kerberosvault_accesskey": "Clé d'accès",
|
"kerberosvault_accesskey": "Clé d'accès",
|
||||||
"kerberosvault_description_accesskey": "La clé d'accès de votre compte Kerberos Vault.",
|
"kerberosvault_description_accesskey": "La clé d'accès de votre compte Kerberos Vault.",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "設定"
|
"configure": "設定"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "保存"
|
"save": "保存",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "プロフィール",
|
"profile": "プロフィール",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "持続性の検証中に問題が発生しました",
|
"verify_persistence_error": "持続性の検証中に問題が発生しました",
|
||||||
"verify_camera": "カメラの設定を確認しています。",
|
"verify_camera": "カメラの設定を確認しています。",
|
||||||
"verify_camera_success": "カメラの設定が正常に検証されました。",
|
"verify_camera_success": "カメラの設定が正常に検証されました。",
|
||||||
"verify_camera_error": "カメラ設定の確認中に問題が発生しました"
|
"verify_camera_error": "カメラ設定の確認中に問題が発生しました",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "全般的",
|
"general": "全般的",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "録音を保存しているリージョン。",
|
"kerberoshub_description_region": "録音を保存しているリージョン。",
|
||||||
"kerberoshub_bucket": "bucket",
|
"kerberoshub_bucket": "bucket",
|
||||||
"kerberoshub_description_bucket": "録音を保存しているbucket",
|
"kerberoshub_description_bucket": "録音を保存しているbucket",
|
||||||
"kerberoshub_username": "ユーザー名/ディレクトリ",
|
"kerberoshub_username": "ユーザー名/ディレクトリ (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "Kerberos Hub アカウントのユーザー名。",
|
"kerberoshub_description_username": "Kerberos Hub アカウントのユーザー名。",
|
||||||
"kerberosvault_apiurl": "Kerberos ボールト API URL",
|
"kerberosvault_apiurl": "Kerberos ボールト API URL",
|
||||||
"kerberosvault_description_apiurl": "Kerberos ボールト API",
|
"kerberosvault_description_apiurl": "Kerberos ボールト API",
|
||||||
"kerberosvault_provider": "プロバイダ",
|
"kerberosvault_provider": "プロバイダ",
|
||||||
"kerberosvault_description_provider": "録音の送信先のプロバイダー。",
|
"kerberosvault_description_provider": "録音の送信先のプロバイダー。",
|
||||||
"kerberosvault_directory": "ディレクトリ",
|
"kerberosvault_directory": "ディレクトリ (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "録音がプロバイダーに保存されるサブディレクトリ。",
|
"kerberosvault_description_directory": "録音がプロバイダーに保存されるサブディレクトリ。",
|
||||||
"kerberosvault_accesskey": "アクセスキー",
|
"kerberosvault_accesskey": "アクセスキー",
|
||||||
"kerberosvault_description_accesskey": "Kerberos Vault アカウントのアクセス キー。",
|
"kerberosvault_description_accesskey": "Kerberos Vault アカウントのアクセス キー。",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "Instellingen"
|
"configure": "Instellingen"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Opslaan"
|
"save": "Opslaan",
|
||||||
|
"verify_connection": "Verifieer Connectie"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "Profiel",
|
"profile": "Profiel",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "Er ging iets fout tijdens het controleren van de opslag instellingen",
|
"verify_persistence_error": "Er ging iets fout tijdens het controleren van de opslag instellingen",
|
||||||
"verify_camera": "We controleren de camera instellingen.",
|
"verify_camera": "We controleren de camera instellingen.",
|
||||||
"verify_camera_success": "De camera instellingen zijn gevalideerd.",
|
"verify_camera_success": "De camera instellingen zijn gevalideerd.",
|
||||||
"verify_camera_error": "Er ging iets mis met de camera instellingen."
|
"verify_camera_error": "Er ging iets mis met de camera instellingen.",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "Algemeen",
|
"general": "Algemeen",
|
||||||
@@ -187,13 +191,13 @@
|
|||||||
"kerberoshub_description_region": "De regio waar jouw opnames worden opgeslagen.",
|
"kerberoshub_description_region": "De regio waar jouw opnames worden opgeslagen.",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "De bucket opslag locatie",
|
"kerberoshub_description_bucket": "De bucket opslag locatie",
|
||||||
"kerberoshub_username": "Gebruikersnaam/Map",
|
"kerberoshub_username": "Gebruikersnaam/Map (moet overeenkomen met de Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "De gebruikersnaam van jouw Kerberos Hub account.",
|
"kerberoshub_description_username": "De gebruikersnaam van jouw Kerberos Hub account.",
|
||||||
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
||||||
"kerberosvault_description_apiurl": "De Kerberos Vault API",
|
"kerberosvault_description_apiurl": "De Kerberos Vault API",
|
||||||
"kerberosvault_provider": "Provider",
|
"kerberosvault_provider": "Provider",
|
||||||
"kerberosvault_description_provider": "De provider verantwoordelijk voor de opnames op te slaan.",
|
"kerberosvault_description_provider": "De provider verantwoordelijk voor de opnames op te slaan.",
|
||||||
"kerberosvault_directory": "Map",
|
"kerberosvault_directory": "Map (moet overeenkomen met de Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Sub map waarin de opnames worden opgeslagen.",
|
"kerberosvault_description_directory": "Sub map waarin de opnames worden opgeslagen.",
|
||||||
"kerberosvault_accesskey": "Access key",
|
"kerberosvault_accesskey": "Access key",
|
||||||
"kerberosvault_description_accesskey": "De access key van jouw Kerberos Vault account.",
|
"kerberosvault_description_accesskey": "De access key van jouw Kerberos Vault account.",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "Configure"
|
"configure": "Configure"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Save"
|
"save": "Save",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "Profil",
|
"profile": "Profil",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "Something went wrong while verifying the persistence",
|
"verify_persistence_error": "Something went wrong while verifying the persistence",
|
||||||
"verify_camera": "Verifying your camera settings.",
|
"verify_camera": "Verifying your camera settings.",
|
||||||
"verify_camera_success": "Camera settings are successfully verified.",
|
"verify_camera_success": "Camera settings are successfully verified.",
|
||||||
"verify_camera_error": "Something went wrong while verifying the camera settings"
|
"verify_camera_error": "Something went wrong while verifying the camera settings",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "General",
|
"general": "General",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "The region we are storing our recordings in.",
|
"kerberoshub_description_region": "The region we are storing our recordings in.",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "The bucket we are storing our recordings in.",
|
"kerberoshub_description_bucket": "The bucket we are storing our recordings in.",
|
||||||
"kerberoshub_username": "Username/Directory",
|
"kerberoshub_username": "Username/Directory (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "The username of your Kerberos Hub account.",
|
"kerberoshub_description_username": "The username of your Kerberos Hub account.",
|
||||||
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
||||||
"kerberosvault_description_apiurl": "The Kerberos Vault API",
|
"kerberosvault_description_apiurl": "The Kerberos Vault API",
|
||||||
"kerberosvault_provider": "Provider",
|
"kerberosvault_provider": "Provider",
|
||||||
"kerberosvault_description_provider": "The provider to which your recordings will be send.",
|
"kerberosvault_description_provider": "The provider to which your recordings will be send.",
|
||||||
"kerberosvault_directory": "Directory",
|
"kerberosvault_directory": "Directory (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Sub directory the recordings will be stored in your provider.",
|
"kerberosvault_description_directory": "Sub directory the recordings will be stored in your provider.",
|
||||||
"kerberosvault_accesskey": "Access key",
|
"kerberosvault_accesskey": "Access key",
|
||||||
"kerberosvault_description_accesskey": "The access key of your Kerberos Vault account.",
|
"kerberosvault_description_accesskey": "The access key of your Kerberos Vault account.",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "Configurar"
|
"configure": "Configurar"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "Salvar"
|
"save": "Salvar",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "Perfil",
|
"profile": "Perfil",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "Algo deu errado ao verificar o armazenamento",
|
"verify_persistence_error": "Algo deu errado ao verificar o armazenamento",
|
||||||
"verify_camera": "Verificando as configurações de sua câmera.",
|
"verify_camera": "Verificando as configurações de sua câmera.",
|
||||||
"verify_camera_success": "As configurações da câmera foram verificadas com sucesso.",
|
"verify_camera_success": "As configurações da câmera foram verificadas com sucesso.",
|
||||||
"verify_camera_error": "Algo deu errado ao verificar as configurações da câmera."
|
"verify_camera_error": "Algo deu errado ao verificar as configurações da câmera.",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "Geral",
|
"general": "Geral",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "A região em que estamos armazenando nossas gravações.",
|
"kerberoshub_description_region": "A região em que estamos armazenando nossas gravações.",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "O bucket no qual estamos armazenando nossas gravações.",
|
"kerberoshub_description_bucket": "O bucket no qual estamos armazenando nossas gravações.",
|
||||||
"kerberoshub_username": "Nome de usuário/diretório (Username/Directory)",
|
"kerberoshub_username": "Nome de usuário/diretório (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "O nome de usuário da sua conta do Kerberos Hub.",
|
"kerberoshub_description_username": "O nome de usuário da sua conta do Kerberos Hub.",
|
||||||
"kerberosvault_apiurl": "Url da API do Kerberos Vault",
|
"kerberosvault_apiurl": "Url da API do Kerberos Vault",
|
||||||
"kerberosvault_description_apiurl": "a API Kerberos Vault",
|
"kerberosvault_description_apiurl": "a API Kerberos Vault",
|
||||||
"kerberosvault_provider": "Provedor",
|
"kerberosvault_provider": "Provedor",
|
||||||
"kerberosvault_description_provider": "O provedor para o qual suas gravações serão enviadas.",
|
"kerberosvault_description_provider": "O provedor para o qual suas gravações serão enviadas.",
|
||||||
"kerberosvault_directory": "Diretório",
|
"kerberosvault_directory": "Diretório (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "Subdiretório as gravações serão armazenadas em seu provedor.",
|
"kerberosvault_description_directory": "Subdiretório as gravações serão armazenadas em seu provedor.",
|
||||||
"kerberosvault_accesskey": "Chave de acesso(Access key)",
|
"kerberosvault_accesskey": "Chave de acesso(Access key)",
|
||||||
"kerberosvault_description_accesskey": "A chave de acesso da sua conta do Kerberos Vault.",
|
"kerberosvault_description_accesskey": "A chave de acesso da sua conta do Kerberos Vault.",
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"configure": "配置"
|
"configure": "配置"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"save": "保存"
|
"save": "保存",
|
||||||
|
"verify_connection": "Verify Connection"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"profile": "配置文件",
|
"profile": "配置文件",
|
||||||
@@ -69,7 +70,10 @@
|
|||||||
"verify_persistence_error": "验证持久化存储时出错",
|
"verify_persistence_error": "验证持久化存储时出错",
|
||||||
"verify_camera": "验证您的相机设置",
|
"verify_camera": "验证您的相机设置",
|
||||||
"verify_camera_success": "相机设置验证成功",
|
"verify_camera_success": "相机设置验证成功",
|
||||||
"verify_camera_error": "验证相机设置时出错"
|
"verify_camera_error": "验证相机设置时出错",
|
||||||
|
"verify_onvif": "Verifying your ONVIF settings.",
|
||||||
|
"verify_onvif_success": "ONVIF settings are successfully verified.",
|
||||||
|
"verify_onvif_error": "Something went wrong while verifying the ONVIF settings"
|
||||||
},
|
},
|
||||||
"overview": {
|
"overview": {
|
||||||
"general": "常规",
|
"general": "常规",
|
||||||
@@ -186,13 +190,13 @@
|
|||||||
"kerberoshub_description_region": "存储录像的区域",
|
"kerberoshub_description_region": "存储录像的区域",
|
||||||
"kerberoshub_bucket": "Bucket",
|
"kerberoshub_bucket": "Bucket",
|
||||||
"kerberoshub_description_bucket": "存储录像的桶",
|
"kerberoshub_description_bucket": "存储录像的桶",
|
||||||
"kerberoshub_username": "账户/目录",
|
"kerberoshub_username": "账户/目录 (should match Kerberos Hub username)",
|
||||||
"kerberoshub_description_username": "您的 Kerberos Hub 帐户的用户名",
|
"kerberoshub_description_username": "您的 Kerberos Hub 帐户的用户名",
|
||||||
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
"kerberosvault_apiurl": "Kerberos Vault API URL",
|
||||||
"kerberosvault_description_apiurl": "Kerberos Vault API",
|
"kerberosvault_description_apiurl": "Kerberos Vault API",
|
||||||
"kerberosvault_provider": "供应商",
|
"kerberosvault_provider": "供应商",
|
||||||
"kerberosvault_description_provider": "您的录像将会被发送到的提供商",
|
"kerberosvault_description_provider": "您的录像将会被发送到的提供商",
|
||||||
"kerberosvault_directory": "目录",
|
"kerberosvault_directory": "目录 (should match Kerberos Hub username)",
|
||||||
"kerberosvault_description_directory": "录像将存储在提供商中的子目录",
|
"kerberosvault_description_directory": "录像将存储在提供商中的子目录",
|
||||||
"kerberosvault_accesskey": "访问密钥",
|
"kerberosvault_accesskey": "访问密钥",
|
||||||
"kerberosvault_description_accesskey": "Kerberos Vault 帐户的访问密钥",
|
"kerberosvault_description_accesskey": "Kerberos Vault 帐户的访问密钥",
|
||||||
|
|||||||
@@ -38,6 +38,16 @@ class App extends React.Component {
|
|||||||
dispatchGetDashboardInformation();
|
dispatchGetDashboardInformation();
|
||||||
dispatchConnect();
|
dispatchConnect();
|
||||||
|
|
||||||
|
const connectInterval = interval(1000);
|
||||||
|
this.connectionSubscription = connectInterval.subscribe(() => {
|
||||||
|
const { connected } = this.props;
|
||||||
|
if (connected) {
|
||||||
|
// Already connected
|
||||||
|
} else {
|
||||||
|
dispatchConnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const interval$ = interval(5000);
|
const interval$ = interval(5000);
|
||||||
this.subscription = interval$.subscribe(() => {
|
this.subscription = interval$.subscribe(() => {
|
||||||
dispatchGetDashboardInformation();
|
dispatchGetDashboardInformation();
|
||||||
@@ -64,6 +74,7 @@ class App extends React.Component {
|
|||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.subscription.unsubscribe();
|
this.subscription.unsubscribe();
|
||||||
|
this.connectionSubscription.unsubscribe();
|
||||||
const message = {
|
const message = {
|
||||||
client_id: uuid(),
|
client_id: uuid(),
|
||||||
message_type: 'goodbye',
|
message_type: 'goodbye',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
doGetConfig,
|
doGetConfig,
|
||||||
doSaveConfig,
|
doSaveConfig,
|
||||||
|
doVerifyOnvif,
|
||||||
doVerifyHub,
|
doVerifyHub,
|
||||||
doVerifyPersistence,
|
doVerifyPersistence,
|
||||||
doGetKerberosAgentTags,
|
doGetKerberosAgentTags,
|
||||||
@@ -39,6 +40,28 @@ export const updateRegion = (id, polygon) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const verifyOnvif = (config, onSuccess, onError) => {
|
||||||
|
return (dispatch) => {
|
||||||
|
doVerifyOnvif(
|
||||||
|
config,
|
||||||
|
(data) => {
|
||||||
|
dispatch({
|
||||||
|
type: 'VERIFY_ONVIF',
|
||||||
|
});
|
||||||
|
if (onSuccess) {
|
||||||
|
onSuccess(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
const { message } = error;
|
||||||
|
if (onError) {
|
||||||
|
onError(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const verifyCamera = (streamType, config, onSuccess, onError) => {
|
export const verifyCamera = (streamType, config, onSuccess, onError) => {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
doVerifyCamera(
|
doVerifyCamera(
|
||||||
|
|||||||
@@ -91,6 +91,26 @@ export function doVerifyHub(config, onSuccess, onError) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doVerifyOnvif(config, onSuccess, onError) {
|
||||||
|
const endpoint = API.post(`onvif/verify`, {
|
||||||
|
...config,
|
||||||
|
});
|
||||||
|
endpoint
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw new Error(res.data);
|
||||||
|
}
|
||||||
|
return res.data;
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
onSuccess(data);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
const { data } = e.response;
|
||||||
|
onError(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function doVerifyCamera(streamType, config, onSuccess, onError) {
|
export function doVerifyCamera(streamType, config, onSuccess, onError) {
|
||||||
const cameraStreams = {
|
const cameraStreams = {
|
||||||
rtsp: '',
|
rtsp: '',
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ function getAuthState() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reduxWebsocketMiddleware = reduxWebsocket();
|
const reduxWebsocketMiddleware = reduxWebsocket({
|
||||||
|
reconnectOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
const store = createStore(
|
const store = createStore(
|
||||||
rootReducer(history),
|
rootReducer(history),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Link, withRouter } from 'react-router-dom';
|
|||||||
import { withTranslation } from 'react-i18next';
|
import { withTranslation } from 'react-i18next';
|
||||||
import { send } from '@giantmachines/redux-websocket';
|
import { send } from '@giantmachines/redux-websocket';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { interval } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
KPI,
|
KPI,
|
||||||
@@ -66,6 +67,11 @@ class Dashboard extends React.Component {
|
|||||||
message_type: 'stream-sd',
|
message_type: 'stream-sd',
|
||||||
};
|
};
|
||||||
dispatchSend(message);
|
dispatchSend(message);
|
||||||
|
|
||||||
|
const requestStreamInterval = interval(3000);
|
||||||
|
this.requestStreamSubscription = requestStreamInterval.subscribe(() => {
|
||||||
|
dispatchSend(message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +81,9 @@ class Dashboard extends React.Component {
|
|||||||
liveview[0].remove();
|
liveview[0].remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.requestStreamSubscription) {
|
||||||
|
this.requestStreamSubscription.unsubscribe();
|
||||||
|
}
|
||||||
const { dispatchSend } = this.props;
|
const { dispatchSend } = this.props;
|
||||||
const message = {
|
const message = {
|
||||||
message_type: 'stop-sd',
|
message_type: 'stop-sd',
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
updateRegion,
|
updateRegion,
|
||||||
removeRegion,
|
removeRegion,
|
||||||
saveConfig,
|
saveConfig,
|
||||||
|
verifyOnvif,
|
||||||
verifyCamera,
|
verifyCamera,
|
||||||
verifyHub,
|
verifyHub,
|
||||||
verifyPersistence,
|
verifyPersistence,
|
||||||
@@ -63,6 +64,9 @@ class Settings extends React.Component {
|
|||||||
verifyCameraSuccess: false,
|
verifyCameraSuccess: false,
|
||||||
verifyCameraError: false,
|
verifyCameraError: false,
|
||||||
verifyCameraMessage: '',
|
verifyCameraMessage: '',
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: false,
|
||||||
|
verifyOnvifErrorMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
loadingHub: false,
|
loadingHub: false,
|
||||||
loadingCamera: false,
|
loadingCamera: false,
|
||||||
@@ -127,6 +131,7 @@ class Settings extends React.Component {
|
|||||||
this.onAddRegion = this.onAddRegion.bind(this);
|
this.onAddRegion = this.onAddRegion.bind(this);
|
||||||
this.onUpdateRegion = this.onUpdateRegion.bind(this);
|
this.onUpdateRegion = this.onUpdateRegion.bind(this);
|
||||||
this.onDeleteRegion = this.onDeleteRegion.bind(this);
|
this.onDeleteRegion = this.onDeleteRegion.bind(this);
|
||||||
|
this.verifyONVIF = this.verifyONVIF.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -274,6 +279,8 @@ class Settings extends React.Component {
|
|||||||
verifyHubError: false,
|
verifyHubError: false,
|
||||||
configSuccess: false,
|
configSuccess: false,
|
||||||
configError: false,
|
configError: false,
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (config) {
|
if (config) {
|
||||||
@@ -295,6 +302,53 @@ class Settings extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verifyONVIF() {
|
||||||
|
const { config, dispatchVerifyOnvif } = this.props;
|
||||||
|
|
||||||
|
// Get camera configuration (subset of config).
|
||||||
|
const cameraConfig = {
|
||||||
|
onvif_xaddr: config.config.capture.ipcamera.onvif_xaddr,
|
||||||
|
onvif_username: config.config.capture.ipcamera.onvif_username,
|
||||||
|
onvif_password: config.config.capture.ipcamera.onvif_password,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: false,
|
||||||
|
verifyOnvifErrorMessage: '',
|
||||||
|
verifyCameraSuccess: false,
|
||||||
|
verifyCameraError: false,
|
||||||
|
verifyCameraErrorMessage: '',
|
||||||
|
configSuccess: false,
|
||||||
|
configError: false,
|
||||||
|
loadingCamera: false,
|
||||||
|
loadingOnvif: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (config) {
|
||||||
|
dispatchVerifyOnvif(
|
||||||
|
cameraConfig,
|
||||||
|
(data) => {
|
||||||
|
console.log(data);
|
||||||
|
this.setState({
|
||||||
|
verifyOnvifSuccess: true,
|
||||||
|
verifyOnvifError: false,
|
||||||
|
verifyOnvifErrorMessage: '',
|
||||||
|
loadingOnvif: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.setState({
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: true,
|
||||||
|
verifyOnvifErrorMessage: error,
|
||||||
|
loadingOnvif: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
verifyHubSettings() {
|
verifyHubSettings() {
|
||||||
const { config, dispatchVerifyHub } = this.props;
|
const { config, dispatchVerifyHub } = this.props;
|
||||||
if (config) {
|
if (config) {
|
||||||
@@ -317,6 +371,8 @@ class Settings extends React.Component {
|
|||||||
verifyCameraSuccess: false,
|
verifyCameraSuccess: false,
|
||||||
verifyCameraError: false,
|
verifyCameraError: false,
|
||||||
verifyCameraErrorMessage: '',
|
verifyCameraErrorMessage: '',
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: false,
|
||||||
loadingHub: true,
|
loadingHub: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -362,6 +418,8 @@ class Settings extends React.Component {
|
|||||||
persistenceError: false,
|
persistenceError: false,
|
||||||
verifyCameraSuccess: false,
|
verifyCameraSuccess: false,
|
||||||
verifyCameraError: false,
|
verifyCameraError: false,
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: false,
|
||||||
verifyCameraErrorMessage: '',
|
verifyCameraErrorMessage: '',
|
||||||
loading: true,
|
loading: true,
|
||||||
});
|
});
|
||||||
@@ -402,6 +460,7 @@ class Settings extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
configSuccess: false,
|
configSuccess: false,
|
||||||
configError: false,
|
configError: false,
|
||||||
|
loadingCamera: true,
|
||||||
verifyPersistenceSuccess: false,
|
verifyPersistenceSuccess: false,
|
||||||
verifyPersistenceError: false,
|
verifyPersistenceError: false,
|
||||||
verifyHubSuccess: false,
|
verifyHubSuccess: false,
|
||||||
@@ -410,9 +469,10 @@ class Settings extends React.Component {
|
|||||||
verifyCameraSuccess: false,
|
verifyCameraSuccess: false,
|
||||||
verifyCameraError: false,
|
verifyCameraError: false,
|
||||||
verifyCameraErrorMessage: '',
|
verifyCameraErrorMessage: '',
|
||||||
|
verifyOnvifSuccess: false,
|
||||||
|
verifyOnvifError: false,
|
||||||
hubSuccess: false,
|
hubSuccess: false,
|
||||||
hubError: false,
|
hubError: false,
|
||||||
loadingCamera: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatchVerifyCamera(
|
dispatchVerifyCamera(
|
||||||
@@ -453,6 +513,10 @@ class Settings extends React.Component {
|
|||||||
verifyCameraSuccess,
|
verifyCameraSuccess,
|
||||||
verifyCameraError,
|
verifyCameraError,
|
||||||
verifyCameraErrorMessage,
|
verifyCameraErrorMessage,
|
||||||
|
loadingOnvif,
|
||||||
|
verifyOnvifSuccess,
|
||||||
|
verifyOnvifError,
|
||||||
|
verifyOnvifErrorMessage,
|
||||||
loadingCamera,
|
loadingCamera,
|
||||||
loading,
|
loading,
|
||||||
loadingHub,
|
loadingHub,
|
||||||
@@ -652,10 +716,23 @@ class Settings extends React.Component {
|
|||||||
type="alert"
|
type="alert"
|
||||||
message={`${t(
|
message={`${t(
|
||||||
'settings.info.verify_camera_error'
|
'settings.info.verify_camera_error'
|
||||||
)} :${verifyCameraErrorMessage}`}
|
)}: ${verifyCameraErrorMessage}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{loadingOnvif && (
|
||||||
|
<InfoBar type="loading" message={t('settings.info.verify_onvif')} />
|
||||||
|
)}
|
||||||
|
{verifyOnvifSuccess && (
|
||||||
|
<InfoBar
|
||||||
|
type="success"
|
||||||
|
message={t('settings.info.verify_onvif_success')}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{verifyOnvifError && (
|
||||||
|
<InfoBar type="alert" message={`${verifyOnvifErrorMessage}`} />
|
||||||
|
)}
|
||||||
|
|
||||||
{loadingHub && (
|
{loadingHub && (
|
||||||
<InfoBar type="loading" message={t('settings.info.verify_hub')} />
|
<InfoBar type="loading" message={t('settings.info.verify_hub')} />
|
||||||
)}
|
)}
|
||||||
@@ -1103,7 +1180,7 @@ class Settings extends React.Component {
|
|||||||
noPadding
|
noPadding
|
||||||
label={t('settings.camera.onvif_xaddr')}
|
label={t('settings.camera.onvif_xaddr')}
|
||||||
value={config.capture.ipcamera.onvif_xaddr}
|
value={config.capture.ipcamera.onvif_xaddr}
|
||||||
placeholder="http://x.x.x.x/onvif/device_service"
|
placeholder="x.x.x.x:yyyy"
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
this.onUpdateField(
|
this.onUpdateField(
|
||||||
'capture.ipcamera',
|
'capture.ipcamera',
|
||||||
@@ -1143,6 +1220,12 @@ class Settings extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</BlockBody>
|
</BlockBody>
|
||||||
<BlockFooter>
|
<BlockFooter>
|
||||||
|
<Button
|
||||||
|
label={t('buttons.verify_connection')}
|
||||||
|
type="default"
|
||||||
|
icon="verify"
|
||||||
|
onClick={this.verifyONVIF}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
label={t('buttons.save')}
|
label={t('buttons.save')}
|
||||||
type="default"
|
type="default"
|
||||||
@@ -2245,6 +2328,8 @@ const mapStateToProps = (state /* , ownProps */) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch /* , ownProps */) => ({
|
const mapDispatchToProps = (dispatch /* , ownProps */) => ({
|
||||||
|
dispatchVerifyOnvif: (config, success, error) =>
|
||||||
|
dispatch(verifyOnvif(config, success, error)),
|
||||||
dispatchVerifyCamera: (streamType, config, success, error) =>
|
dispatchVerifyCamera: (streamType, config, success, error) =>
|
||||||
dispatch(verifyCamera(streamType, config, success, error)),
|
dispatch(verifyCamera(streamType, config, success, error)),
|
||||||
dispatchVerifyHub: (config, success, error) =>
|
dispatchVerifyHub: (config, success, error) =>
|
||||||
@@ -2272,6 +2357,7 @@ Settings.propTypes = {
|
|||||||
dispatchUpdateRegion: PropTypes.func.isRequired,
|
dispatchUpdateRegion: PropTypes.func.isRequired,
|
||||||
dispatchRemoveRegion: PropTypes.func.isRequired,
|
dispatchRemoveRegion: PropTypes.func.isRequired,
|
||||||
dispatchVerifyCamera: PropTypes.func.isRequired,
|
dispatchVerifyCamera: PropTypes.func.isRequired,
|
||||||
|
dispatchVerifyOnvif: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withTranslation()(
|
export default withTranslation()(
|
||||||
|
|||||||
Reference in New Issue
Block a user