Dla ułatwienia sobie pracy załączmy sobie uprawnienia roota:
sudo su
Następnie zaktualizujmy repozytoria i paczki zainstalowanego oprogramowania na naszym Raspberry Pi:
apt update
apt upgrade
Teraz zainstalujmy pakiet motion:
apt install motion
Oraz zainicjujemy wsparcie dla naszej kamery (oryginalny moduł kamery dla Raspberry Pi):
modprobe bcm2835-v4l2
Zakładam, że pakiet motion został poprwnie zainstalowany, jak również podłączona kamera jest poprawnie rozpoznawana przez system. Sprawdźmy to za pomocą polecenia:
ls /dev/video*
W odpowiedzi powinniśmy otrzymać listę dostępnych w systemie urządzeń video:

Przed uruchomieniem pakietu motion należy zmodyfikować plik konfiguracyjny:
nano /etc/motion/motion.conf
W pierwszej kolejności trzeba wskazać oprogramowaniu motion właściwe urządzenie, które ma wykorzystać. W naszym przypadku będzie to urządzenie /dev/video0 zatem odszukujemy odpowiednią sekcję pliku konfiguracyjnego i w razie potrzeby modyfikujemy zawartość:
# Video device (e.g. /dev/video0) to be used for capturing.
videodevice /dev/video0
Na końcu zezwalamy na podłączenie się do streamu z kamery dowolnej maszynie w sieci LAN: wartość zmiennej stream_localhost zmieniamy z on na off :
# Restrict stream connections to the localhost.
stream_localhost off
oraz ustawiamy odpowiadający mi port, na którym pakiet motion wystawi screen z kamery do sieci LAN:
# The port number for the live stream.
stream_port 8081
Po zapisaniu zmian w pliku konfiguracyjnym uruchamiamy pakiet motion:
motion
W odpowiedzi powinniśmy otrzymać informacje jak niżej:

Od tego momentu za pomocą dowolnego komputera w obrębie tej samej sieci LAN i przeglądarki internetowej możemy włączyć podgląd obrazu zwracanego przez kamerę. W tym celu wpisujemy w przeglądarkę adres IP naszego Raspberry Pi (w moim przypadku: 192.168.56.7) wskazując port na którym pakiet motion wystawił srteam z kamery (w moim przypadku 8081).
http://192.168.56.7:8081/
Po zatwierdzeniu wpisanego adresu przeglądarka odtworzy stream z kamery:

Kolejnym krokiem będzie detekcja ruchu oraz zapis 10 klatek poruszającego się obiektu do obrazów .jpg w wybranym katalogu na karcie pamięci Raspberry Pi.
Na tym etapie zatrzymujemy uruchomiony wcześniej pakiet motion za pomocą skrutu klawiszowego Ctrl+X i skonfigurujmy jeszcze kilka rzeczy w pliku ustawień:
nano /etc/motion/motion.conf
Wskazanie katalogu do którego będą zapisywane przechwycone klatki poruszającego się obiektu:
# Target directory for pictures, snapshots and movies
target_dir /home/mariusz/motion/pictures/
Liczba klatek, która ma zostać przechwycona w ciągu sekundy:
# Maximum number of frames to be captured per second.
framerate 2
stream_maxrate 2
Włączenie zaznaczania poruszającego się obiektu za pomocą czerwonego prostokąta, dzięki czemu, będziemy mieli pewność, który obiekt spowodował detekcję ruchu. Będziemy również w stanie odróżnić klatki poprzedzające wykrycie ruchu od tych, na których ruchu nie wykryto, co dodatkowo ułatwi nam ocenę poprawności konfiguracji całego rozwiązania:
locate_motion_mode on
locate_motion_style redbox
Na czułość detekcji ruchu możemy wpłynąć poprzez zadeklarowanie liczby pojedynczych pikseli, które muszą się zmienić na przechwyconym obrazie, by wygenerować zdarzenie wykrycia ruchu:
# Threshold for number of changed pixels that triggers motion.
threshold 1500
Warto założyć jakiś minimalny poziom dopuszczalnego stałego ruchu pikseli w obrazie:
# Noise threshold for the motion detection.
noise_level 100
oraz zdefiniować wymaganą liczbę kolejno występujących po sobie ramek, na których wykryto „ruch”, celem eliminacji fałszywych alarmów na podstawie przetworzenia uszkodzonych klatek:
# Number of images that must contain motion to trigger an event.
minimum_motion_frames 3
Chwilę początkową wystąpienia detekcji ruchu zdefiniowaliśmy powyżej. Teraz wypadałoby zdefiniować moment, który motion zinterpretuje jako koniec występowania ruchu.
Pozostawimy domyślnie ustawioną wartość 60 sekund, ponieważ taki chcielibyśmy uzyskać interwał czasu pomiędzy kolejno wysyłanymi wiadomościami e-mail:
# Gap in seconds of no motion detected that triggers the end of an event.
event_gap 60
Warto również ustawić bufor kilku klatek poprzedzających moment wykrycia ruchu, które zostaną doklejone do serii zdjęć pokazujących całe zdarzenie. Te kilka obrazów poprzedzających samo wykrycie ruchu potrafi mieć kluczowe znaczenie dla poprawnej interpretacji zaistniałych wydarzeń.
# The number of pre-captured (buffered) pictures from before motion.
pre_capture 3
Doklejanie klatek po ustaniu ruchu, wydaje się nie mieć już większego znaczenia, zatem nie skonfigurujemy takiego zachowania.
Oprogramowanie motion pozwala wykonać dowolny skrypt użytkownika i to na różnym etapie trwania rejestracji całego zdarzenia. Ponieważ chcemy jak najszybciej wysłać maila z informacją o wykryciu ruchu, niech triggerem naszego skryptu (plik notify.sh w lokalizacji /home/mariusz/motion/scripts/ stworzymy później) będzie moment wykrycia ruchu (początek zdarzenia):
# Command to be executed when an event starts.
on_event_start /home/mariusz/motion/scripts/notify.sh
Innymi słowy, nie będziemy czekać na zakończenie zdarzenia, gdyż może ono trwać bardzo długo. Zamiast tego odczekamy kilka sekund by zebrało się kilka zdjęć, a następnie wyślemy je na docelowy adres mailowy, niezależnie od tego, czy „ruch” wciąż ma miejsce, czy może całe zdarzenie już się zakończyło.
Kluczową rzeczą dla realizacji naszych potrzeb jest załączenie zapisywania pojedynczych klatek po wykryciu ruchu w postaci obrazów:
# Output pictures when motion is detected
picture_output on
Obrazy te będą, za pomocą odpowiedniego skryptu, dołączone jako załącznik do maila z powiadomieniem.
Warto również zdefiniować rozsądne nazewnictwo tworzonych plików:
# File name(without extension) for pictures relative to target directory
picture_filename %Y.%m.%d-%H.%M.%S-%q
Z uwagi na zadanie do realizacji (wysyłanie powiadomienia mailowego z załącznikiem w postaci obrazów nieruchomych) wyłączymy tworzenie nagrań video (nie będą nam do niczego potrzebne):
# Create movies of motion events.
movie_output off
Teraz potrzebujemy zadbać o możliwość wysyłania maili z poziomu konsoli, a zatem także z poziomu skryptów powłoki bash.
By pominąć problemy z utrzymaniem własnego serwera poczty e-mail na tzw. białych listach dostawców internetowych (karkołomne zadanie) zamiast uruchamiania własnego serwera poczty, utworzymy darmowe konto pocztowe w serwisie interia.pl, a na RPi zainstalujemy paczkę sSMTP, która będzie wysyłała wiadomość e-mail z lokalnego komputera za pomocą skrzynki pocztowej założonej na Interii. Dodatkowo paczka mutt pomoże nam w dołączaniu do maila załączników w postaci plików .jpg.
W pierwszej kolejności zakładamy nową skrzynkę mailową wchodząc na link: https://konto-pocztowe.interia.pl/#/nowe-konto/darmowe. Po utworzeniu darmowej skrzynki pocztowej i zalogowaniu się do poczty: https://poczta.interia.pl/logowanie/ w panelu ustawień koniecznie załączamy możliwość logowania się do poczty z zewnętrznych programów pocztowych: https://ustawienia-pocztowe.interia.pl/#/poczta-parametry

Tak skonfigurowana poczta Interii jest już gotowa do obsługi za pomocą zewnętrznego klienta poczty e-mail (sSMTP, mutt).
Pora zainstalować parę sSMTP i mutt. Zakładając, że wciąż działamy na prawach administratora wykonujemy:
apt update
apt upgrade
apt install ssmtp mutt
Po zainstalowaniu pakietów, w katalogu domowym roota tworzymy katalog .mutt a w nim tworzymy plik konfiguracyjny .muttrc:
mkdir /root/.mutt/
nano /root/.mutt/muttrc
Do pliku wklejamy zawartość, jak poniżej, pamiętając o wcześniejszej podmianie nazwy użytkownika i hasła zgodnie z takimi, jakie zastosowaliśmy podczas tworzenia nowej skrzynki pocztowej.
set edit_headers = yes
set imap_user = "nasza.nazwa@interia.pl"
set imap_pass = "nasze.haslo"
set smtp_url = "smtp://nasza.nazwa@poczta.interia.pl:587/"
set smtp_pass = "nasze.haslo"
set from = "nasza.nazwa@interia.pl"
set realname = "nasza.nazwa@interia.pl"
set folder = "imaps://poczta.interia.pl:993"
set spoolfile = "+INBOX"
set header_cache=~/.mutt/cache/headers
set message_cachedir=~/.mutt/cache/bodies
set certificate_file=~/.mutt/certificates
set move = no
Po zapisaniu ustawień sprawdzimy, czy mutt będzie w stanie poprawnie zalogować się do naszej skrzynki. W tym celu wykonujemy polecenie:
mutt
Jeśli naszym oczom ukarze się plansza klienta poczty to oznacza to, że poczta została skonfigurowana poprawnie i jest gotowa do pracy:

Jako, że maile będziemy wysyłać za pośrednictwem konsoli i skryptów bash, opuśćmy naszego klienta używając przycisku q.
Nadszedł czas na przetestowanie wysyłki maila z konsoli. Można go przeprowadzić wydając polecenie:
test | EMAIL="nasza.nazwa@interia.pl" mutt -s "temat" jakis.adres@docelowy.com
Po kilku chwilach na nasz docelowy adres mailowy powinna dotrzeć wysłana przez nas wiadomość.
W lokalizacji /home/mariusz/motion/pictures prawdopodobnie znajduje się już kilka klatek zapisanych przez motion do obrazków w formacie .jpg (dobrze byłoby zostawić tylko kilka, bo za chwilę będziemy chcieli wysłać je wszystkie za pomocą poczty e-mail).
Spróbujmy zatem wysłać treść maila z szablonu z załączonymi plikami .jpg, posługując się poleceniem:
test | EMAIL="nasza.nazwa@interia.pl" mutt -s "temat" jakis.adres@docelowy.com -a /home/mariusz/motion/pictures/*.jpg
Jeśli nie popełniliśmy żadnago błędu, na docelową skrzynkę mailową trafi mail w postaci:

Na tym etapie pozostanie już tylko napisanie skryptu notify.sh w lokalizacji /home/mariusz/motion/scripts/, który już wcześniej przypisaliśmy do zmiennej on_event_start programu motion.
Otwieramy / tworzymy zatem plik skryptu:
nano /home/mariusz/motion/scripts/notify.sh
i umieszczamy w nim przykładowy kod, pamiętając o wprowadzeniu poprawnej ścieżki do plików oraz docelowego adresu e-mail dla powiadomień:
#!/bin/bash
#Script config section (do not mofify if you are not sure what you are doing)
timestamp=`date +%Y.%m.%d-%T`
date=`date +%Y.%m.%d`
installation_patch=/home/mariusz/motion
log_directory=$installation_patch/log/
log_file=$date.log
last_notifocation=$installation_patch/log/last_notification
pictures_directory=$installation_patch/pictures/
#e-mail config section (feel free to modify)
email_source=nasza.nazwa@interia.pl
email_target=jakis.adres@docelowy.com
email_title=$timestamp
email_attachment_patch=$pictures_directory*.jpg
#e-mail messages config section (feelfree to modify)
email_message_motion_notification="Notification about motion detected"
email_message_missing_patch="The system needs your attention: The patch is missing: "
email_message_missing_pictures="The system needs your attention: There is no any pictures to send. The pictures directory is empty: "
#log_messages (feel free to modify)
Preparing_to_send_notification="Preparing to send notification"
Pictures_to_be_sent="Pictures to be sent:"
Waiting_for_pictures="Waiting for pictures..."
Task_finished_successfully="Task finished successfully"
Old_pictures_has_been_removed="Old pictures has been removed"
Spacer="----------------------------------------------------"
#Script body (do not change anything below)
# Check for log directory presence
if [ ! -d $log_directory ]
then
echo "$email_message_missing_patch $log_directory" | EMAIL=$email_source mutt -s $email_title $email_target
fi
# Check for pictures directory presence
if [ ! -d $pictures_directory ]
then
echo "$timestamp - $email_message_missing_patch $pictures_directory" >> $log_directory$log_file
echo $Spacer >> $log_directory$log_file
echo "$email_message_missing_patch $pictures_directory" | EMAIL=$email_source mutt -s $email_title $email_target
fi
# Collecting pictures (waiting for the pictures)
echo "$timestamp - $Waiting_for_pictures" >> $log_directory$log_file
sleep 5
# Check for any pictures presence
files=($pictures_directory*)
if [ ! ${#files[@]} -gt 1 ]
then
echo "$timestamp - $email_message_missing_pictures $pictures_directory" >> $log_directory$log_file
echo $Spacer >> $log_directory$log_file
echo "$email_message_missing_pictures $pictures_directory" | EMAIL=$email_source mutt -s $email_title $email_target
fi
# If everything is OK send the pictures via e-mail
this_notofocation=`date +%Y-%m-%d-%H:%M`
previous_notofocation=$(<$last_notifocation)
#echo "Obecna notyfikacja: $this_notofocation"
#echo "Poprzednia notyfikacja: $previous_notofocation"
if [ -d $log_directory ] && [ -d $pictures_directory ] && [ ${#files[@]} -gt 1 ] && [ ! $this_notofocation == $previous_notofocation ]
then
echo "$timestamp - $Preparing_to_send_notification" >> $log_directory$log_file
echo "$timestamp - $Pictures_to_be_sent" >> $log_directory$log_file
ls $pictures_directory >> $log_directory$log_file
echo $email_message_motion_notification | EMAIL=$email_source mutt -s $email_title $email_target -a $email_attachment_patch
echo "$timestamp - $Task_finished_successfully" >> $log_directory$log_file
rm $pictures_directory*
echo "$timestamp - $Old_pictures_has_been_removed" >> $log_directory$log_file
echo $Spacer >> $log_directory$log_file
date '+%Y-%m-%d-%H:%M' > $last_notifocation
fi
Jeśli po uruchomieniu paczki motion bezpośrednio w konsoli wszystko działa poprawnie przyszedł moment by zadbać o to by motion startował automatycznie wraz z uruchomieniem platformy sprzętowej.
Przed przystąpieniem do wystartowania usługi, warto zadbać o właściwe uprawnienia do plików i lokalizacji:
chown motion /var/log/motion/motion.log
chown -R motion /home/mariusz/motion/
Po wykonaniu powyższych poleceń pozostaje spróbować uruchomić pakiet motion jako usługę:
sudo systemctl start motion
System powinien zacząć działać poprawnie. Dioda LED na kamerze powinna świecić cały czas. Gdyby jednak pi kilku sekundach się wyłączyła, będzie to oznaczało, że działanie pakietu zostało zakończone. Wówczas przyczyn warto poszukać w logach pakietu motion:
cat /var/log/motion/motion.log
Pomocne strony:




























