Chaos IoT

Liiketunnistimella toimiva kamera.


1 Johdanto

Tarkoituksena on tehdä IoT -laite, jonka avulla voidaan valvoa etänä tilaa. Laitteistoina käytetään Raspberry Pi 3 (model B) -tietokonetta, liiketunnistinta sekä kameraa. Raspberry Pi:n käyttöjärjestelmänä Raspbian Stretch, ohjelmointikielinä Python, PHP, HTML, CSS ja JavaScript.

2 Termit

Raspi = Raspberry Pi 3
PIR Sensori = Liiketunnistin
Skripti = Algoritmi

3 Vaatimukset

3.1 Tarvittavat Osat


Raspberry Pi 3, virtalähde, muistikortti (microSD), kortinlukija, PIR-sensori, Raspberry Pi kameramoduuli, kytkentäjohto, hiiri, näppäimistö, näyttö.

3.2 Tietotaidot


Tietokoneen perusymmärrys ja perustaidot.

4 Sovelluksen Toteutus

4.1 Yleinen Arkkitehtuuri


4.1.1 Käyttöjärjestelmän Asennus


Käyttöjärjestelmä (Raspbian Stretch with desktop) ladataan Raspberryn virallisilta sivuilta: https://www.raspberrypi.org/downloads/raspbian/ Kansiosta löytyvä näköistiedosto kirjoitetaan sd -kortille Etcher -ohjelmistolla, joka ladataan ja asennetaan https://etcher.io/ sivulta. Muistikortti asennetaan kortinlukijaan/koneeseen, avataan Etcher -ohjelmisto, painetaan “Select image” ja valitaan äsken ladattu käyttöjärjestelmäkansio. Tämän jälkeen klikataan “Select drive” ja valitaan muistikortti. Lopuksi “Flash!”. Kun Etcher on lopettanut kirjoittamisen, muistikortti asennetaan Raspberryyn ja seurataan alkuasennusohjeita.

4.1.2 Kieli-, näppäimistö- ja kamera-asetukset


Kun käyttöjärjestelmä on asennettu, säädetään asetuksia: Käynnistysvalikko -> Asetukset -> Raspberry Pi -> Configuration -> Localisation -> Set locate -> Kieliksi Suomi ja Keyboard->Suomi Interfaces->Camera: enable ja GPIO: enable

4.1.3 Videokameran suoratoistoserverin asennus


Suoratoistoa varten tietokoneelle asennetaan UV4L kamera-ajuri, sekä suoratoistoserveri ohjelmisto. Yksityiskohtaiset asennusohjeet löytyvät osoitteesta: http://www.linux-projects.org/uv4l/installation/ Asennus suoritetaan Raspbian Wretch käyttöjärjestelmän terminaalissa, käyttäen alla listattuja komentoja.
curl http://www.linux-projects.org/listing/uv4l_repo/lpkey.asc | sudo apt-key add -
Tämän jälkeen /etc/apt/sources.list tiedostoon lisätään seuraava rivi:
deb http://www.linux-projects.org/listing/uv4l_repo/raspbian/stretch
stretch main Tiedostoa /etc/apt/sources.list päästään muokkaamaan komennolla
sudo nano /etc/apt/sources.list
Tiedoston muokkauksen jälkeen suoritetaan järjestelmän päivityskomento sudo apt-get update Päivitys komennon jälkeen asennetaan UV4L ajuri ja ohjelmisto käyttäen komentoa
sudo apt-get install uv4l uv4l-raspicam
Ajurin ja ohjelmiston lisäksi asennetaan valinnainen lisäosa, joka mahdollistaa palvelun käynnistämisen käyttöjärjestelmän käynnistymisen yhteydessä. Lisäosa asennetaan komennolla
sudo apt-get install uv4l-raspicam-extras
UV4L ajuri ja ohjelmisto on nyt asennettu ja valmis käytettäväksi. Ohjelmiston graafiseen käyttöliittymään päästään syöttämällä verkkoselaimen osoitekenttään osoite http://localhost:8080/ Suoratoisto on nähtävissä ainoastaan sisäverkosta. Mikäli suoratoistoa haluttaisiin päästä katsomaan myös sisäverkon ulkopuolelta, tulisi reitittimestä avata portti 8080.

4.1.4 PIR-sensorin asennus


PIR-sensori kytketään Raspberry Pi:n GPIO pinneihin. Sensorin VCC kytketään Rasperry Pi:n pinniin numero 2, joka antaa sensorille 5V käyttöjännitteen. PIR-sensorin GND eli maa kytketään Raspberry Pi:n pinniin numero 6, joka on niin ikään GND eli maa. PIR-sensorin OUT kytketään Rasperry Pi:n datapinniin GPIO18 eli pinniin numero 12.
Liite 9.9 Raspberry Pi pin layout
Liite: 9.10 Raspberry Pi ja PIR-sensori

4.1.5 Kameran Asennus


Raspberry Pi kameramoduuli asennetaan Raspberry Pi:n CSI liittimeen, joka sijaitsee ethernet-liittimen ja HDMI-liittimen välissä. Kameran kaapeli asetetaan liittimeen siten, että kaapelin sininen puoli jää ethernet-liittimen puolelle.
Liite: 9.11 Raspberry Pi kameramoduuli


5 Käyttöliittymän Kuvaus

Hallintapaneeliin pääsee sähköpostiin tulevan liikkeestä ilmoittavan viestin “Hallitse ilmoituksia” -linkin kautta. Avautuvalla sivulla on kolme välilehteä:
Ilmoitukset -välilehdellä näkyvät raspin ottamat kuvat ja niiden ajankohdat.
Käyttäjät -välilehdellä käyttäjien tiedot. Mahdollisuus lisätä tunnuksia jotka saavat sähköpostin kun liikettä on havaittu ja tarvittaessa myös poistaa vanhoja tunnuksia.
Asetukset -välilehdellä Raspberryn hallintatyökalut.
App Key: Ohjelmiston käyttäjälle luoma yksilöllinen tunniste, jonka avulla palvelin kohdistaa vastaanottamansa tiedot tietylle käyttäjälle.
1.kuvake: Sammuttaa ilmoitusten lähetyksen
2.kuvake: Käynnistää raspin uudelleen
3.kuvake: Tilastot (mahdollisuus rajata päivämäärillä)
4.kuvake: Käynnistää etäterminaalin (tästä voi lähettää komentoja raspille jotka se toteuttaa/suorittaa kuten esimerkiksi: sudo reboot (käynnistää raspin uudelleen) tai sudo apt-get update (päivittää) jne..)

6 Funktioiden Kuvaukset

Kaikki koodit ja funktiot löytyvät meidän julkisesta GitHub profiililta:
https://github.com/OGkaaos/Chaos-IoT

Ensiksi pitää tarkistaa että palvelimella PHP versio on >5.4 ja tietokanta >5.5.51-38.1 ja jos on uudempi versio niin katso kohta 6.3 jossa näytetään miten koodi voidaan muokata toimivaksi jos on uudempi php/tietokanta.
kansiolle uploads/ pitää antaa 777 käyttöoikeudet jotta raspi pääsisi lataa kuvia sinne ja myös että FTP tunnuksella pitää olla root kansiona -> uploads/ kansio!
Liite 9.2 on kaavio joka näyttää mitä mikäkin algoritmi/koodi tekee. Ja koodien sisälle on lisätty kommentit jotka kertovat mitä mikäkin funktio tekee. Syy siihen et miksi laitettiin GitHub:iin on se että koodit ovat liiän pitkiä laittaakseen tähän.
Raspberry Pi:ihin tulisi asentaa seuraavat kirjastot (ei pakollisia):

1 Python Pillow (ei pakollinen):
https://pillow.readthedocs.io/en/latest/installation.html tämä pitää asentaa jos halua asentaa seuraavan kirjaston ”resizeimage” jolla pystyy muokkaamaan kuvan kokoa.

Asennusohjeet (Python Pillow):
Kirjoita terminaliin:

pip install pillow


2 Resizeimage (ei pakollinen):
https://pypi.python.org/pypi/python-resize-image tällä voidaan vaihtaa kuvan kokoa.

Asennusohjeet (Resizeimage):
Kirjoita terminaliin:
pip install python-resize-image 


Jotta koodi toimisi. Jos niitä asenna niin raspin koodista (motion_detector.py) pitää poistaa seuraavat koodit:
from PIL import Image               # Jotta voidaan vaihtaa kuvan kokoa
from resizeimage import resizeimage # Jotta voidaan vaihtaa kuvan kokoa

# tässä muutetaan kuvan kokoa jotta dashboard toimisi mahdollisimman nopeasti
fd_img = open('/home/pi/Desktop/havainnot/' + date + '.png', 'r')
img = Image.open(fd_img)                
img = resizeimage.resize_cover(img, [480, 360]) # Kuvan koko 480x360 img.save('/home/pi/Desktop/havainnot/' + date + '.png', img.format)
fd_img.close() # Suljetaan fd_img (resizeimage)


6.1 Algoritmien Järjestys


Seuraa 9.2 kaaviota aloittamalla ylhäältä ja siitä siirtymällä alaspäin. Aloita näistä:
Ja siitä siirtymällä muihin scripteihin. Ja sitä koodia voi testaa ilman raspia napsauttamalla ”testilähetys” asetukset välilehdellä (manage.php) Rivi: 366 (pitää vaihtaa linkin osoite omaan domainiin/scriptiin)

6.2 Tietokanta


Tulisi luoda tietokanta (MySQL) jonka saa luotua webbihotelli tarjoajan sivulta (omasta dashboardista). ><(9.8) löytyy kuvia tietokannasta mutta taulukkoja: image_logs, livestream ei tarvitse luoda. Luo tietokantaan seuraavat taulukot:

6.3 Ongelmat / Parannukset


Jotta ohjelmasta saataisiin turvallinen siihen pitäisi tehdä seuraavat muokkaukset:
Db.php tiedostossa:
mysql_connect("TIETOKANTA OSOITE/IP", "KÄYTTÄJÄNIMI", "SALASANA") or die(mysql_error()); mysql_select_db("TAULUKKO") or die(mysql_error());
Korvaamalla tällä:
$conn = mysqli_connect("TIETOKANTA OSOITE/IP", "KÄYTTÄJÄNIMI", "SALASANA") or die(mysqli_error());
mysqli_select_db("TAULUKKO") or die(mysqli_error());

Kaikistä php tiedostoista jossa on mysql yhteys/query pätkät seuraavasti:
mysql_query("SELECT * FROM users WHERE email='$email'");
Korvaamalla tällä:
$mysql = "SELECT * FROM users WHERE email='$email'"; $mysql_1 = mysqli_query($conn, $mysql); 
/* $conn meinaa tietokanta tiedostossa tietokanta yhteyttä ja $mysql meinaa ylemmän rivin query:iä */

Kaikki jossa ilmentyy mysql ! mutta query pysyy samana eli
$mysql = ”SELECT * FROM taulukon_nimi WHERE rivi = ’$joku’ ”;
$mysqli_query($conn, $mysql);


6.4 MySQL Injection ja sen estäminen


Sivustolla voi estää MySQL Injectionin vaihtamalla scripteistä (script/): $_POST / $_GET kohdat:
Esimerkki (activate.php):
$activate = $_GET[”status”];
Korvaa tällä:
$activate_html = htmlspecialchars(isset($_GET[”status”]) ? $_GET[“status”] : “”);
$activate = str_replace(“”, “'”, $activate_html);

Tämä estää käyttäjien lisäämään turhia “scriptejä” teksi kenttiin.

6.5 Python Koodi ja sen Testailu


Python koodi löytyy myös https://github.com/OGkaaos/Chaos-IoT/blob/master/Raspberry%20Koodi/motion_detector.py github:istä.


Voit testailla raspberry koodia aluksi rekisteröitymällä tälle sivulle tästä jonka jälkeen voit käyttää Python Generator:ia luodaakseen valmis python koodi omalla APP Avaimella jonka saat dashboardista asetukset välilehdeltä. Kun koodi on valmis voit lisätä sen raspiin ja käynnistää sen koodin. Ohjeet koodin availuun/käynnistykseen löytyvät kohdan 6.5.1 yläpuolelta (jos havainnot saapuu dashboardiin (ilmoitukset) välilehteen ilman virheitä ja kaikki toimii moitteettomasti niin voit jatkaa lataamalla oma kopio softasta tästä)

Python Generator (Ilman koodin muokkailua): Python Generator tai sitten manuaalisesti:

import os                           # Käyttöjärjestelmä
import RPi.GPIO as GPIO             # Raspberry GPIO
import time                         # Ajanhallinta
import requests                     # Nettisivun selailua varten
import picamera                     # Raspberry kamera (PiCamera())
import ftplib                       # FTP Latausta varten
import datetime                     # Päivämäärän luontia varten
import subprocess                   # Remote-Terminal varten
import threading                    # Timer:iä varten
from PIL import Image               # Jotta voidaan vaihtaa kuvan kokoa
from resizeimage import resizeimage # Jotta voidaan vaihtaa kuvan kokoa

camera = picamera.PiCamera() # PiCamera
pin = 18                     # Liiketunnistimen PIN -> 18

GPIO.setmode(GPIO.BCM)      
GPIO.setup(pin, GPIO.IN)

print "Paina Ctrl+C lopetakseen."
time.sleep(2)
print "Valmis..";

# Remote Terminal Koodi
def updates():
    threading.Timer(3.0, updates).start() # timer :: toistuu aina 3 sek välein
    
    # hakee/etsii tulevia komentoja
    link = 'https://marcosraudkett.com/mvrclabs/code/scripts/admin/script/pi-terminal/APPKEY/'
    f = requests.get(link) # lukee sivulla olevan tekstin
    #print f.text
    
    # toteutetaan komento raspberrillä
    shell = subprocess.Popen(f.text, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout
    response = shell.read() # luetaan shell
    #print response
    
    # skripti joka palauttaa viestin äskeiselle komennolla joka toteutettiin
    link_response = 'https://marcosraudkett.com/mvrclabs/code/scripts/admin/script/pi-terminal-response/APPKEY/&response='+response
    f2 = requests.get(link_response) # lukee sivulla olevan tekstin
    
updates()

# Liikettä Havaittu
try:
    while True:
        if (GPIO.input(pin)==1):
            print "Liiketta Havaittu"
            
            # luodaan päivämäärä + kellonaika NYT
            date = datetime.datetime.now().strftime("%m-%d-%Y_%H%M%S")
            
            # ottaa kuvan
            camera.capture('/home/pi/Desktop/havainnot/' + date + '.png')

            # tässä muutetaan kuvan kokoa jotta dashboard toimisi mahdollisimman nopeasti
            fd_img = open('/home/pi/Desktop/havainnot/' + date + '.png', 'r')
            img = Image.open(fd_img)
            img = resizeimage.resize_cover(img, [480, 360])
            img.save('/home/pi/Desktop/havainnot/' + date + '.png', img.format)
            fd_img.close()
            
            camera.vflip = True

            # FTP Lataus
            session = ftplib.FTP('website.com','FTP KÄYTTÄJÄNIMI','FTP SALASANA') # FTP Tiedot
            file = open('/home/pi/Desktop/havainnot/' + date + '.png', 'rb')                 
            session.storbinary('STOR ' + date + '.png', file)     
            file.close()                                   
            session.quit()
            
            # skripti joka tallentaa tietokantaan ja myös ilmoittaa käyttäjille jolla on kyseinen appkey ja &img=KUVAN PVM.png
            requests.get('https://marcosraudkett.com/mvrclabs/code/scripts/admin/script/service.php?app_key=APPKEY&img=' + date + '.png').content
            
            os.remove('/home/pi/Desktop/havainnot/' + date + '.png')
        
        # odottaa 4 sek ennenkuin voi havaita uudelleen.
        time.sleep(4)
except KeyboardInterrupt:
    print "Dead"
    GPIO.cleanup()


Python koodia voi avaa seuraavalla komennolla:

python /home/pi/Desktop/motion_detector.py
python /kansio/kansio/kansio/tiedoston_nimi.py

6.5.1 Python on Startup

Mikäli haluaa että python koodi avautuu heti kun raspi käynnistyy niin ohjeet siihen löytyy seuraavasta linkistä: http://www.instructables.com/id/Raspberry-Pi-Launch-Python-script-on-startup/

7 Yhteenveto

Mikäli haluaa nähdä livestreamin muualta kuin sisäverkosta, on avattava reitittimestä portti 8080 tai muulla tavoin avattava yhteys Raspberrystä internetiin. Tämä tekisi sovelluksesta hieman käyttökelpoisemman

Aluksi piti käyttää IoT alustana Cayenne IoT:tä, mutta huomasimme, että se asettaa projektille rajoitteita. Tästä syystä päätimme toteuttaa projektin ilman Cayenneä.

Lähteet

https://www.raspberrypi.org/
https://www.linux-projects.org/uv4l/installation/
https://www.raspberrypi.org/documentation/installation/installing-images/README.md

9 Liitteet

9.1 Lohkokaavio

lohkokaavio

9.2 Algoritmi Kaavio

algoritmi-kaavio

9.3 Hallintapaneeli Etusivu (Ilmoitukset)

hallintapaneeli-etusivu-ilmoitukset

9.4 Hallintapaneeli Etusivu (Käyttäjät)

hallintapaneeli-etusivu-kayttajat

9.5 Hallintapaneeli Etusivu (Asetukset)

hallintapaneeli-etusivu-asetukset

9.6 Hallintapaneeli Etusivu (Remote Terminal)

hallintapaneeli-etusivu-asetukset

9.7 Hallintapaneeli Etusivu (Tilastot)

hallintapaneeli-etusivu-tilastot

9.8 Tietokanta Yleisnäkymä (Taulukkoja image_logs ja livestream ei tarvitse)

tietokanta-yleisnakyma

9.8.1 Tietokanta (Commander Taulukko)

tietokanta-commander

9.8.2 Tietokanta (Mailer Taulukko)

tietokanta-mailer

9.8.3 Tietokanta (Notifications Taulukko)

tietokanta-notifications

9.8.4 Tietokanta (Settings Taulukko)

tietokanta-settings

9.8.5 Tietokanta (Users Taulukko)

tietokanta-users

9.9 Raspberry Pi PIN Layout

raspi-pin-layout

9.10 Raspberry Pi ja PIR-Sensori

raspi-ja-pisensor

9.11 Raspberry Pi ja kameramoduuli

raspi-picamera