diff --git a/README.md b/README.md
index 491b718..2d608ce 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,35 @@
-# template-bash
-Template repository for projects on bash
+# cctv-scheduler
+PTZ IP-Camera management
-* [`script.sh`](https://git.hmp.today/pavel.muhortov/template-bash#script-sh)
+* [`sequence.sh`](https://git.hmp.today/pavel.muhortov/cctv-scheduler#sequence-sh)
____
-## `script.sh`
+## `sequence.sh`
**Description:**
-> returning current username if privileged rights are exist
-> or
-> returning error, if privileged rights are not exist
-
+> Hikvision PTZ-camera sequence.
+> Additionally:
+> - getting temperature from ds-18b20 over SSH,
+> - saving pictures to FTP.
+> - This is only a local "proof of conept" for testing and debugging.
**Dependencies:**
> - bash (tested version 5.1.4 on Debian GNU/Linux 11)
+> - curl (tested version 7.74 on Debian GNU/Linux 11)
+> - sshpass (tested version 1.09 on Debian GNU/Linux 11)
| POSITION | PARAMETERS | DESCRIPTION | DEFAULT |
|-----------|--------------|------------------------|---------------|
| 1 | **[qn]** |execution without pauses||
-| 2 | **[/path/to/conf]** |path to config| ./script.conf |
+| 2 | **[/path/to/conf]** |path to config| ./sequence.conf |
Example usage in terminal with bash:
```shell
-bash ./script.sh qn ./script.conf
+bash ./sequence.sh - ./sequence.conf
```
-Example usage in terminal with make the script executable:
+Example usage with cron:
```shell
-chmod u+x ./script.sh
-script.sh
+crontab -e
+0 * * * * bash /home/user/cctv-scheduler/sequence.sh qn
```
diff --git a/script.sh b/script.sh
deleted file mode 100644
index 45b48e0..0000000
--- a/script.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#! /bin/bash
-
-#
-## DESCRIPTION:
-# returning current username if privileged rights are exist
-# or
-# returning error, if privileged rights are not exist
-#
-
-#
-## DEPENDENCIES: sudo apt|yum install -y whoami
-#
-
-#
-## FUNCTIONS
-#
-
-addtologs() {
- echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a $logs
-}
-
-execpause() {
- read -p "Press [ENTER] to continue... "
-}
-execquite() {
- addtologs "execution time is $(($(date +%s)-$time)) seconds, exit"
- if [ "${show}" != "qn" ];then
- execpause
- fi
- exit
-}
-execerror() {
- addtologs "error: $1"
- execquite
-}
-getconfig() {
- logs=$(cat $conf | grep "logs=" | cut -d= -f2)
-}
-checkroot() {
- if [ "${EUID}" -ne 0 ];then
- return 1 # false
- else
- return 0 # true
- fi
-}
-
-#
-## PARAMETERS
-#
-
-show=${1}
-conf=${2}
-if [ -z "${conf}" ] || [ "${conf}" == "-" ];then
- conf="$(dirname $(realpath "$0"))/$(basename -s .sh $0).conf"
-fi
-
-#
-## VARIABLES
-#
-
-time=$(date +%s)
-cd "$(dirname "$(realpath "$0")")"
-if [ ! -e ${conf} ];then
- :
-else
- getconfig
-fi
-if [ -z "${logs}" ];then
- logs=/dev/null
-elif [ ! -e ${logs} ];then
- touch ${logs}
-fi
-
-#
-## RUN
-#
-
-checkroot && echo "Running as $(whoami)" && execquite || execerror "Restart this as root!"
diff --git a/sequence.sh b/sequence.sh
new file mode 100644
index 0000000..3cce3cb
--- /dev/null
+++ b/sequence.sh
@@ -0,0 +1,188 @@
+#! /bin/bash
+
+#
+## DESCRIPTION:
+# Hikvision PTZ-camera sequence.
+# Additionally:
+# - getting temperature from ds-18b20 over SSH,
+# - saving pictures to FTP.
+# This is only a local "proof of conept" for testing and debugging.
+#
+
+#
+## DEPENDENCIES: sudo apt|yum install -y curl sshpass
+#
+
+#
+## FUNCTIONS
+#
+
+addtologs() {
+ echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a $logs
+}
+execpause() {
+ read -p "Press [ENTER] to continue... "
+}
+execquite() {
+ addtologs "execution time is $(($(date +%s)-$time)) seconds, exit"
+ if [ "${show}" != "qn" ];then
+ execpause
+ fi
+ exit
+}
+execerror() {
+ addtologs "error: $1"
+ execquite
+}
+getconfig() {
+ logs=$(cat $conf | grep "logs=" | cut -d= -f2)
+ camuser=$(cat $conf | grep "camuser=" | cut -d= -f2)
+ campass=$(cat $conf | grep "campass=" | cut -d= -f2)
+ camaddr=$(cat $conf | grep "camaddr=" | cut -d= -f2)
+ camport=$(cat $conf | grep "camport=" | cut -d= -f2)
+ ftpuser=$(cat $conf | grep "ftpuser=" | cut -d= -f2)
+ ftppass=$(cat $conf | grep "ftppass=" | cut -d= -f2)
+ ftpaddr=$(cat $conf | grep "ftpaddr=" | cut -d= -f2)
+ ftpport=$(cat $conf | grep "ftpport=" | cut -d= -f2)
+ tmpuser=$(cat $conf | grep "tmpuser=" | cut -d= -f2)
+ tmppass=$(cat $conf | grep "tmppass=" | cut -d= -f2)
+ tmpaddr=$(cat $conf | grep "tmpaddr=" | cut -d= -f2)
+ tmpport=$(cat $conf | grep "tmpport=" | cut -d= -f2)
+ tmpnode=$(cat $conf | grep "tmpnode=" | cut -d= -f2)
+}
+getairtmp() {
+ local 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 [ ! -z "${temp}" ]; then
+ addtologs "air temperature now is $temp'C" > /dev/null
+ echo $temp
+ else
+ execerror "air temperature now is $temp'C"
+ fi
+}
+getcamimg() {
+ local name=$1
+ local file="$ftpaddr:$ftpport/Records/cam-street.home.local/$(date +"%Y")/$(date +"%m")/$(date +"%V")/$(date +"%d")/${name}_$(date +"%Y.%m.%d_%H-%M-%S").jpeg"
+ url='/Streaming/channels/101/picture?snapShotImageType=JPEG&videoResolutionWidth=1920&videoResolutionHeight=1080'
+ curl -vs "http://$camuser:$campass@$camaddr:$camport/$url" -o tmp \
+ && curl -T tmp "ftp://$ftpuser:$ftppass@$file" --ftp-create-dirs \
+ && rm tmp && addtologs "save photo to ftp://$file" || execerror "save photo to ftp://$file"
+}
+setcamtxt() {
+ local message=$1
+ url='/Video/inputs/channels/101/overlays/text'
+ xml='1true00'"${message}"''
+ curl -d "$xml" -X PUT "http://$camuser:$campass@$camaddr:$camport/$url" && addtologs "text on video is $message" && sleep 5 || execerror "text on video is $message"
+}
+setcampos() {
+ local x=$1
+ local y=$2
+ local z=$3
+ local t=$4
+ local message=$5
+ url='/ISAPI/PTZCtrl/channels/101/absolute'
+ xml=''"${y}"''"${x}"''"${z}"''
+ curl -d "$xml" -X PUT "http://$camuser:$campass@$camaddr:$camport/$url" && addtologs "$message" && sleep $t || execerror "$message"
+}
+setcammov() {
+ local x=$1
+ local y=$2
+ local z=$3
+ local t=$4
+ local message=$5
+ url='/ISAPI/PTZCtrl/channels/101/continuous'
+ xml=''"${x}"''"${y}"''"${z}"''
+ curl -d "$xml" -X PUT "http://$camuser:$campass@$camaddr:$camport/$url" && addtologs "$message" && sleep $t || execerror "$message"
+}
+
+#
+## PARAMETERS
+#
+
+show=${1}
+conf=${2}
+if [ -z "${conf}" ] || [ "${conf}" == "-" ];then
+ conf="$(dirname $(realpath "$0"))/$(basename -s .sh $0).conf"
+fi
+
+#
+## VARIABLES
+#
+
+time=$(date +%s)
+cd "$(dirname "$(realpath "$0")")"
+if [ ! -e ${conf} ];then
+ execerror "Not found config file: ${conf}"
+else
+ getconfig
+fi
+if [ -z "${logs}" ];then
+ logs=/dev/null
+elif [ ! -e ${logs} ];then
+ touch ${logs}
+fi
+if ! command -v curl &> /dev/null || ! command -v sshpass &> /dev/null; then
+ execerror "Not found dependencies"
+fi
+
+#
+## RUN
+#
+
+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
+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'
+setcampos 2510 -100 80 5.00s '10 >| 11 Точка - Бассейн 8x'
+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'
+setcammov 99 0 -33 3.25s '13 >> 14 Точка - Крыша магазина 4x'
+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