2023-01-29 16:21:32 +03:00
|
|
|
#! /bin/bash
|
|
|
|
|
2023-03-11 22:20:57 +03:00
|
|
|
# DESCRIPTION:
|
|
|
|
# Handling Hikvision PTZ-cameras sequences.
|
|
|
|
# Additionally:
|
|
|
|
# - get ds18b20 sensor value over SSH,
|
|
|
|
# - saving pictures to FTP.
|
|
|
|
# This is only a local "proof of conept" for testing and debugging.
|
2023-01-29 16:21:32 +03:00
|
|
|
#
|
2023-03-11 22:20:57 +03:00
|
|
|
# DEPENDENCIES:
|
|
|
|
# - curl
|
|
|
|
# - sshpass
|
2023-01-29 16:21:32 +03:00
|
|
|
#
|
2023-03-11 22:20:57 +03:00
|
|
|
# PARAMETERS:
|
|
|
|
# 1: "qn" - execution without pauses
|
|
|
|
# 2: custom configuration file path
|
2023-01-29 16:21:32 +03:00
|
|
|
#
|
2023-03-11 22:20:57 +03:00
|
|
|
# FUNCTIONS:
|
2023-01-29 16:21:32 +03:00
|
|
|
#
|
|
|
|
|
2023-03-11 22:20:57 +03:00
|
|
|
#######################################
|
|
|
|
# Print message and add to log.
|
|
|
|
# Globals:
|
|
|
|
# logs
|
|
|
|
# Arguments:
|
|
|
|
# 1: message to print and logging
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
addtologs() {
|
2023-03-11 22:20:57 +03:00
|
|
|
echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a "${logs}"
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Waiting for press [ENTER].
|
|
|
|
# Globals:
|
|
|
|
# None
|
|
|
|
# Arguments:
|
|
|
|
# None
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
execpause() {
|
2023-03-11 22:20:57 +03:00
|
|
|
read -r -p "Press [ENTER] to continue... "
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Exit procedure.
|
|
|
|
# Globals:
|
|
|
|
# show
|
|
|
|
# Arguments:
|
|
|
|
# None
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
execquite() {
|
2023-03-11 22:20:57 +03:00
|
|
|
addtologs "execution time is $(($(date +%s)-time)) seconds, exit"
|
|
|
|
if [ "${show}" != "qn" ]; then
|
|
|
|
execpause
|
|
|
|
fi
|
|
|
|
exit
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Error exit procedure with Telegram notification.
|
|
|
|
# Globals:
|
|
|
|
# telegramapiurl
|
|
|
|
# telegramchatid
|
|
|
|
# Arguments:
|
|
|
|
# 1: message to print and logging
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
execerror() {
|
2023-03-11 22:20:57 +03:00
|
|
|
addtologs "error: $1"
|
|
|
|
curl -s -X POST "${telegramapiurl}/sendMessage" \
|
|
|
|
-d "chat_id=${telegramchatid}" \
|
|
|
|
-d "text=$(basename -s .sh "$0") error: $1" \
|
|
|
|
>> /dev/null 2>&1
|
|
|
|
execquite
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Parsing config file and creating global vars.
|
|
|
|
# Globals:
|
|
|
|
# None
|
|
|
|
# Arguments:
|
|
|
|
# None
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
getconfig() {
|
2023-03-11 22:20:57 +03:00
|
|
|
logs=$(grep "logs=" "${conf}" | cut -d= -f2)
|
|
|
|
camuser=$(grep "camuser=" "${conf}" | cut -d= -f2)
|
|
|
|
campass=$(grep "campass=" "${conf}" | cut -d= -f2)
|
|
|
|
camaddr=$(grep "camaddr=" "${conf}" | cut -d= -f2)
|
|
|
|
camport=$(grep "camport=" "${conf}" | cut -d= -f2)
|
|
|
|
ftpuser=$(grep "ftpuser=" "${conf}" | cut -d= -f2)
|
|
|
|
ftppass=$(grep "ftppass=" "${conf}" | cut -d= -f2)
|
|
|
|
ftpaddr=$(grep "ftpaddr=" "${conf}" | cut -d= -f2)
|
|
|
|
ftpport=$(grep "ftpport=" "${conf}" | cut -d= -f2)
|
|
|
|
ftppath=$(grep "ftppath=" "${conf}" | cut -d= -f2)
|
|
|
|
tmpuser=$(grep "tmpuser=" "${conf}" | cut -d= -f2)
|
|
|
|
tmppass=$(grep "tmppass=" "${conf}" | cut -d= -f2)
|
|
|
|
tmpaddr=$(grep "tmpaddr=" "${conf}" | cut -d= -f2)
|
|
|
|
tmpport=$(grep "tmpport=" "${conf}" | cut -d= -f2)
|
|
|
|
tmpnode=$(grep "tmpnode=" "${conf}" | cut -d= -f2)
|
|
|
|
telegramapiurl=$(grep "telegramapiurl=" "${conf}" | cut -d= -f2)
|
|
|
|
telegramchatid=$(grep "telegramchatid=" "${conf}" | cut -d= -f2)
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Get ds18b20 sensor value over SSH.
|
|
|
|
# Globals:
|
|
|
|
# tmpaddr
|
|
|
|
# tmpport
|
|
|
|
# tmpuser
|
|
|
|
# tmppass
|
|
|
|
# tmpnode
|
|
|
|
# Arguments:
|
|
|
|
# None
|
|
|
|
# return:
|
|
|
|
# temperature in Celsius
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
getairtmp() {
|
2023-03-11 22:20:57 +03:00
|
|
|
temp=$(sshpass -p "${tmppass}" \
|
|
|
|
ssh "${tmpuser}@${tmpaddr}" -p "${tmpport}" \
|
|
|
|
-o StrictHostKeyChecking=no -o ConnectTimeout=10 \
|
|
|
|
"cat /sys/bus/w1/devices/${tmpnode}/temperature" \
|
|
|
|
) && temp=$((temp / 1000))
|
|
|
|
if [ -n "${temp}" ]; then
|
|
|
|
addtologs "getairtmp: air temperature now is ${temp}'C" > /dev/null
|
|
|
|
echo "${temp}"
|
|
|
|
else
|
|
|
|
execerror "getairtmp: air temperature now is ${temp}'C"
|
|
|
|
fi
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Get static picture from camera and upload to FTP.
|
|
|
|
# Globals:
|
|
|
|
# camaddr
|
|
|
|
# camport
|
|
|
|
# camuser
|
|
|
|
# campass
|
|
|
|
# ftpaddr
|
|
|
|
# ftpport
|
|
|
|
# ftppath
|
|
|
|
# ftpuser
|
|
|
|
# ftppass
|
|
|
|
# Arguments:
|
|
|
|
# 1: filename prefix
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
getcamimg() {
|
2023-03-11 22:20:57 +03:00
|
|
|
local name
|
|
|
|
name=$1
|
|
|
|
path="${ftppath}/$(date +"%Y")/$(date +"%m")/$(date +"%V")/$(date +"%d")"
|
|
|
|
file="${ftpaddr}:${ftpport}/${path}/${name}_$(date +"%Y.%m.%d_%H-%M-%S").jpeg"
|
|
|
|
url='Streaming/channels/101/picture?snapShotImageType=JPEG&videoResolutionWidth=1920&videoResolutionHeight=1080'
|
|
|
|
if curl -vs "http://$camuser:$campass@$camaddr:$camport/$url" -o tmp \
|
|
|
|
&& curl -T tmp "ftp://$ftpuser:$ftppass@$file" --ftp-create-dirs; then
|
|
|
|
addtologs "getcamimg: save photo to ftp://${file}"
|
|
|
|
rm tmp
|
|
|
|
else
|
|
|
|
execerror "getcamimg: save photo to ftp://${file}"
|
|
|
|
fi
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Set message as video overlay text.
|
|
|
|
# Globals:
|
|
|
|
# camaddr
|
|
|
|
# camport
|
|
|
|
# camuser
|
|
|
|
# campass
|
|
|
|
# Arguments:
|
|
|
|
# 1: overlay text content
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
setcamtxt() {
|
2023-03-11 22:20:57 +03:00
|
|
|
local message=$1
|
|
|
|
url='ISAPI/System/Video/inputs/channels/101/overlays/text'
|
|
|
|
xml='<TextOverlayList>
|
|
|
|
<TextOverlay>
|
|
|
|
<id>1</id>
|
|
|
|
<enabled>true</enabled>
|
|
|
|
<posX>0</posX><posY>0</posY>
|
|
|
|
<displayText>'"${message}"'</displayText>
|
|
|
|
</TextOverlay>
|
|
|
|
</TextOverlayList>'
|
|
|
|
if curl -d "${xml}" -X PUT "http://$camuser:$campass@$camaddr:$camport/$url" \
|
|
|
|
| grep -q '<statusString>OK</statusString>'; then
|
|
|
|
addtologs "setcamtxt: ${message}"
|
|
|
|
sleep 5
|
|
|
|
else
|
|
|
|
execerror "setcamtxt: ${message}"
|
|
|
|
fi
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Set camera moving to absolute position.
|
|
|
|
# Globals:
|
|
|
|
# camaddr
|
|
|
|
# camport
|
|
|
|
# camuser
|
|
|
|
# campass
|
|
|
|
# Arguments:
|
|
|
|
# 1: horisontal camera position from 0 to 3600
|
|
|
|
# 2: vertical camera position from -900 to 2700
|
|
|
|
# 3: zoom camera position from 0 to 1000
|
|
|
|
# 4: time to wait
|
|
|
|
# 5: message to print and logging
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
setcampos() {
|
2023-03-11 22:20:57 +03:00
|
|
|
local x=$1
|
|
|
|
local y=$2
|
|
|
|
local z=$3
|
|
|
|
local t=$4
|
|
|
|
local message=$5
|
|
|
|
url='ISAPI/PTZCtrl/channels/101/absolute'
|
|
|
|
xml='<PTZData>
|
|
|
|
<AbsoluteHigh>
|
|
|
|
<elevation>'"${y}"'</elevation>
|
|
|
|
<azimuth>'"${x}"'</azimuth>
|
|
|
|
<absoluteZoom>'"${z}"'</absoluteZoom>
|
|
|
|
</AbsoluteHigh>
|
|
|
|
</PTZData>'
|
|
|
|
if curl -d "${xml}" -X PUT "http://$camuser:$campass@$camaddr:$camport/$url" \
|
|
|
|
| grep -q '<statusString>OK</statusString>'; then
|
|
|
|
addtologs "setcampos: ${message}"
|
|
|
|
sleep "${t}"
|
|
|
|
else
|
|
|
|
execerror "setcampos: ${message}"
|
|
|
|
fi
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
2023-03-11 22:20:57 +03:00
|
|
|
|
|
|
|
#######################################
|
|
|
|
# Set camera moving to direction.
|
|
|
|
# Globals:
|
|
|
|
# camaddr
|
|
|
|
# camport
|
|
|
|
# camuser
|
|
|
|
# campass
|
|
|
|
# Arguments:
|
|
|
|
# 1: acceleration of horizontal camera movement from -100 to 100
|
|
|
|
# 2: acceleration of vertical camera movement from -100 to 100
|
|
|
|
# 3: acceleration of zoom camera movement from -100 to 100
|
|
|
|
# 4: time to wait
|
|
|
|
# 5: message to print and logging
|
|
|
|
#######################################
|
2023-01-29 16:21:32 +03:00
|
|
|
setcammov() {
|
2023-03-11 22:20:57 +03:00
|
|
|
local x=$1
|
|
|
|
local y=$2
|
|
|
|
local z=$3
|
|
|
|
local t=$4
|
|
|
|
local message=$5
|
|
|
|
url='ISAPI/PTZCtrl/channels/101/continuous'
|
|
|
|
xml='<PTZData>
|
|
|
|
<pan>'"${x}"'</pan>
|
|
|
|
<tilt>'"${y}"'</tilt>
|
|
|
|
<zoom>'"${z}"'</zoom>
|
|
|
|
</PTZData>'
|
|
|
|
if curl -d "${xml}" -X PUT "http://$camuser:$campass@$camaddr:$camport/$url" \
|
|
|
|
| grep -q '<statusString>OK</statusString>'; then
|
|
|
|
addtologs "setcammov: ${message}"
|
|
|
|
sleep "${t}"
|
|
|
|
else
|
|
|
|
execerror "setcammov: ${message}"
|
|
|
|
fi
|
2023-01-29 16:21:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
2023-03-11 22:20:57 +03:00
|
|
|
## VARIABLES:
|
2023-01-29 16:21:32 +03:00
|
|
|
#
|
|
|
|
|
2023-03-11 22:20:57 +03:00
|
|
|
show=$1
|
|
|
|
conf=$2
|
|
|
|
if [ -z "${conf}" ] || [ "${conf}" == "-" ]; then
|
|
|
|
conf="$(dirname "$(realpath "$0")")/$(basename -s .sh "$0").conf"
|
2023-01-29 16:21:32 +03:00
|
|
|
fi
|
|
|
|
|
|
|
|
time=$(date +%s)
|
2023-03-11 22:20:57 +03:00
|
|
|
cd "$(dirname "$(realpath "$0")")" || execerror
|
|
|
|
if [ ! -e "${conf}" ]; then
|
|
|
|
execerror "Not found config file: ${conf}"
|
2023-01-29 16:21:32 +03:00
|
|
|
else
|
2023-03-11 22:20:57 +03:00
|
|
|
getconfig
|
2023-01-29 16:21:32 +03:00
|
|
|
fi
|
|
|
|
if [ -z "${logs}" ];then
|
2023-03-11 22:20:57 +03:00
|
|
|
logs=/dev/null
|
|
|
|
elif [ ! -e "${logs}" ];then
|
|
|
|
touch "${logs}"
|
2023-01-29 16:21:32 +03:00
|
|
|
fi
|
|
|
|
if ! command -v curl &> /dev/null || ! command -v sshpass &> /dev/null; then
|
2023-03-11 22:20:57 +03:00
|
|
|
execerror "Not found dependencies"
|
2023-01-29 16:21:32 +03:00
|
|
|
fi
|
|
|
|
|
|
|
|
#
|
2023-03-11 22:20:57 +03:00
|
|
|
# MAIN:
|
2023-01-29 16:21:32 +03:00
|
|
|
#
|
|
|
|
|
|
|
|
setcamtxt "$(getairtmp)'C"
|
|
|
|
setcampos 0 0 10 5.00s 'xx >| 01 Точка - Панорама центр 1x'
|
|
|
|
sleep 1m
|
|
|
|
setcamtxt '' && getcamimg 'point-01' && setcamtxt "$(getairtmp)'C"
|
|
|
|
sleep 4m
|
|
|
|
setcampos 395 0 10 5.00s '01 >| 02 Точка - Панорама право 1x'
|
|
|
|
setcampos 2915 0 10 5.00s '02 >| 03 Точка - Панорама лево 1x'
|
|
|
|
sleep 1m
|
|
|
|
setcamtxt '' && getcamimg 'point-02' && setcamtxt "$(getairtmp)'C"
|
|
|
|
sleep 4m
|
|
|
|
setcammov 25 25 33 6.00s '03 >> 04 Точка - Дорожный переход 8x'
|
|
|
|
setcampos 3060 -85 80 5.00s '03 >| 04 Точка - Дорожный переход 8x'
|
|
|
|
sleep 5m
|
|
|
|
setcammov 99 99 0 2.25s '04 >> 05 Точка - Поля 8x'
|
|
|
|
setcampos 3208 -200 80 5.00s '04 >| 05 Точка - Поля 8x'
|
|
|
|
setcampos 3208 -200 160 5.00s '05 >| 06 Точка - Поля 16x'
|
|
|
|
setcammov -70 0 -33 3.00s '06 >> 07 Точка - Поля 4x'
|
|
|
|
setcampos 3175 -200 40 5.00s '06 >| 07 Точка - Поля 4x'
|
|
|
|
sleep 1m
|
|
|
|
setcamtxt '' && getcamimg 'point-04' && setcamtxt "$(getairtmp)'C"
|
|
|
|
sleep 4m
|
|
|
|
setcampos 2860 -200 40 5.00s '07 >| 08 Точка - Стадион 4x'
|
|
|
|
sleep 1m
|
|
|
|
setcamtxt '' && getcamimg 'point-05' && setcamtxt "$(getairtmp)'C"
|
|
|
|
sleep 4m
|
|
|
|
setcammov 0 -44 33 1.50s '08 >> 09 Точка - Стадион 8x'
|
|
|
|
setcampos 2860 -170 80 5.00s '08 >| 09 Точка - Стадион 8x'
|
|
|
|
sleep 1m
|
2023-03-11 22:20:57 +03:00
|
|
|
setcammov 0 -99 0 7.50s '09 >> 10 Точка - Въезд во двор 8x'
|
2023-01-29 16:21:32 +03:00
|
|
|
setcampos 2805 200 80 5.00s '09 >| 10 Точка - Въезд во двор 8x'
|
|
|
|
sleep 5m
|
|
|
|
setcammov -88 99 0 5.00s '10 >> 11 Точка - Бассейн 8x'
|
|
|
|
setcammov -99 88 0 2.00s '10 >> 11 Точка - Бассейн 8x'
|
|
|
|
setcammov -44 99 0 4.25s '10 >> 11 Точка - Бассейн 8x'
|
2023-03-11 22:20:57 +03:00
|
|
|
setcampos 2510 -20 80 5.00s '10 >| 11 Точка - Бассейн 8x'
|
2023-01-29 16:21:32 +03:00
|
|
|
sleep 1m
|
|
|
|
setcammov -88 99 33 2.50s '11 >> 12 Точка - Общежитие дальнее 16x'
|
|
|
|
setcampos 2415 -200 160 5.00s '11 >| 12 Точка - Общежитие дальнее 16x'
|
|
|
|
sleep 1m
|
|
|
|
setcammov 66 0 0 22.5s '12 >> 13 Точка - Общежите ближнее 16x'
|
|
|
|
setcampos 2640 -200 160 5.00s '12 >| 13 Точка - Общежите ближнее 16x'
|
|
|
|
sleep 1m
|
|
|
|
setcammov 66 0 0 90.5s '13 >> 14 Точка - Крыша магазина 4x'
|
2023-03-11 22:20:57 +03:00
|
|
|
setcammov 99 0 -44 3.25s '13 >> 14 Точка - Крыша магазина 4x'
|
2023-01-29 16:21:32 +03:00
|
|
|
setcampos 335 -200 40 5.00s '13 >| 14 Точка - Крыша магазина 4x'
|
|
|
|
sleep 1m
|
|
|
|
setcamtxt '' && getcamimg 'point-11' && setcamtxt "$(getairtmp)'C"
|
|
|
|
sleep 4m
|
|
|
|
setcammov -99 0 -33 2.50s '14 >> 15 Точка - Панорама верх 1x'
|
|
|
|
setcampos 0 -200 10 5.00s '14 >| 15 Точка - Панорама верх 1x'
|
|
|
|
sleep 1m
|
|
|
|
setcamtxt '' && getcamimg 'point-12' && setcamtxt "$(getairtmp)'C"
|
|
|
|
sleep 4m
|
|
|
|
setcammov 0 -33 0 10.0s '15 >> 01 Точка - Панорама центр 1x'
|
|
|
|
setcampos 0 0 10 5.00s '15 >| 01 Точка - Панорама центр 1x'
|
|
|
|
execquite
|