Skip to content

Commit

Permalink
v2
Browse files Browse the repository at this point in the history
  • Loading branch information
omersavas26 committed Apr 1, 2021
1 parent a120281 commit f9f257a
Show file tree
Hide file tree
Showing 48 changed files with 2,312 additions and 1,071 deletions.
Binary file removed Kutu/Aski.stl
Binary file not shown.
Binary file removed Kutu/Cerceve.stl
Binary file not shown.
Binary file removed Kutu/Kapak.stl
Binary file not shown.
Binary file removed Kutu/Kutu.stl
Binary file not shown.
Binary file removed Kutu/Pencere.stl
Binary file not shown.
114 changes: 81 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,54 @@
# Mesai Takip Cihazı
## Kütahya İl Özel İdaresi - Bilgi işlem müdürlüğü

![Cihaz](./img/Cihaz.jpg)

Kütahya İl Özel İdaresi olarak geliştirmiş olduğumuz mesai takip cihazı. Yazılımı, devre tasarımı ve (3d yazdırılabilir) kutu tasarımı tamamen bize aittir. Tüm Raspberry Pi sürümleri ile çalışmaktadır. Fakat kutu RP3 için tasarlandığından diğer sürümleri için revizyon gerekir Cihaz kameranın bir özelliği olarak 135 derece oval fotoğraf almaktadır. Ayrıca yine kameranın bir özelliği olarak karanlık ortamlarda da -gece görüşü- fotoğraf alabilmektedir.
Kütahya İl Özel İdaresi için geliştirmiş olduğumuz mesai takip cihazıdır. Yazılımı, devre tasarımı ve (3d yazdırılabilir) kutu tasarımı tamamen bize aittir. Tüm Raspberry Pi sürümleri ile çalışmaktadır. Fakat kutu RP3 için tasarlandığından diğer sürümleri için revizyon gerekir.

13.56 Mhz rfid kart ile uyumludur. Kart okutulduğunda personelin resmini kaydeder, led ışık ve ses ile sinyal verir, sonra belirtilen web servisine geçiş hakkında istek gönderir (senkron yada asenkron seçebilirsiniz). Cevap olarak bir geçiş ID 'si ve personel ismini bekler. Istenilir ise kart okuduktan sonra bir turnikeye yada diğer bir donanıma tetikleme yapılabilir.
Cihazın açılması ile "main.py" yazılımı çalışır ve kart okutulması için beklemeye başlar. Başlatılması esnasında "./auth.py" dosyasını ve "./updateUsersList.py" dosyasını tetikleyerek cihaza özel güncel bir yetki alımasını ve bu yetkiyi kullanarak güncel kullanıcı listesinin alınmasını tetikler. Kullanıcı listesi personelin sunucu iletişimi esnasında bekletilmemesini sağlar. Personel kart okuttuğunda ilk olarak kameradan fotoğrafını alır, sonra ses ve ışık ile sinyal verir. Eğer okutulan kart id numarası "./file/users.json" dosyasında (bkz: "updateUserList.py") kayıtlı ise ekrana personel ismini yazar ver personeli bekletmeden gönderir. Sonra asenkron olarak sunucuya kart okutma bilgisini içeren bir istek atar cevap olarak da bir id numarası bekler. Cevap alabilirse çektiği fotoğrafın adını bu id bilgisi ile değiştirir. Eğer okutulan kart id numarası "./file/users.json" dosyasında yok ise sunucuya senkron bir istek atarak kart okutulma bilgisini gönderir cevap olarak de personel adı ve kart okutma için bir id numarası bekler. Beklediği cevap gelirse çektiği resmin adını yine id numarası ile değiştirerek personel adını ekrana yazdırır. Her ihtimal için; eğer beklenen cevap gelmez ise resmin adını card id ve tarih saat bilgisi olarak bırakır (bkz: "send.py"). Bir sonraki personelin kart okutmasını beklemeye başlar.

Sunucuya ulaşamaz ise offline olarak çalışabilir. Çekilen fotoğraflar geçiş zaman bilgileri ile birlikte tutulur. Sonra merkezi bilgi sisteminiz ftp bağlantısı ile resimleri alıp dosya sunucunuza taşıyabilir. Yada "aktar.py" dosyası belirli peryotlarda çalıştırılarak (cron) istenilen sunucuya yükleme işlemi cihaz tarafından da yapılabilir.
Eğer istenir ise, her kart okutmada bir kapı yada turnike tetiklenebilir. Ayrıca sunucu bağlantısı olmadan "./file/users.json" dosyasını manuel olarak doldurarak offline olarak da kullanılabilir.

Uygulama çalışma esnasında logları cihazin dosya sistemine txt dosyası olarak yazar. Beklenmedik bir hata oluşur ise hem offline logu tutulup hem de bir mesaj kuyruğuna (varsayılan RabbitMQ) log olarak yazılır.
Cihaz, personel geçişini yavaşlatmamak ve bağlantı olmadığı zamanlarda mesai takibini aksatmamak için çektği fotoğrafları önce hafızasında biriktirir sonra sizin belirlediğiniz peryotlarda sunucuya yüklemeye çalışır (bkz: "send.py"). Fotoğraflar "./foto" dizinindedir. İki tip fotoğraf vardır. İlki; sorunsuz bir şekilde sunucuya kart okutma bilgisi gönderilmiş ve cevap olarak da eklenen kaydın id bilgisi geri dönmüş olan fotoğraflar. Bunların isimleri "ID146589_XXXXX.jpg" şeklindedir. "_" karakterinden sonraki "XXXXXX" dizisi opsiyoneldir. Sunucu tarafından her kayıt için özel bir token gönderilir ise bu "XXXXXX" yerine yazılır. Böylelikle kayıt ikinci bir token ile korunmuş olur. Token bilgisini bilmeyen bir cihaz, fotoğraf yükleme yapamaz. İkinci tip fotoğraflar ise "TN198 76 64 27-2021_04_01_16_58_00.jpg" şeklinde isimlendirilmiştir. Bunlar, kart okutma bilgisi sunucuya gönderilememiş geçişler için çekilmiş olan fotoğraflardır. Adında kart bilgisi ve geçiş zamanını tutar. "send.py" yazılımı belirli peryotlarda çalışarak önce kayıt id 'leri olmayanları sunucuya kart okutma bilgisi oalrak gönderir ve id talep eder; ardından tüm fotoğrafları band genişliğini sınırlandırarak sunucuya yükler.

Uyguluma sorunsuz çalıştığı süre zarfında belirli aralıklarla bir Mqtt kuyruğuna sıhhat bilgisini gönderebilir.
Sahadaki çok sayıda cihazınızın güncellenmesi için bir mekanizma kurulmuştur. Cihazlar belirli aralıklarda sizin belirdiğiniz adresi kontrol ederek güncel dosyaları otomatik olarak alabilirler (bkz "update.py"). İstenirse bu adres token ile korunabilir. Bu sayede yazılımın yanı sıra font ve logo gibi bilgilerde uzaktan değiştirilebilir.

Cihazın crontab ile uygun görülen bir zamanda günde bir sefer yeniden başlatılması önerilir.
Cihaz kameranın bir özelliği olarak 135 derece oval fotoğraf almaktadır. Ayrıca yine kameranın bir özelliği olarak karanlık ortamlarda da -gece görüşü- fotoğraf alabilmektedir. 13.56 Mhz mifare rfid kart ile uyumludur.

İstenir ise cihazlar tek bir merkezden güncelleme alabilir (guncelle.py).
### auth.py
Eğer token auth ile çalışan bir servisiniz varsa bu dosya çalıştığında servisinize login isteği atar. Login olundu ise token ve cihaz ismi gibi bilgilerden "./file/auth.json" adında bir yetki dosyası oluşturur. "main.py" ve "send.py" gibi dosyalar ilk çalıştıklarında bu dosyayı tetikleyerek auth işlemi gerçekleştirirler ve çalışma süreleri boyunca auth.json dosyasını kullanırlar. Ayrıca cihaz ilk açıldığında da tetiklenir. Eğer cihaz yetkilendirmesi yapmak istenmiyorsa cihaz adı gibi bilgileri içeren sabit bir auth.json dosyası oluşturulabilir.

### clear.py
Cihaz ilk açıldığında çalışarak GPIO pin çıkışlarını temizler.

![Cihaz](./Cihaz.jpg)
### control.py
cron ile her dakika çalışarak "main.py" nin çalışıyor olması gibi kontrol edilmesi gereken süreçleri izler. Sorun var ise yeniden başlatır.


### dateTimeSync.py
Kısıtlı ağlarda cihaz tarih saat servisine erişierek zaman bilgisi alamaz ise bir http servis üzerinden tarih saat bilgisi alınarak cihazın zamanını günceller.


### fileList.txt
Bu dosya güncelleme sunucusu üzerinde bulunur. "update.py" yazılımı önce uzaktaki "version.txt" dosyasına sonra da bu dosyaya bakarak güncellemesi gereken dosyaları belirler ve güncel dosyaları indirerek cihaz üzerinde yazar. Yazılım mekanizmasına yeni bir dosya eklendi ise dosya adı ve yolu fileList.txt içine yazılmalıdır.

### main.py
Ana yazılımdır. Cihaz ilk açıldığında çalışmaya başlar ve kapanana kadar çalışarak personelin kart okutmasını bekler. Kart okutulması ile fotoğraf çeker ve sunucu bu kart okutulması hakkında bilgilendirir. Başlatılması esnasında "./auth.py" dosyasını ve "./updateUsersList.py" dosyasını tetikleyerek cihaza özel güncel bir yetki alımasını ve (eğer gerekiyorsa) bu yetkiyi kullanarak güncel kullanıcı listesinin alınmasını tetikler.

### send.py
"./main.py" tarafından üretilmiş olan fotoğrafları belirli aralıklara sunucuya yüklemeye çalışır. Başlatılması esnasında "./auth.py" dosyasını tetikler ve (eğer gerekiyorsa) sunucu iletişimi sırasında bu yetki bilgisini kullanır.

### update.py
Belirli aralıklarla güncelleme sunucusuna talepler göndererek gülcel bir sürüm var ise cihaz yazılımını günceller.

### updateUserList.py
Sunucudan güncel kullanıcı bilgisini ister ve "./file/users.json" dosyasını doldurur. İstenirse users.json dosyası manuel olarak doldurularak cihaz offline olarak da kullanılabilir.

### version.txt
Aynı anda hem cihazda hemde güncelleme sunucusunda bulunur. "./update.py" bu dosyaya bakarak, sunucu üzerindeki dosyadan farklı ise güncelleme yapar.

## Bileşenler
1. Raspberry Pi (3 önerilir)
1. Raspberry Pi (3 B+ önerilir)
2. Mikro SD kart
3. Raspberry Pi Camera (Raspberry Pi 3 Model B + Night Vision Camera 5MP Wide Angle 135 Degree Fisheye Lens 1080P Camera Module)
4. PCB Devre
Expand All @@ -34,46 +61,67 @@ Cihazın crontab ile uygun görülen bir zamanda günde bir sefer yeniden başla
11. Kaplama için yeteri kadar karbon folyo (Opsiyonel)
12. 4 adet 2.2x6 mm ve 3 adet 2.2x9 mm vida
13. 13x2, 4x1, 8x1 dişi header
14. Buzzer

## Donanım

[Video gelecek]

## Kurulum
## Yazılım

1. Image ile kurulum
.img dosyası indirilip micro sd karta "Win32 Disk Imager" yada benzeri bir uygulama ile yazılıp

2. Manuel kurulum
- Arduino klasorundeki buzzer.ino dosyası Arduino nanoya upload edilir.
- Raspbian işletim sistemi sd karta yüklenir ve açılır
- `sudo raspi-config` ile ayar ekranı açılıp ssh, camera, i2c ve spi aktifleştirilir
- Aşağıdaki kurulumlar yapılır.

```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install vsftpd apache2 git python-spidev python-dev python-pip python-smbus python-picamera python-netifaces python-imaging python-smbus i2c-tools wondershaper -y
sudo apt-get install git python3 python3-spidev python3-dev python3-pip python3-smbus python3-picamera i2c-tools wondershaper libopenjp2-7 -y
sudo python3 -m pip install -U pip
sudo python3 -m pip install -U setuptools
sudo pip3 install Pillow
sudo pip3 install adafruit-circuitpython-ssd1306
sudo pip3 install requests
sudo chmod 777 -R /var/www/html/
git clone https://github.com/lthiery/SPI-Py.git
cd ~/SPI-Py
sudo python setup.py install
pip install pika
pip install paho-mqtt
pip install requests
git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
cd Adafruit_Python_SSD1306
sudo python setup.py install
git clone https://github.com/lthiery/SPI-Py.git && cd SPI-Py && git checkout 8cce26b9ee6e69eb041e9d5665944b88688fca68 && sudo python3 setup.py install
```
- `sudo crontab -e` ile zamanlanmış görevler açılıp en alta aşağıdaki 5 satır eklenir.
```
@reboot sleep 5 && python /var/www/html/temizle.py &
@reboot sleep 20 && python /var/www/html/index.py &
30 22 * * * /sbin/shutdown -r +1 &
0 */2 * * * python /var/www/html/aktar.py &
0 12 * * * python /var/www/html/guncelle.py &
- `sudo crontab -e` ile zamanlanmış görevler açılıp en alta aşağıdaki satırlar eklenir.
.
```
@reboot python3 /var/www/html/clear.py &
@reboot python3 /var/www/html/dateTimeSync.py &
0 * * * * python3 /var/www/html/dateTimeSync.py &
@reboot sleep 10 && python3 /var/www/html/main.py
0 */2 * * * python3 /var/www/html/send.py &
0 12 * * * python3 /var/www/html/update.py
0 13 * * * python3 /var/www/html/updateUsersList.py &
* * * * * python3 /var/www/html/control.py &
30 22 * * * /sbin/shutdown -r +1 &
```
- index.py, MFRC522.py ve temizle.py guncelle.py aktar.py /var/www/html dizinine kopyalanır.
- Font klasöründeki lato.ttf dosyası /var/www/html/font dizinine kopyalanır.
- logo.png dosyası /var/www/html/img dizinine kopyalanır.
- Arduino klasorundeki buzzer.ino dosyası Arduino nanoya upload edilir.
- wget download.sh && ./download.sh
46 changes: 46 additions & 0 deletions afterUpdateSubscriber.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import sys
import json
import time
import traceback

sys.path.append("/var/www/html/lib/")
from helper import *
import helper as h

file_name = os.path.basename(__file__)

try:
def file_update(file_name):
txt = http_get(h.update_base_url+file_name)
write_to_file(h.app_base_path+file_name, txt)
log(INFO, file_name+" upgrade OK")

def version_file_update():
version_file = "version.txt"
log_and_run(file_update, version_file)

def update_file_update():
update_file = "update.py"
log_and_run(file_update, update_file)

def run():
log_and_run(version_file_update)
log_and_run(update_file_update)



#Ana Fonksiyon
if __name__ == "__main__":

preload(file_name)

log_and_run(run)

log_and_run(endload)



except Exception as e:
fn = os.path.basename(__file__)
root_ex(fn, e)
Loading

0 comments on commit f9f257a

Please sign in to comment.