Interop.zkemkeeper.dll kullanımı ve Parmak Okuma Sistemi

Son bir aydır yazılım danışmanlığını yapmakta olduğum hastanenin PDKS sistemi olan zkTECO firmasına ait parmak okutma cihazıyla ilgileniyorum. Bu cihaz Türkiye de kullanılan bir ürün olduğu için ilk başlarda veri okumada zorlanmam diye düşünmüştüm. Ancak yeterli Türkçe kaynak olmadığını, bu cihazı pazarlayan LiderZaman firmasının da yeterli kaynak paylaşmadığını görünce ihtiyacım olanı formlardan edindim. Bu zorlu süreç bana paylaşmanın ne kadar önemli olduğunu tekrar hatırlattı. O yüzden proje bitince yazmak istedim.

Öncelikle projenin amacı şuydu; 600 ‘e yakın personeli olan bir hastanede bir hemşirenin zamanında gelmemesi veya personel sorumlusunun bunu idare etmeye çalışması bir takim sorunlara sebep oluyor. Bu sorundan yola çıkarak, cihaz eskiden manuel bir şekilde parmak okutanları sisteme aktarıyordu. Biz bunu her 10 dakika bilgeleri aktar olarak değiştirdik. Ve en önemlisi belirlenen vardiya da işine gelmeyen personeli yöneticisine SMS olarak ilettik. Tüm müdür ve idari yöneticilere de mail olarak gönderdik. Böylece personel eksikliği anında belirleniyor ve sorun çözülmüş oluyor. Şimdi size cihazdan nasıl bilgi çektiğim konusunda bilgi vereceğim.

Öncelikle bu PDKS cihazlarından şu bilgiler gelir; PDKSID,PERSONEL NO, SAAT, TARIH buradan şunu anlamanız gerekir; gelen parmak okutma bilgisi giriş mi çıkışmı onu siz belirleyeceksiniz.

Bu bilgileri alırken yine dikkat etmeniz gereken bir şey var. Bilgileri oku dediğinizde cihaz disable yani pasif olur. O esnada parmak okutma yapılmaz. Cihaz bağlantınızı kapattığınızda tekrar aktif olur. O yüzden bu cihazdan bilgi çekme işlemi çok hızlı bitirilmeli yada musait bir zamanda yapılmalı. Ben cihazdan bilgileri çekmeyi PHP Soket programlama ile çözdüm ancak C# desteği ile cihazdan bilgileri silmeyi hallettim. Yine önemli bir nokta; siz cihazdan verileri silmediğiniz sürece 100K bilgi hafızada durur. Elektrik gittiği anda tüm bilgiler gider. Bir bakıma RAM ‘de tutar bilgileri. O yüzden her aktarımdan sonra silmeniz veri tekrarı olmaması için önemlidir.

İlgili firmaya ’10DK da bir veri yazsın istiyoruz’ dediğimizde bu sistemde bu tür işler olmaz demişlerdi. Buradan saygılarımı sunuyorum; ben yaptım oldu !

Kodlama kısmına gelince;
C# Örneklemesi

1-Adım:
zkemkeeper.dll ‘i indirip sisteme tanıtmanız gerekir. Bunun içinde şu kodu inc.bat olarak kayıt edip çalıştırın.(windows 10 için wow64 içine atın)
copy .\sdk\*.dll %windir%\system32\
regsvr32 %windir%\system32\zkemkeeper.dll

2- Adım:
Bunu ekledikten sonra Projeniniz Referance kısmından Add Referance diyerek Interop.zkemkeeper.dll ekleyin.

3-Adım:


int toplam = 0;
string sdwEnrollNumber = "0";
int idwVerifyMode = 0;
int idwInOutMode = 0;
int idwYear = 0;
int idwMonth = 0;
int idwDay = 0;
int idwHour = 0;
int idwMinute = 0;
int idwSecond = 0;
int idwWorkcode = 0;
bool bIsConnected = axCZKEM1.Connect_Net("192.168.1.241", 4370); //Ip ve Port bilgisini cihazın ayarlar kısmından öğrenebilirsiniz.
axCZKEM1.RegEvent(axCZKEM1.MachineNumber, 65535);
axCZKEM1.EnableDevice(1, false);
if (bIsConnected == true)
{
if (axCZKEM1.ReadGeneralLogData(1))//Hafızadan okuma modunda aç
while (axCZKEM1.SSR_GetGeneralLogData(1, out sdwEnrollNumber, out idwVerifyMode,
out idwInOutMode, out idwYear, out idwMonth, out idwDay, out idwHour, out idwMinute, out idwSecond, ref idwWorkcode))
{
int leng = sdwEnrollNumber.Length;
if (leng == 1) sdwEnrollNumber = "0000" + sdwEnrollNumber;
if (leng == 2) sdwEnrollNumber = "000" + sdwEnrollNumber;
if (leng == 3) sdwEnrollNumber = "00" + sdwEnrollNumber;
if (leng == 4) sdwEnrollNumber = "0" + sdwEnrollNumber;
string minute = "";
string hour = "";
if (idwMinute < 10) minute = "0" + idwMinute.ToString(); else minute = idwMinute.ToString();
if (idwHour < 10) hour = "0" + idwHour.ToString(); else hour = idwHour.ToString();
string saat = hour + ":" + minute;
string tarih = idwDay.ToString() + "." + idwMonth.ToString() + "." + idwYear.ToString();
string[] veriler = new string[2];
veriler[0] = sdwEnrollNumber.ToString();
veriler[1] = saat;
veriler[2] = tarih;
kayitlar += "PRNO:" + sdwEnrollNumber.ToString() + "-SAAT:" + saat + "-TARIH:" + tarih + "\n";

4- Hafızadan silmek için:

axCZKEM1.EnableDevice(1, true);
axCZKEM1.ClearGLog(1);

Tüm işlem bu kadar. Ama esas işlem cihazdan veriler geldikten sonra oluyor. Bu konuda yardıma ihtiyacı olan arkadaşlara yardımcı olabilir, firmanız için gerekli yazılımı geliştirebilirim.

Windows Görev Zamanlayıcısı ile .php Cron Job İşlemi Yapmak

Bu aralar zkTeco ve zkemkeeper.dll ile işlemler yapmaya çalışıyorum. Bu konu hakkında ayrıca bir yazı yazacağım ancak bugünkü konumuz .php dosyasının Windows ortamında nasıl Cron Job yapılacağı hakkında olacak. Bu yöntemin bir tane yöntemi yoktur eminim. Benim yapacağım işlerm script oluşturmak olacak.

Öncelikle localhostunuzun kurulu olduğunu varsayıyorum.

1– İlk Adım Script Dosyası oluşturmak:
Öncelikle .php exe niz neredeyse ve hangi .php dosyasını çalıştırmak istiyorsanız o dizinleri yazın. Dosyayı script.bat olarak kayıt ettiğimizi varsayalım.

1
"C:\wamp64\bin\php\php5.6.25\php.exe" -f "C:\wamp64\www\zk\test.php"

2- Şimdi Görev Zamanlayıcısının algılayabilmesi için .vbs oluşturmak gerekiyor onu yapıyoruz. Dizinlere dikkat edin.
script.bat isimli dosya 1. adımda. Bu dosyayıda shell.vbs olarak kayıt ediyorum

1
2
3
Set WinScriptHost = CreateObject("WScript.Shell")
WinScriptHost.Run Chr(34) & "C:\script.bat" & Chr(34), 0
Set WinScriptHost = Nothing

3- Son adım Windows Görev Zamanlayıcısını çalıştırmak olacak.
Eylemler- Program Başlat – Yeni – Program/Komut Dosyası- Buraya shell.vbs dosyasını seçiyorum.
Sağ taraftaki ‘Yeni Görev Oluştur’ seçiyorum. Tetikleyici kısmından – Yeni diyerek – Günlük 1 seçeneğini yazarak ‘şu süreyle kısmını süresiz’ yapıyorum – Görevi şu sıklıkla yenile kısmından 10 Dk yi seçiyorum.

Artık sistem hazır.

Windows Postgre SQL Dump etme

Var olan bir .sql dosyasını postgreSql de ‘cmd’ ekranında nasıl dump ederim diye düşünürken şu yöntemi buldum. Arşivlemek niyetiyle yazmak istedim.

1- Cmd ekranına girin

2- cd yaparak C:\Program Files\PostgreSQL\9.6\bin gibi bir yol bulup girin.

3- Girdikten sonra “psql -U username(postgres)” yazın burada hangi kullanıcı ismi ile bağlandıysanız onu yazın.

4- Şifrenizi girdikten sonra “\i E:/yedeklerim.sql” şeklinde dosyayı gösterin.

5- Bir bardak çay için 🙂

Eğer Ubuntu kullanıyorsanız sadece şunu deneyin:

1- psql -d dbIsmi -U username -f yedek.sql

Ubuntu ‘da Döküman İçinde Anahtar Kelime Arama

Bir muhabbette denk geldim, insanlar bir belge içersin de anahtar bir kelime aramak istediklerinde her belgenin içine tek-tek girip aradıklarını söylediler. Bu işlem Linux da çok basit olmasına karşın demek ki diğer sistemlerde bu şekilde değil. O yüzden paylaşmak istedim.

find . -iname ‘*docx’ | xargs grep ‘kelime’ -sl

-iname : *docx dediğim için tüm bilgisayarda ki word belgelerinin içersin de ‘kelime’ anahtarını arar. Eğer tüm dizinde tüm dosyalarda arama yapacaksanız -iname ‘*’ yapmanız gerekir.

Yine, yeniden …

2007 yılında başladığım blog tutma olayına, 2009 yılı itibariyle ara vermiş ve daha az yazar olmuştum. 2011 yılından sonra ise neredeyse hiç yazmadım. Yazmayı istesem de vakit ayıramadım.

Bir şeyler yazabilmek için ciddi bir zaman gerekiyor. Aynı şekilde yazacağın konu hakkında tam bilgiye sahip olmalısın ki okuyanı tatmin edesin. Tatmin edici bir şeyler yazmadıktan sonra ne gerek var kasmaya deyip bloguma dokunmamıştım.

Velhasıl; yeniden blog macerasına başlamış bulunmaktayım. Ağırlıklı olarak yazılım konusunda söyleyeceklerim olacak. Teknik konularda Türkçe içerik üreterek bir bakıma vicdanımı rahatlatmak istiyorum.

Eski blog sayfam hala duruyor. İncelemek isterseniz blog.yesersin.com ‘u ziyaret ediniz.

 

Güncelleme: 25 Kasım 2016 ‘da yaptığım bir hata sonucu tüm database silmiş bulundum. Allahtan google cache var. Tüm yazıları tekrar getirerek, -ki yorumlar hariç- siteyi tekrar kurmam gerekti. Erişim problemi yaşarsanız bu yüzdendir.

İyi okumalar.

Ubuntu TortoiseSVN Kurulumu

Github başta olmak üzere, ortak çalışma alanlarına bağlanmak için kullandığım SVN programı Tortise SVN dir. Kurulumu oldukça basittir.

Ubuntu Ver: 14.04

1
2
3
4
5
sudo add-apt-repository ppa:rabbitvcs/ppa
 
sudo apt-get update
 
sudo apt-get install rabbitvcs-nautilus3

GUI ‘sini görmek istiyorsanız “Oturum Kapat” yapıp tekrar girmeniz veya;

1
sudo nautilus

Temiz kodlamalar.

Ubuntu Apachi ve PHP (LAMP) Kurulumu

LAMP: Linux, Apache, Mysql, Php isimlerinin baş harflerini alan, paket halinde bir yazılımdır. Bunu kurduktan sonra ekstra bir yazılıma ihtiyacınız olmuyor.

Ayrı ayrı da yapabilirsiniz. Amerikayı tekrar keşfetmenin lüzumu yok. O yüzden LAMP kurup gerekli ayarları yapmanız zaman tasarufu açısından önemlidir.

1
sudo apt-get install apache2 php5 mysql-server phpmyadmin #sirayı takip etmeniz faydalıdır.

Sizden bir seçim yapmanızı isterse “apache2” seçin. Şifrenizi hatırlayacağınız bir şey girin.

Her şey sorunsuz gittiyse: Tarayıcınızı açın, adres olarak “http://localhost/” yazın “It’s Work” yazısını gördüyseniz çalışıyor demektir.

Ekrana Hata Mesajı Basmak

Yeni kurulum sonrasında php ekrana hataları basmıyor. Bunu aktif etmeniz gerekmektedir.

1
2
3
4
5
6
7
8
sudo gedit /etc/php5/apache2/php.ini
#Bu satırı
display_errors = Off
#bununla değiştirin
display_errors = On 
 
#Apache Restart:
sudo /etc/init.d/apache2 restart

Temiz kodlamalar.

MSSQL, Aynı Database Dosyasının Yedeğin Farklı İsimle Restore Edilmesi

MSSQL de var olan, canlıda ki bir veritabanın üzerinde değişiklik yapmak istemediğimden, bu veritabanının bir kopyasını alıp onun üzerinde deneme yapmak istedim. Bunun içinde baktım klasik Backup/Restore yöntemleri işimi görmüyor bende şu yöntemi keşfettim.

 

1. Adım
Backup aldığınız .bak dosyasının log file ismi önemli. Öncelikle onu öğrenmeniz gerek.

1
2
  restore filelistonly from disk='c:\Erkan-22082016100353.bak'
--Çıktısı LogicalName yazan kısımdır. Bende 'ERP' ve 'ERP_log' yazıyor. Yol kısmını da not alın

2. Adım
Sırada bu .bak dosyasının kopyasını yaratmak var. Move komutunun oldugu yere dikkat edin. Orası 1. adımda çıkan isimdir. Dosya yolu da yukardakı komutta çıkandır.

1
2
3
4
 restore database yedekDb From disk='c:\Erkan-22082016100353.bak'
with 
move 'ERP' to 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\yedekDb.mdf',
move 'ERP_log' to 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\yedekDb_log.ldf'

Artık elimde yedekDb isimli, erkan isimli veritabanının bire-bir aynısı database mevcut.

Linux da MSSQL GUI Bağlantı, FortiClient VPN, Remote Windows Uygulaması (Ubuntu, Kali .deb destekli)

Uzun yıllar Ubuntu kullandım. Linux benim için heyecan ve hız demek. Bu yüzdendir ki yaptığım her işi Ubuntu dan halletmeye çalışırım. Ancak iş sahası Windows olunca mecburen bir çok işi windows uyumlu yapmak gerekiyor. Benim en çok aradığım 3 program vardı. Bunlar windowsta ki işlerimin yarısı demekti.
Mssql arayüzüne bağlanmak, remote server desktop, birde ağın localine bağlanmak için forticlient. Bunların 3 ü olduktan sonra heryer Paris…

Mssql için DBeaver

Bence harika bir araç. Aklınıza gelen bütün DB ‘lere bağlanıyor. Kurulumu kadar kullanımı da basit.
dbeaver indirelim Debian 64bit olanı indirdim. İndirdiğimiz dizine girip -ki benim /root/Download klasörü

1
sudo dpkg -i dbeaver-ce_3.7.2_amd64.deb

Linux Forticlient VPN Kurulumu
Vpn ile şirket içi ağa erişmek için kullandığım harkulade bir araç.
forticlient sslvpn indirelim İndirdikten sonra kurulumu yukari da anlattığım gibidir.

Windowsa uzak masaüstü bağlantısı sağlamak için kullandığım Rdesktop

1
2
3
$ sudo add-apt-repository ppa:pmjdebruijn/rdesktop-release
$ sudo apt-get update
$ sudo apt-get install rdesktop

rdesktop terminal kullanımı

1
 rdesktop -u administrator -p sifremiz 192.168.1.200

Hepsi bu kadar.

Volley ile Android Json haberleşmesi

Merhaba,

Android ile uğraşıyorsanız mutlaka bir servis kullanıyorsunuzdur. Ben servis olarak Json kullanıyorum. Bu servis ile Android tarafında Volley kütüphanesi ile haberleşiyorum. Eğer zorlanan arkadaşlar varsa Volley nasıl kullanılır ufak bir örnekle anlatmaya çalışacağım.

1. Adım Öncelikle volley.jar ‘ı indirip. Projemizde app/libs/ içine kopyalamamız gerekiyor.
2. Adım Kopyaladıktan sonra Android studio kullananlar için “proje sağ tuş – Open Module Setting – Dependencies – Add( alt+insert) – file dependencies” diyerek /libs içinde ki volleyi bağımlılıklara ekliyoruz.
3. Adım AndroidManifest.xml dosyasını açıp içersine aşağıdaki yetkiyi ekliyoruz.

<uses-permission android:name="android.permission.INTERNET"/>

4. Adım volley sınıfı olan kodları yeni bir sınıf oluşturup “AppController.java” diyerek kayıt ediyoruz. Ve bunu /src/main/java/” içersine ekliyoruz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class AppController extends Application {
    public static final String TAG = AppController.class.getSimpleName();
 
    private RequestQueue mRequestQueue;
 
    private static AppController mInstance;
 
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
 
    public static synchronized AppController getInstance() {
        return mInstance;
    }
 
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
 
        return mRequestQueue;
    }
 
    public  void addToRequestQueue(Request req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }
 
    public  void addToRequestQueue(Request req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
 
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

5. Adım Her sınıf eklendikten sonra AndroidMaifest.xml ‘e bu sınıf kayıt edilmelidir. Bizde açıp aşağıdaki kodu “application” tagından sonra ekliyoruz.

  android:name=".AppController"

6. Adım Adım Son olarak json formatınıza göre sınıf yazmanız gerekiyor. Ben Array yapısını kullanıyorum, Json formatım şu:

  {
  "error": false,
  "sabitler": [
    {
      "yoneticiAdi": "Erkan Yeşersin",
      "yoneticiMail": "yesersin@gmail.com",
      "yoneticiTel": "123456",
      "yoneticiIban": "TR10200020000200002000000",
      "karOrani": "20" 
    }
  ]
}

7. Adım Veri çekmek için kullandıgımız sınıfımda şu şekilde:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
private  void JsonOrnegiFonksiyonu(){
 
        final StringRequest strReq = new StringRequest(Request.Method.GET,
                "http://erkanyesersin.com/ornekJson.php", new Response.Listener<String>() {
 
            @Override
            public void onResponse(String response) {
                try {
                    jsonResponse = "";
                    JSONObject jObj=new JSONObject(response);
 
                    boolean error = jObj.getBoolean("error");
                    if (!error) {
 
                        JSONArray questionsArray = jObj.getJSONArray("sabitler");
                        for (int i = 0; i < questionsArray.length(); i++) {
                            JSONObject c = questionsArray.getJSONObject(i);
 
                            String yoneticiAdi = c.getString("yoneticiAdi");
                            String yoneticiMail = c.getString("yoneticiMail");
                            String yoneticiIban = c.getString("yoneticiIban");
 
                            jsonResponse += "Name: " + yoneticiAdi + "\n\n";
                            jsonResponse += "Email: " + yoneticiMail + "\n\n";
                            jsonResponse += "Home: " + yoneticiIban + "\n\n";
                        } 
                        txtResponse.setText(jsonResponse); 
                    } 
 
                } catch (JSONException e) {
                    Log.i("BekleyenSiparis","Excep "+e.getMessage());
                    e.printStackTrace();
                }
 
            }
 
        }, new Response.ErrorListener() {
 
            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_SHORT).show();
 
            }
        });
 
        AppController.getInstance().addToRequestQueue(strReq, "ConstantInfo");
    }

8. Adım Veri göndermek için kullandıgımız sınıfımda şu şekilde:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  private void jsonSave(){
        StringRequest stringRequest = new StringRequest(Request.Method.POST,
                "http://erkanyesersin.com/test.php",new Response.Listener<String>(){
 
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jObj = new JSONObject(response);
                    Toast.makeText(getApplicationContext(),jObj.getString("mesaj"),Toast.LENGTH_LONG).show();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
 
            }
        }, new Response.ErrorListener() {
 
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Registration Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
 
            }
        }) {
            //Esas post işini yapan kısım.
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = map;
                map.put("test", "erkanssss");
                //burada put: ilk parameter $_POST["test"] olandır. Diğeride postun değeridir.
                return params;
            }
 
        };
        AppController.getInstance().addToRequestQueue(stringRequest, "ers");
    }