1MPLEMENTAS1 SC A DA PADA ANDROID DENGAN SIMULATOR MODBUSPAL STUDI KASUS PERUSAHAAN X
Skripsi
Disusun oleh : Audy Ram andha
10 9 0 9 10 0 0 159
PRO GRAM STUDI T E K N IK IN FORM ATI KA FA K U LTA S SAINS DAN T E K N O L O G I UNIVERSITAS ISLAM N EGERI SYARIF HIDAYATULLAH JA K A R T A 2015 M / 1436 H
IMPLEMENTASI SCADA PADA ANDROID DENGAN SIMULATOR MODBUSPAL STUDI KASUS PERUSAHAAN X
S K K IP S I Sebagai Salah Satu Syarat untuk M em peroleh G elar Sarjana K om puter
Pada Fakultas Sains dan T eknologi U niversitas Islam N egeri S y arif H idayatullah Jakarta
Olch : A u d y R am andha 109091000159
PRO G RA M STUDI T E K N IK INFORM ATIKA FAKULTAS SAINS DAN TE K N O L O G I UNIVERSITAS ISLAM NEGERI SYARIF HIDAYATULLAH JA K A R T A 2015 M / 1436 H
’’IM PLEM ENTASI SCADA PADA ANDROID DENGAN SIMULATOR MODBUSPAL STUDI KASUS PERUSAHAAN X”
SKREPSI S eb ag ai S a la h S a tu S y a ra t U n tu k M e m p e ro le h G e la r S a rja n a K o m p u te r F ak u ltas Sains d an T ck n o lo g i U n iv e rsita s Islam N eg cri S y a r if H id a y a tu lla h Ja k a rta
Oleh: AUDY RAMANDHA 109091000159
M enyetujui,
P e m b im b in g II
Pembimbing I
Hendra B
F eri F a h ria n to M .S c
lseno M .Kom
N IP . 1 9 8 2 1 2 1 1 2 0 0 9 1 2 1 003
N IP . 1 9 8 0 0 0 2 9 201101 1 002
M engetahui, K c tu a P ro g ra m Studi T c k n ik In fo rm atik a
A rini. M T
NIP. 19760131200901 2 001
’’IMPLEMENTASI SCADA PADA ANDROID DENGAN SIMULATOR MODBUSPAL STUDI KASUS PERUSAHAAN X”
Skripsi Sebagai Salah Satu Syarat U ntuk M em peroleh G elar Sarjana K om puter Pada Fakultas Sains dan T eknologi U niversitas Islam N egeri S y a rif H idayatullah Jakarta
Oleh: AUDY RAMANDIIA N I M : 109091000159
M enyetujui, P em b im b in g I
Pembjbnbing II
/ Feri Fahrianto. M .Sc NIP. 19800829 2011 1 002
no M .K om H endra Bavu N IP. 1982121 f 200912 1 003
Penguji I cA
Pengitji II
+ Q ^
A ndrew Fiade.M .K om NIP. 19820811 2009 1 004
. 19820823 201101 2 013
M engetahui,
yns^j/m T eknologi
in. Nl.Si Hk 3 999903 1 003
K etua Program Studi T ek n ik Inform atika
NIP. 19760131 200901 2 001
LEM BAR PERNYATAAN
D E N G A N INI S A Y A M E N Y A T A K A N
BAHVVA SK R IPSI INI B E N A R
A S M H A S IL K A R Y A S E N D IR I Y A N G B E U J M P E R N A H D IA J U K A N SE B A G A I
SK R IP SI
ATAU
KARYA
IL M IA H
PA D A
PERGURUAN
T IN G G I A T A U L E M B A G A M A N A P U N .
Jakarta, 10 Februari 2015
A udv R am andha N IM . 109091000159
v
AL'DY R A M A N D H A . Im plem entasi Scada Pada A ndroid D engan Sim ulator M odbuspal. Di bim bing oleh: Feri Fahrianto, M .Sc dan H endra Bayu Suseno, M .K om . ABSTRAK llin g g a saat ini (SCADA) m em pakan sistem control d ata dan pengaw asan digital y an g sedang po p u lcr dan banyak ditcrapkan dalam bcrbagai b id an g baik industri, perorangan, dan ju g a energi. A danya duk u n g an perkem bangan teknologi jaringan kom unikasi data scrta aplikasi sistem opcrasi yang mobile yang sudali dapat ditcrapkan di dalam perangkat handphone scperti A ndroid, dengan dukungan teknologi didalam nya term asu k nirkabel, k em udahan akses data menjadi lebih terorganisir dengan m enggunakan protokol M odbus. Dukungan Java untuk SC A D A su d ah mulai diberikan dengan adanya library open source yang bernam a Java M od b u s (Jam od) yang m en d u k u n g protokol M od b u s dengan TCP/IP. Proses m onitoring yang dijalankan tcntu tidak optim al tanpa pcran sistem untuk mcncatat data yang ada m clalui library yang berpcran dalam proses pcncatatan atas akuisisi data yaitu Opcncsv. D alam proses pcngopcrasian SC A D A yang telah terkonsep dengan baik dengan Sistem Aplikasi A ndroid tentunya dirancang dengan m enu yang sederhana dan m u d ah dim engerti terutam a untuk proses training yang c fe k tif sebelum operator bekerja di lapangan. Dalam pendukung proses pelatihan SC A D A yang efektif, penulis berinisiatif untuk m enam bahkan sim ulator pendukung input data yang bernam a M odbusPal. Piranti lunak ini selain m em p erm u d ah pem belajaran juga diharapkan dapat m enekan biaya atas pengadaan m odule perangkat keras y an g dinilai m cm akan biaya yang tinggi ju g a konfigurasi yang m enyita w aktu. D iharapkan dengan adanya Skripsi ini bertujuan m em buat aplikasi y an g m am p u m elakukan pengendalian pengaw asan dan ju g a akuisisi data yang baik dengan duk u n g an teknologi terbaru yang diharapkan d ap at dikem bangkan u n tuk pelatihan dan ju g a im plem entasi di lapangan. M eto d e yang digunakan p a d a skripsi ini adalah m odel proses extreme programming karena aplikasi yang akan dibuat tidak m em butuhkan w aktu yang lama (Agile method) dengan m ethod pengetcsan Blackbox testing. Bahasa p em ro g ram an Java pada smartphone Android. Inti dari skripsi ini yaitu tcrlctak pada im plem entasi S C A D A pada O S A ndroid dengan m enggunakan Library S C A D A yaitu Jamod, transfer data m enggunakan jarin g an N irkabel yang didukung protokol Modbus TCP/IP dengan sim ulator transm isi data m enggunakan M odbusPal dengan library O p en C S V untuk m enyim pan data yang tcrakuisisi d en g an fo rm a t file C SV . Data dan informasi yang ditam pilkan pada aplikasi ini diharapkan dapat m enjaw ab kcndala im plem entasi S C A D A yang dinilai cukup sulit terutam a dalam pcngaplikasian dengan teknologi terbaru untuk bcrbagai keperluan. Kata kunci: Im plem entasi, S C A D A , A ndroid, Sim ulator, M odbus, M odbusPal, JaM od, O penC SV , Nirkabel
KATA PENGANTAR
B ism i 1lah irrahm anirrah im , A lham dulillah, puji syukur penulis panjatkan kepada Allah S ubhanahu Wa T a 'a la atas seluruh rahm at dan karunia-N ya yang diberikan kepada penulis schingga penulis dapat m claksanakan pcnclitian skripsi ini dan m cnyclcsaikan penulisannya dengan baik. Shalaw at serta salam selalu tersam paikan kepada Rasulullah
Shalallahu
‘A laihi
W asallam ,
keluarganya,
sahabatnya,
serta
pengikutnya yang setia hingga akhir zam an. Skripsi ini berjudul “Im plem entasi S C A D A
pada A ndroid dengan
Sim u lator M odbuspal Studi K asus P erusahaan X ” , yang disusun untuk m em enuhi salali satu syarat dalam m enyelesaikan program Strata 1 pada Program Studi Tcknik Inform atika di U niversitas Islam N egeri S y a rif H idayatullah Jakarta. Harapan bahw a skripsi ini dapat bcrm anfaat bagi sem u a pihak yang berkepentingan, m erupakan kebahagiaan tersendiri bagi penulis w alaupun disadari bahw a “ tiada g ad in g yang tak retak” tidak ada sesuatu pun yang sem purna m clainkan Allah S W T S a n g M a h a Penguasa A lam Semesta. Pada kesem patan ini, penulis ingin m enyam paikan ueapan terim a kasih kepada pihak-pihak yang telah m endukung terselesaikannya skripsi ini. Karena tanpa dukungan dari m ereka, penulis tidak akan m am pu m enyelesaikan skripsi ini dengan baik. M ereka yang telah m endukung penulis adalah : 1.
Ibu dan A lm arhum A yah tercinta yang selalu m engiringi d o 'a dalam setiap langkah.
2.
Bapak DR. A gus Salim, M . Si, selaku D ekan Fakultas Sains dan Teknologi, U niversitas Islam N cgeri S y a rif H idayatullah Jakarta.
3.
Ibu Arini. M T, sebagai K etua P rogram Studi T eknik Inform atika, Fakultas Sains d an Teknologi. U niversitas Islam N egeri S y a rif H idayatullah Jakarta.
4.
Bapak Feri Fahrianto M .Sc, selaku dosen p em bim bing I dan Sekretaris K etua Program Studi T eknik Inform atika, Fakultas Sains dan T eknologi, U niversitas Islam
Negeri S y a rif H idayatullah Jakarta,
yang telah m em beri banyak
m asukan bagi penulis dalam m enyelesaikan skripsi ini. 5.
Bapak H endra Bayu S useno M .K om . selaku dosen p em bim bing II penulis yang selalu m enyem angati anak didiknya dan ju g a telah m em berikan banyak ban tu an bagi penulis dalam m enyelesaikan skripsi ini.
6.
A nggi
C ipla
Bcrliani,
istri saya,
yang tak
henti-hentinya
m em berikan
sem angat, w aktu dan d o ’a untuk m enyelesaikan skripsi ini, m em berikan motivasi di saal penulis mulai jen u h dengan skripsi ini. 7.
Luthfi A u ru m Arrasyid, A nakku yang selalu m enem ani ayahnya begadang dan m engganggu ayahnya dengan m em bantu “ m engetik” serta senyum annya yang m cm buat lelah pergi menghilang.
8.
Saudara-saudaraku seperjuangan di T eknik Inform atika yang sudah m enem ani penulis dalam m enyelesaikan skripsi ini. terutam a sahabat-sahabatku sem ua di FST TI angkatan 2009. Terim a kasih.
9. T em an -tem an say a di Perusahaan X, terim a kasih sem angat dan sarannya untuk penyclesaian skripsi ini.
10. Seluruh D osen dan s ta f karyaw an Fakultas Sains dan Teknologi, khususnya Program Studi T cknik Informatika. yang telah m cm b im b in g penulis sclam a m enuntut ilmu di U niversitas Islam N egeri S y arif H idayatullah Jakarta. 11. S em ua pihak yang sudah m em bantu dan tidak dapat disebutkan satu-persatu. Penulis m engharapkan kritik serta saran yang m em bangun dari pem baca untuk pcnulisan laporan yang lebih baik lagi. Kritik dan saran serta pcrtanyaan dapat
disam paikan
ke
penulis
melalui
email A u d y .R am an d h a@ g m ail.co m .
Sem oga skripsi ini dengan izin Allah S W T dapat berm anfaat bagi sem ua pem baca. Amin.
Jakarta, 10 F ebruari 2015
A udy R am andha N IM . 109091000159
DAFTAR ISI
H alam an LEM BAR SA M PU L........................................................................................................i LEM BAR PER N Y A TA A N .........................................................................................iv ABSTRAK.........................................................................................................................v KATA PEN GA N TA R................................................................................................... vi DAFTAR I S I ...................................................................................................................ix DAFTAR GAM BAR...................................................................................................xiii DAFTAR T A B E L .........................................................................................................xv
BAB I PENDAHULUAN.............................................................................................. 1 1.1. Latar Belakang............................................................................................................1 1.2. Rumusan M asalah..................................................................................................... 4 1.3. Batasan M asalah........................................................................................................ 5 1.4. Tujuan Penelitian.......................................................................................................6 1.5. Manfaat Penelitian.................................................................................................... 6 1.6. Metodologi Penelitian...............................................................................................7 1.6.1. Metote Pengumpulan D ata....................................................................................7 1.6.2. Metode Pengembangan Sistem.............................................................................8 1.7. Sistematika Penulisan..............................................................................................9
BAB II TINJAUAN PU ST A K A ............................................................................... 10 2.1. Konsep Implementasi............................................................................................ 11 2.2. Konsep SCADA..................................................................................................... 11 2.2.1 Konsep Akuisisi Data .................................................................................. 11 2.3. Konsep Modbus ................................................................................................... 12 2.3.1. Port Serial AT89S51...................................................................................... 19 2.4. Konsep Aplikasi M obile.......................................................................................22 2.4.1. Pengertian A plikasi.......................................................................................22 2.4.2. Aplikasi M obile..............................................................................................24 2.5. Simulator................................................................................................................25
ix
2.6. Google Android ................................................................................................... 26 2.6.1. Arsitektur A ndroid........................................................................................ 27 2.6.2. Fitur Android.................................................................................................. 29 2.6.3. Versi Sistem Operasi A ndroid.....................................................................30 2.6.4. Kelebihan dan Kekurangan Android...........................................................36 2.7. Basis D ata...............................................................................................................38 2.8. Software / Perangkat Lunak................................................................................. 38 2.8.1. Eclipse.......................................................................................................... 38 2.8.2. Android SDK(Software Development K it).............................................. 39 2.8.3. Java................................................................................................................39 2.8.4. SQLite.......................................................................................................... 41 2.9.
Library / Classpath............................................................................................ 42
2.10.
Java Modbus Library (Jamod).......................................................................... 43
2.11.
OpenCSV Library.............................................................................................. 44
2.12. M odbuspal........................................................................................................... 44 2.13.
Agile Software Development.............................................................................49
2.14.
Extreme Programming (XP) M odel................................................................. 51
BAB III M ETODOLOGI PE N E L IT IA N .............................................................. 54 3.1. Tempat dan waktu penelitian................................................................................. 54 3.2. Metode Pengumpulan D ata....................................................................................54 3.2.1. Studi Pustaka.................................................................................................. 54 3.2.2. W aw ancara.....................................................................................................58 3.3. Metode Pengembangan Sistem.............................................................................. 58 3.4. Kerangka B erfikir................................................................................................... 59
BAB IV ANALISA DAN PEM BAHASAN............................................................. 61 4.1. Planning................................................................................................................... 61 4.1.1. Visi A plikasi.................................................................................................. 62 4.1.2. Fitur Kunci......................................................................................................63 4.1.3. Tujuan Aplikasi..............................................................................................63
x
4.1.4. Pengguna Aplikasi.......................................................................................64 4.1.5. Informasi yang Dibutuhkan.......................................................................64 4.1.6. Kebutuhan Aplikasi untuk A ndroid......................................................... 64 4.1.7. Kebutuhan atas Simulator Pendukung...................................................... 65 4.2. Design....................................................................................................................... 65 4.2.1. Use C ase.........................................................................................................65 4.2.2. User Stories....................................................................................................66 4.2.3. Design CRC Card..........................................................................................67 4.2.4. Design G U I....................................................................................................72 4.2.5. Design Database............................................................................................ 75 4.3. Coding...................................................................................................................... 78 4.3.1. Pembahasan Fungsi...................................................................................... 78 4.4. Testing...................................................................................................................... 84 4.4.1. Pengujian dengan Unit Testing................................................................. 84 4.4.2. Pengujian dengan Implementation Testing.............................................. 85 4.4.2.1. Bukti Pengujian Implementasi....................................................... 87 4.5. Evaluasi Sistem....................................................................................................... 96 4.6 Contoh Training dan Simulasi................................................................................96 4.6.1 Contoh Kasus..................................................................................................96 4.6.2 Pembahasan K asus.........................................................................................97
BAB V P E N U T U P ................................................................................................... 104 5.1. Kesimpulan..........................................................................................................104 5.2. Saran..................................................................................................................... 105
DAFTAR PUSTAKA...............................................................................................107 LA M PIR A N ...............................................................................................................109 Lampiran Hasil W awancara..............................................................................109 Lampiran Koding................................................................................................113
xi
DAFTAR GAMBAR Halaman Gambar 2.1. Konsep SCA D A ...................................................................................... 11 Gambar 2.2. Sistem Pengiriman Query Respond.......................................................13 Gambar 2.3. Interval antar 3,5(atas) dan 1,5 (bawah) di dalam fra m e ....................15 Gambar 2.4. Driver dan receiver pada SN75176...................................................... 21 Gambar 2.5. Logo A ndroid.......................................................................................... 27 Gambar 2.6. Struktur Android......................................................................................28 Gambar 2.7. Logo Android versi 1.5 (Cupcake)........................................................31 Gambar 2.8. Logo Android versi 1.6 (Donut)............................................................32 Gambar 2.9. Logo Android versi 2.0/2.1 (Eclair)..................................................... 32 Gambar 2.10. Logo Android versi 2.2 (Froyo)...........................................................33 Gambar 2.11. Logo Android versi 2.3 (Gingerbread)............................................... 34 Gambar 2.12. Logo Android versi 3.0/3.1 (Honeycomb)..........................................34 Gambar 2.13. Logo Android versi 4.0 (Ice Cream Sandwich)..................................35 Gambar 2.14. Logo Android versi 4.1 (Jelly B ea n )...................................................35 Gambar 2.15. Logo Java............................................................................................. 40 Gambar 2.16. Skema Model X P ....................................................................................51 Gambar 3.1. Implementasi Scada pada Android dengan Simulator Modbuspal Studi Kasus Perusahaan X ................................................................................... 60 Gambar 4.1. Use Case untuk Aplikasi DroidSCADA..................................................... 66 Gambar 4.2. Desain Dashboard......................................................................................73 Gambar 4.3. Desain Device L ist.....................................................................................74 Gambar 4.4. Desain Tag Form.......................................................................................74 Gambar 4.5. Desain Device Form...................................................................................75 Gambar 4.6. Rancangan Database................................................................................... 76 Gambar 4.7. File Instalasi DroidSCADA.apk..................................................................88 Gambar 4.8. Menu instalasi DroidSCADA.apk.............................................................. 88 Gambar 4.9. Proses instalasi DroidSCADA.apk............................................................. 89 Gambar 4.10. Icon DroidSCADA terpasang di perangkatAndroid.................................89 Gambar 4.11. File Instalasi DroidSCADA.apk............................................................... 90 Gambar 4.12. Gambar Notifikasi atas belum adanya Device yang sudah dimasukkan.. 90 xiii
Gambar 4.13. Menu pada Dashboard DroidSCADA...................................................... 91 Gambar 4.14. Notifikasi apabila tidak ada data pada aplikasi.........................................91 Gambar 4.15. Tampilan Device List................................................................................92 Gambar 4.16. Tampilan input Sync Period pada Device Editor..................................... 92 Gambar 4.17. Detail Device Editor................................................................................. 93 Gambar 4.18. Gambar Detail untuk Setting untuk Suspend terhadap Device..................94 Gambar 4.19. Tampilan pada device list di yang sudah tersimpan..................................94 Gambar 4.20. Gambar Tag Editor....................................................................................95 Gambar 4.21. Gambar tampilan untuk mengatur Register Format.................................95 Gambar 4.22. Gambar Tentang Pengaturan tipe Register............................................... 96 Gambar 4.23. Gambar Tag yang sudah atur dan tersimpan............................................. 96 Gambar 4.24. Konfigurasi modbuspal.............................................................................99 Gambar 4.25. Konfigurasi device................................................................................101 Gambar 4.26. Device List........................................................................................... 101 Gambar 4.27. Konfigurasi Tag................................................................................... 101 Gambar 4.28. Dashboard setelah menambah 4 sensor............................................... 102 Gambar 4.29. Dashboard setelah service dijalankan................................................. 102 Gambar 4.30. Notifikasi Ekspor Data......................................................................... 103 Gambar 4.31. File hasil ekspor dibuka pada aplikasi MS Excel................................ 103 Gambar 4.32. Hasil rata - rata dari program MS Excel.............................................. 104
xiv
DAFTAR TABEL H alam an Tabel 2.1.
ASCII Framing Frame pada transmisi ASCII........................................14
Tabel 2.2.
RTU Framing Frame pesan pada mode transmisi R T U ....................14
Tabel 2.3.
Tabel fungsi M odbus................................................................................. 16
Tabel 2.4.
Exception C ode.......................................................................................... 19
Tabel 2.5.
Mode pada port serial AT89S51........................................................... 20
Tabel 2.6. Mode Pengiriman dan penerimaan data SN75176..........................................22 Tabel 3.1. Perbandingan Literatur Sejenis.....................................................................60 Tabel 4.1. CRC Card Dashboard.....................................................................................68 Tabel 4.2. CRC Card Device List.....................................................................................68 Tabel 4.3. CRC Card Device Form................................................................................. 69 Tabel 4.4. CRC Card Tag Form.......................................................................................69 Tabel 4.5. CRC Device List Adapter................................................................................ 69 Tabel 4.6. CRC Card Tag List Adapter............................................................................69 Tabel 4.7. CRC Card Core............................................................................................ 70 Tabel 4.8. CRC Card Worker.......................................................................................... 70 Tabel 4.9. CRC Card Converter.......................................................................................70 Tabel 4.10. CRC Card CSV........................................................................................... 70 Tabel 4.11. CRC CardLocalDB...................................................................................... 71 Tabel 4.12. CRC Card Device......................................................................................... 71 Tabel 4.13. CRC Card Tag............................................................................................ 71 Tabel 4.14. CRC Card TagValue..................................................................................... 71 Tabel 4.15. CRC Card Scale........................................................................................... 72 Tabel 4.16. CRC CardDeviceListObject.......................................................................72 Tabel 4.17. CRC Card TagListObject..............................................................................72 Tabel 4.18. CRC Card Modbus........................................................................................ 72 Tabel 4.19. Struktur Database Device.............................................................................77 Tabel 4.20. Struktur Database Tag.................................................................................. 78 Tabel 4.21. Struktur Database TagValue......................................................................78 Tabel 4.22. Hasil Pengujian Dengan Unit Testing........................................................ 86 Tabel 4.23. Hasil Pengujian Implementasi................................................................... 87
xv
BAB I PENDAHULUAN
1.1.
Latar Belakang Pada saat ini, kemajuan teknologi sangat berpengaruh terutama sebagai
sistem pengawasan dan pengendalian, terutama dalam bentuk proses yang menerapkan suatu sistem yang mengawasi setiap proses pada sistem dukungan dalam bentuk penyimpanan akusisi data. Dalam mendukung efisiensi dan efektifitas kegiatan industri dibutuhkan metode pengawasan yang memiliki biaya lebih murah dibanding harus membeli perangkat monitoring sistem yang terkontrol dan terakuisisi dengan implementasi yang berbiaya tinggi yang disamping itu juga untuk memenuhi kebutuhan training dan testing. Pada suatu industri yang memiliki banyak peralatan (plant) dengan letak geografis yang tersebar pada jarak yang cukup jauh, diperlukan sebuah sistem yang dapat melakukan pengawasan dan pengendalian jarak jauh. Sistem tersebut harus mampu melakukan pengawasan (supervisory) dan pengendalian (controlling) terhadap semua proses yang sedang berjalan. Untuk mengatasi permasalahan tersebut, banyak industri yang menerapkan SCADA (Supervisory Control and Data Acquisition) atau dapat juga diartikan dalam Bahasa Indonesia sebagai pengawasan kontrol dan akusisi Data sebagai sistem pengawasan dan pengendalian. Salah satu perusahaan yang bergelut di bidang pengawasan seperti ini adalah perusahaan X, dimana perusahaan ini memfokuskan diri sebagai penyedia perangkat PLC dengan koneksi Modbus TCP.
1
2
Sebagai perusahaan baru, perusahaan X ini belum mempunyai sarana untuk kebutuhan pelatihan dan testing konfigurasi PLC mereka. Hasil wawancara dengan beberapa orang yang terlibat (karyawan) di perusahaan X memang menunjukkan belum ada solusi untuk pelatihan dan pengetesan perangkat mereka, sedangkan solusi sementara membutuhkan pemahaman untuk bisa membaca data dari perangkat seperti perangkat Modbus TCP. Hal ini mengindikasikan kebutuhan aplikasi ringan berbasis Mobile untuk melihat hasil konfigurasi perangkat monitoring mereka. Mereka juga membutuhkan aplikasi tersebut untuk melatih pegawai mereka yang bertugas dengan peralatan untuk melakukan konfigurasi di lapangan, yang difokuskan pada penggunaan aplikasi beserta pengenalan fungsionalitas di dalamnya. Berdasarkan kebutuhan diatas, untuk menyelesaikan permasalahan dalam perusahaan X, penulis tertarik untuk melakukan implementasi sistem telekontrol SCADA berbasis Android. Untuk mendapatkan informasi yang relevan dalam identifikasi masalah dan penentuan atas fungsionalitas terhadap applikasi yang akan dibuat di dalamnya, penulis melakukan tahap wawancara pada para pegawai di perusahaan X dengan pendekatan User Stories yang menjadi bagian dari metode Extreme Programming. Pembahasan tentang metodologi ini termasuk pembahasan tentang penentuan permasalahan hingga proses testing dengan metode blackbox testing akan dibahas dalam bab selanjutnya (bab 4). Dalam sistem telekontrol SCADA ini, akan menggunakan Modbuspal yang didedikasikan sebagai simulator pembentuk komponen Master dan Slave. Komunikasi antara Master dan Slave menggunakan komunikasi fungsi dasar protokol Modbus. Kemudian peralatan yang
3
digunakan untuk input akuisisi data adalah android. Sistem perangkat mobile ini memiliki keunggulan dalam mobilitas yang tinggi dengan aplikasi berbasis android yang dibenamkan sebuah library yang bernama Java Modbus Library (Jamod) untuk mempersingkat waktu pembuatan aplikasi. Dalam transfer data tentunya diperlukan sebuah dukungan jaringan yang dapat diandalkan dengan sambungan secara nirkabel (Wireless), sebagai bentuk implementasi jaringan yang akan dipergunakan adalah pemancar nirkabel dengan menggunakan router yang sudah tersambung dengan perangkat pemancar data dengan dukungan protokol Modbus dan juga perangkat android. Untuk setiap data yang ditransfer tentunya menggunakan p ort tertentu yang terhubung dari IP pada setiap PC yang terpasang Modbuspal.
Default
port
untuk
Modbus
adalah
502.
Penulis
akan
mengimplementasikan sebuah aplikasi yang bernama “DroidSCADA” yang berarti SCADA yang berjalan pada sistem operasi Android. Dalam aplikasi tersebut fungsi yang akan diterapkan dapat mengindentifikasi setiap Device dan Tag yang terhubung dengan dengan aplikasi SCADA, menampilkan data yang yang diakuisisi di dalam menu, pengaturan atas device dan tag serta proses backup data dan beberapa menu akan meliputi “View Dashboard System ”, “View D evice”, “Device Menu ”, “Tag menu ”, “Export Data to CSV” , dan fungsi yang pada setiap penjelasannya akan dibahas pada bab 2 dan juga bab 4 untuk ulasan mengenai setiap fungsi dari mekanisme atas aplikasi yang berjalan. Dan sebagai bentuk persiapan aplikasi ini terhadap training, penulis akan mensisipkan contoh training yang akan diterapkan oleh perusahaan X.
4
1.2.
Rumusan Masalah Berdasarkan identifikasi masalah yang penulis dapatkan dari proses
wawacancara dengan internal perusahaan X (User Stories) maka perumusan masalah yang telah didapatkan adalah sebagai berikut : 1. Metode apa yang akan digunakan untuk menentukan kebutuhan sehingga dapat menjawab pertanyaan utama tentang Aplikasi apa yang akan dibuat dengan dasar dari akuisisi data yang dapat dipantau dalam kurun jangka waktu tertentu dalam proses pelatihan. 2. Apa yang dapat dipakai sebagai solusi dari perangkat modul yang dinilai mahal untuk kebutuhan testing dan memiliki nilai kepraktisan dari sisi hardware dan software 3. Apa yang dapat dilakukan menyimpan data yang didapat sehingga dapat ditentukan track record dari hasil pengarsipan atas akuisisi data 4. Bagaimana menentukan library khusus yang tepat terutama untuk proses pendukung SCADA dan proses Back Up? 5. Bagaimana membangun aplikasi yang dapat menyesuaian terhadap kebutuhan (User Requirement) yang berubah seperti perubahan konfigurasi, dan backup dalam aplikasi monitoring SCADA dengan menggunakan smartphone berbasis android 4.1.1 (Jelly Bean)”.
5
1.3.
Batasan Masalah Berdasarkan masalah di atas maka ruang lingkup penelitian dibatasi pada: 1. Dalam Implementasinya aplikasi ini menggunakan user story sebagai acuan yang didapat daripada para engineer di lapangan dan beberapa orang dari internal perusahaan. 2. Penulis hanya memfokuskan pada bagaimana implementasi aplikasi sehingga bisa berjalan, tidak pada sisi keamanan maupun infrastruktur pendukung terhadap performa melainkan pada kecepatan pembuatan aplikasi yang sederhana dan mendukung aspek pelatihan bagi tiap individu yang berkecimpung di bidang otomasi, control dan monitoring. Apabila ada hal yang dirasa akan berdampak pada hal-hal tersebut, akan dimasukkan ke dalam bab saran yang akan digunakan untuk pengembangan selanjutnya. 3. Aplikasi ini mendukung pengaturan terhadap penentuan Port, dengan koneksi nirkabel terhadap simulator Modbuspal dengan koneksi TCP/IP dan batas register address 0-65535 yang dapat di simpan dengan Sampling Period ke dalam format CSV. 4. Aplikasi dibuat dengan menggunakan mobile development system android. 5. Penulis hanya akan menggunakan Modbuspal sebagai simulator pendukung dalam akuisisi data terutama dalam transfer data. 6. Aplikasi hanya mendukung koneksi Modbus TCP/IP dan dijalankan menggunakan koneksi wireless. 7. Penggunaan library jam od (java Modbus) untuk akuisisi data menggunakan protokol modbus dan library opencsv untuk ekspor data yang tersimpan
6
kedalam format csv. Contoh simulasi training akan disisipkan di akhir bab 4, tidak disertai hasil pengerjaan dan hasil atas contoh training.
1.4.
T ujuan Penelitian Tujuan dari pembuatan tugas akhir ini adalah agar perusahaan X dapat
menyediakan sarana yang mudah dan murah bagi para engineer di perusahaan x untuk dapat melakukan konfigurasi perangkat ataupun training untuk konfigurasi PLC Modbus mereka sebelum terjun ke lapangan dengan menggunakan perangkat android.
1.5.
M anfaat Penelitian
1. Bagi Penulis Sebagai
masukan
dan
memperluas
cakrawala
penulis
dalam
mengimplementasikan suatu sistem untuk memecahkan masalah-masalah yang dihadapi dengan hal yang sederhana dan mendasar, serta bertujuan untuk melengkapi tugas-tugas dan memenuhi syarat guna meraih gelar strata satu (S1) program studi Teknik Informatika, Fakultas Sains dan Teknologi UIN Syarif Hidayatullah Jakarta. Penulis juga mendapatkan manfaat teknis seperti reusable codes yang dapat digunakan pada sistem serupa namun berbeda kasus dikemudian hari. Ditambah penulis mendapatkan sebuah basis aplikasi yang bisa lebih mudah untuk dikembangkan menjadi aplikasi SCADA dengan fitur yang lebih lengkap.
7
2. Bagi Umum Membantu dalam pemahaman terhadap suatu sistem yang mendukung applikasi berbasis mobile SCADA untuk tujuan khusus seperti edukasi dan keterampilan. 3. Bagi P eru sah aan Mempermudah dan menekan biaya pengadaan perangkat SCADA yang lebih besar yang digunakan hanya untuk testing konfigurasi perangkat mereka. 4. Bagi Universitas Memperkaya literatur tentang aplikasi mobile android khususnya pada monitoring dan otomasi yang diaplikasikan ke berbagai bidang terutama rekayasa teknologi (engineering).
1.6.
Metodologi Penelitian Metodologi penelitian yang digunakan dalam penulisan skripsi ini meliputi:
1.6.1. M etode Pengum pulan D ata Di dalam menyusun skripsi ini, penulis berusaha mendapatkan serta mengumpulkan data yang lengkap guna menyusun karya ilmiah ini. Adapun metode yang penulis gunakan dalam mendapatkan data-data sebagai berikut : a. Penelitian Kepustakaan (Library Research) Pengumpulan data dan informasi dengan cara membaca buku-buku dan referensi dari internet yang dapat dijadikan acuan pembahasan dalam masalah. Juga digunakan penelitian atas karya Studi literatur sebagai pembanding yang baik dalam perencanaan dan pengembangan.
8
b. Penelitian Lapangan (Field Research) Dalam hal ini penelitian dilakukan dengan wawancara bebas didalam meeting yang dirangkum secara tertulis di perusahaan X.
1.6.2. M etode Pengem bangan Sistem Metode pengembangan sistem yang akan digunakan yaitu metode yang mengikuti kaidah berbasis objek (object oriented). Pada kasus ini menggunakan Agile
Software
Development
dan
proses
model
menggunakan Extreme
Programming (XP). Pemilihan metode ini dikarenakan aplikasi yang akan dibuat tidak terlalu kompleks dan tergolong perangkat lunak kecil dan juga hanya membutuhkan waktu pengerjaan yang singkat. XP mencakup beberapa aturan dan praktek yang terdiri atas planning, design, coding dan test. Berikut penjelasan dari masing-masing tahapan yang akan dilakukan pada pembuatan aplikasi ini. 1. Planning : Perencanaan terhadap software yang diinginkan mengacu pada user stories. User stories menggambarkan fitur dan fungsi yang dibutuhkan terhadap software tersebut. 2. Design : Proses desain pada XP mengikuti prinsip K IS (Keep It Simple) dan menggunakan CRC cards untuk design aplikasi. 3. Coding : Aplikasi akan dibuat menggunakan ADT (Android Development Tools), juga akan membahas tentang implementasi coding berupa fungsi yang berjalan. 4. Testing : testing terhadap aplikasi menggunakan Black box Testing dengan cara Unit Testing.
9
1.7.
Sistematika Penulisan Skripsi ini terdiri dari lima bab yang disusun sedemikian rupa dengan materi
pembahasan yang saling berhubungan dengan sistematika sebagai berikut : BAB I
PENDAHULUAN Bab ini akan diuraikan latar belakang, perumusan masalah, batasan masalah, tujuan dan manfaat penelitian, metodologi penelitian, dan sistematika penulisan.
BAB II
LANDASAN TE O R I Dalam bab ini akan dijelaskan mengenai landasan teori yang relevan dengan permasalahan yang ada.
BAB III
M ETO D O LO G I PENELITIAN Bab ini akan diuraikan metodologi penelitian yang digunakan diantaranya
metodologi
pengumpulan
data
dan
metodologi
pengembangan sistem. BAB IV
ANALISA DAN PEMBAHASAN Bab ini akan diuraikan dan membahas hasil penelitian pengembangan sistem
SCADA
meliputi
hasil
wawancara,
analisis,
desain,
implementasi, operasi dan sistem pendukung. BAB V
PENUTUP Bab ini akan disajikan kesimpulan dan saran-saran yang penulis angkat berdasarkan pembahasan pada bab-bab sebelumnya.
BAB II LANDASAN TEO R I
2.1 . Konsep Im plem entasi Implementasi adalah proses untuk memastikan terlaksananya suatu kebijakan dan tercapainya kebijakan tersebut. Implementasi juga dimaksudkan menyediakan sarana untuk membuat sesuatu dan memberikan hasil yang bersifat praktis terhadap sesama. Van Horn Dan Van Meter mengartikan implementasi kebijakan sebagai tindakan-tindakan oleh individu publik dan swasta (atau kelompok) yang diarahkan pada prestasi tujuan yang ditetapkan dalam keputusan kebijakan sebelumnya (Subarsono (2006 : 100)). Jadi implementasi dimaksudkan sebagai tindakan individu publik yang diarahkan pada tujuan serta ditetapkan dalam keputusan dan memastikan terlaksananya dan tercapainya suatu kebijakan serta memberikan hasil yang bersifat praktis terhadap sesama. Sehingga dapat tercapainya sebuah kebijakan yang memberikan hasil terhadap tindakan-tindakan individu publik dan swasta. Berdasarkan pengertian implementasi yang dikemukakan di atas, dapat dikatakan bahwa implementasi adalah tindakan-tindakan yang dilakukan pihakpihak yang berwenang atau kepentingan baik pemerintah maupun swasta yang bertujuan untuk mewujudkan cita-cita atau tujuan yang telah ditetapkan, implementasi dengan berbagai tindakan yang dilakukan untuk melaksanakan atau merealisasikan program yang telah disusun demi tercapainya tujuan dari program yang telah direncanakan.
10
11
2.2.
Konsep SCADA Sistem SCADA (Supervisory Control A nd Data Acquisition) yang dalam
terjemahan Bahasa Indonesia Kontrol Pengawas dan Akuisisi Data adalah sebuah sistem pengawasan dan pengendalian, dengan cara melakukan pengumpulan dan analisa data secara real time. Sistem SCADA terdiri dari 3 bagian utama yaitu Master, slave, dan media komunikasi. Arsitektur SCADA diperlihatkan pada Gambar 2.1.
Gambar 2.1 konsep SCADA Sistem SCADA memiliki fungsi yaitu untuk pengukuran jarak jauh (telemetering) dan pengendalian jarak jauh (telecontrolling). Dengan fungsi tersebut, sistem SCADA mampu melakukan pengawasan dan pengendalian plant jarak jauh. 2.2.1 Konsep Akuisisi D ata Akuisisi data adalah suatu proses pengambilan data sampel dari fenomena fisik (suhu, tekanan dan lain-lain) dan mengkonversikan data sampel yang didapat menjadi nilai numerik yang dapat dimanipulasi oleh sebuah komputer. Sistem akuisisi data adalah kumpulan dari berbagai elemen-elemen elektronik yang saling bekerja sama dengan tujuan melakukan pengumpulan, penyimpanan,
12
pengolahan data, dan penyaluran data untuk dijadikan sebagai suatu bentuk informasi yang berarti. Elemen-elemen dasar dari sistem akuisisi data berbasis komputer (PC), sebagaimana ditunjukkan pada Gambar 2.1, antara lain : • Transduser; • Pengkondisi sinyal (signal conditioning); • Perangkat keras (hardware) akuisisi data; • Sebuah komputer PC; dan • Perangkat lunak (software) yang terkait. (sumber : http://elib.unikom.ac.id/files/disk1/459/jbptunikompp-gdl-ahmadzaena22924-2-unikom_a-i.pdf)
2.3.
Konsep Modbus Protokol Modbus merupakan aturan-aturan komunikasi data dengan teknik
Master-Slave. Dalam konunikasi tersebut hanya terdapat satu Master dan satu atau beberapa slave yang membentuk sebuah jaringan.
Komunikasi Modbus
selalu diawali dengan query dari Master dan slave memberikan respon dengan mengirimkan data atau melakukan aksi sesuai perintah dari M aster. Master hanya melakukan satu komunikasi dalam satu waktu. Slave hanya akan melakukan komunikasi jika ada perintah (query) dari Master dan tidak bisa melakukan komunikasi dengan slave yang lain.
Pada saat mengirimkan query ke slave,
Master menggunakan 2 mode pengalamatan, yaitu: •
Unicast mode : Master mengirimkan query kepada satu slave. Setelah
menerima dan memproses query, slave akan memberikan jawaban berupa respon kepada M aster.
13
•
Broadcast mode : Master mengirimkan perintah (query) kepada semua
slave. Pada mode pengalamatan ini, slave tidak mengirimkan respon kepada Master. Protokol Modbus membentuk sebuah format pesan untuk query Master dan respon slave.
(J u d y
Adri) M » V r
■■ - r v i i v
SJrtw Aillra-*;
h t f i t t m L ttk
l in - ln r t t «1«V
Q a a y D tila
R lmmhi-.i: Q iti
r r m r O ie r i i
Ft t t ChSvk'
R flJU tt M r
ftiitn StovC"
G am b ar 2.2. System Pengirim an Query Respond Mode Transmisi Serial Dalam jaringan Modbus terdapat 2 mode transmisi serial, yaitu mode RTU dan mode ASCII. Setiap peralatan dalam sebuah jaringan Modbus harus mempunyai mode dan parameter serial yang sama. Pengaturan default Modbus adalah RTU, sedangkan mode ASCII adalah pilihan. Pada Mode RTU (Remote Terminal Unit) Format masing-masing byte (11 bit) dalam mode RTU adalah: Coding system
: 8 bit biner, heksadesimal 0-9,A-F.
Bits p er byte : 1 start bit. 8 data bits, Least Significant Bit (LSB) dikirim pertama. 1 bit untuk even/odd parity, no bit untuk no parity. 1 stop bit jika menggunakan parity, 2 bits untuk no parity. Error check fie ld : Cyclical Redundancy Check (CRC). Pada Mode ASCII (American Standard Code fo r Information Interchange) Format masing-masing byte (10 bit) dalam mode ASCII adalah: coding system heksadesimal, karakter ASCII 0-9, A-F. Bits per byte: 1 start bit.
7 data bits,
14
Least Significant Bit (LSB) dikirim pertama. Satu bit untuk even/odd parity, no bit untuk no parity. Satu stop bit jika menggunakan parity, 2 bits untuk no parity. Kemudian pada error check field adalah penentuan jenis tipe pada Longitudinal Redundancy Check (LRC).
Kemudian hal yang perlu diketahui
dari jenis
Modbus Message Framing yaitu ASCII Framing Frame dengan konsep pengiriman pesan pada mode transmisi ASCII ditunjukkan pada Tabel 2.1. Tabel 2.1 ASCII Framing Frame pada transm isi ASCII START
ADDRESS
FUNCTION
DATA
1 CHAR
2 CHAR
2 CHAR
n CHAR
LRC CHECK 2 CHAR
END 2 CHAR CRLF
Pada mode ASCII, pesan dimulai dengan sebuah karakter colon (:) dalam ASCII 3A hex, dan diakhiri dengan sebuah pasangan carriage return - line fe ed (CRLF) dalam ASCII 0D dan 0A hex.
Kemudian selanjutnya, RTU fram ing
fram e pesan pada mode transmisi RTU ditunjukkan pada gambar tabel 2.2 dibawah ini:
Table 2.2 RTU Framing Frame pesan pada mode transm isi RTU START >3,5 CHAR
ADDRESS
FUNCTION
DATA
S BIT
3 BIT
nxE BIT
CRC CHECK i6 B rr
END T3, >3.5 CHAR
Pada mode RTU, frame pesan dipisahkan oleh silent interval paling sedikit waktu 3,5 karakter. Interval waktu ini disebut T3,5. Seluruh karakter dalam fram e pesan harus ditransmisikan secara bersambung. Interval antar karakter dalam fram e pesan tidak boleh lebih besar dari waktu 1,5 karakter (T1,5). Jika interval
15
antar karakter lebih besar dari T1,5, maka fram e pesan tersebut dinyatakan tidak lengkap dan akan diabaikan.
G am b ar 2.3 interval a n ta r 3,5(atas) dan 1,5 (bawah) di dalam fram e Address field masing-masing slave harus mempunyai alamat yang berbeda dalam range 1 - 247 untuk pengalamatan individual. Alamat 0 digunakan untuk pengalamatan broadcast. Function field function fie ld pada fram e pesan berisi nomer kode fungsi (function code). Kode fungsi yang valid mempunyai range 1 255, dimana kode 1 - 127 untuk fungsi normal, sedangkan 128 - 255 untuk fungsi exception response. Function code berfungsi untuk memberitahu slave tentang perintah yang harus dikerjakan dan sebagai indikasi respon normal atau jenis error yang terjadi (exception response). Pada sistem komunikasi Modbus, jumlah function code yang didukung bervariasi tergantung kontroler dan peralatan slave yang digunakan.
16
Table 2.3 Tabel fungsi M odbus Kode Fungsi 1 = 01H 2 = 02H 3 = 03H 4 = 04H 5 = 05H 6 = 06H 15 = OFH 16= 10H
Fungsi
Aksi yang dikerjakan
Read CoiJ Status Read Input Status Read Holding Registers Read Input Registers Force Single Coil Preset Single Register Force Multiple Coils Preset Multiple Registers
Membaca status ON/OFF coil (output digital). Membaca status ON/OFF input digital. Membaca nilai output analog. Membaca nilai input analog. Mengset status satu coil pada keadaan ON/OFF. Mengset nilai satu output analog. Mengset status beberapa coil pada keadaan ON/OFF. Mengset nilai beberapa output analog.
Keterangan beberapa fungsi dasar yang perlu diperhatikan: 1. Coil = fungsi input secara biner untuk menyatakan input 1 adalah ON dan 0 adalah off, dapat diatur untuk fungsi unt.uk membaca, mengatur juga menetapkan fungsi status (force) dengan output digital baik untuk satu input/output maupun banyak sekaligus (multiple). 2. In p u t status (Input Contact) = menyatakan fungsi input yang dimasukkan sebagai sebuah output pada hasil secara langsung secara digital.. 3. Registers = menyatakan input/output yang dihasilkan dari penerimaan data dari input secara analog baik digital baik untuk satu input/output maupun banyak sekaligus (multiple). Data field pada query berisi kode sebagai informasi tambahan pada function code tentang aksi yang harus dikerjakan slave. Informasi tersebut bisa berupa alamat input-output, jumlah input- output, jumlah byte data, atau nilai data
17
pengesetan. Jika tidak terjadi error, data field pada respon berisi data yang diminta. Sedangkan pada exception response, data field berisi exception code. Error Checking Field.
LRC (Longitudinal Redundancy Check) Pada mode
ASCII, error checking field berisi 2 karakter ASCII yang didasarkan metode LRC. Prosedur perhitungan nilai LRC adalah: 1. Tambahkan semua byte pesan tanpa mengikutkan karakter start yaitu colon dan karakter end yaitu CRLF, dan tanpa melibatkan carry. 2. Kurangkan nilai FF hex dengan nilai hasil penjumlahan semua byte pesan, untuk menghasilkan komplemen 1. 3. Tambahkan hasilnya dengan 1 untuk menghasilkan komplemen dua. Hasilnya merupakan nilai LRC. CRC (Cyclical Redundancy Check) Pada mode RTU, error checking field berisi sebuah nilai 16 bit (2 byte) yang didasarkan pada metode CRC. Prosedur perhitungan CRC adalah: 1. Inisialisasi nilai register 16 bit CRC dengan FFFF hex. 2. Eksklusif OR 8 bit data pesan pertama dengan low order byte register CRC, letakkan hasilnya di register CRC. 3. Geser kanan register CRC 1 bit ke arah LSB, dan MSB diisi dengan 0. Nilai LSB register CRC yang tergeser diperiksa. 4. Jika LSB tergeser adalah 0, ulangi langkah 3 (pergeseran yang lain). Jika LSB tergeser 1, eksklusif-OR register CRC dengan nilai A001 hex (1010 0000 0000 0001).
18
5. Ulangi langkah 3 dan 4 sampai delapan pergeseran. Setelah delapan pergeseran, proses 8 bit data pesan pertama selesai. 6. Ulangi langkah 2 - 5 untuk 8 bit data pesan berikutnya sampai semua data diproses. 7. Nilai akhir register CRC adalah nilai CRC. 8. Pada saat CRC ditempatkan di pesan, nilai CRC low order byte dikirimkan terlebih dahulu dikuti high order byte. Pada exception response terdapat 4 proses komunikasi yang mungkin terjadi antaraMaster dan slave, yaitu: •
Jika slave menerima pesan query tanpa adanya kesalahan komunikasi, dan Slave dapat menangani query tersebut, Slave akan memberikan sebuah respon normal.
•
Jika slave tidak menerima query dikarenakan adanya kesalahan komunikasi, maka tidak ada respon yang dikirimkan. Master akan memberikan kondisi time-out untuk pengiriman query tersebut.
•
Jika Slave menerima pesan query, tetapi terdeteksi kesalahan komunikasi (parity, LRC, atau CRC), maka tidak ada respon yang dikirimkan. Master akan memberikan kondisi time-out.
•
Jika Slave menerima query tanpa adanya kesalahan komunikasi, tetapi Slave tidak dapat menangani perintah tersebut (contoh: perintah untuk membaca coil atau register yang tidak ada), Slave akan mengirimkan sebuah respon pengecualian (exception response) untuk memberikan informasi kepada master letak kesalahan yang terjadi. Pada sebuah exception response, slave
19
mengembalikan kode fungsi dengan MSB (Most Significant Bit) di set 1 dan data field diisi dengan kode pengecualian (exception code). Hal ini dimaksudkan agar master mengetahui exception yang terjadi. Beberapa exception code berikut keterangannya ditunjukkan pada gambar tabel 2.4. Tabel 2.4 Exception Code
Kode 01
Nama ILLEGAL FUNCTION
02
ILLEGAL DATA ADDRESS ILLEGAL DATA VALUE
03
Arti Kode fungsi yang terdapat dalam query merupakan perintah (action ) yang tidak diizinkan untuk Slave. Alamat data dalam quer\m merupakan alamat yang tidak diizinkan untuk Slave. Nilai dalam data field quenm merupakan nilai yang tidak diizinkan untuk Slave.
Komunikasi Serial Komunikasi serial ada 2 macam, yaitu komunikasi sinkron dan asinkron. Komunikasi sinkron dilakukan dengan menambahkan sinyal
sinkronisasi.
Komunikasi
asinkron
dilakukan
dengan
menetapkan
kecepatan bit (baud rate) dan menyisipkan beberapa bit protokol, yaitu bit start, parity dan bit stop. 2.3.1 P o rt Serial AT89S51 Mikrokontroler AT89S51 memiliki fasilitas port serial yaitu P3.0 untuk RxD dan P3.1 untuk TxD. Port serial AT89S51 ini bersifat fu ll duplex, artinya dapat mengirim dan menerima data secara simultan. Selain itu memiliki buffer penerima, sehingga port serial dapat bersiap menerima data kedua sebelum data
20
pertama dibaca dari register penerima. Register penerima dan pengirim port serial diakses melalui SBUF (Serial Buffer). Port serial AT89S51 dapat bekerja dalam 4 mode, dengan pemilihan seperti dalam tabel 2.5. Tabel 2.5 M ode pada p o rt serial AT89S51 SMO 0
SMI 0
Mode 0
0 1
L 0
1 2
Keteranaan Shift Register 8 bit UART 9 bit UART
1
1
3
9 bit UART
Baud Rate 1/12 Frekuensi Oscillator Diset oleh Timer 1/64 atau 1/32 Frek. Oscillator Diset oleh Timer
Baud rate untuk Mode 1 dan Mode 3 ditentukan oleh overflow rate Timer 1 dan nilai SMOD dengan persamaan sebagai berikut: ySMOD
Baud Rate Mode 1,3 = ------- x Timer 1 Overflow Rate 32 Frekuensi Osilator Baud Rate Mode 1,3 = 32 12 x [256-(77/1)] Standar RS232 merupakan aturan mengenai level tegangan, konektor dan aturan komunikasi. Standar RS232 memiliki level tegangan antara -3 sampai -15 Volt untuk logika high, dan antara +3 sampai +15 Volt untuk logika low. Level tegangan antara -3 sampai +3 Volt tidak didefinisikan, sebab di daerah ini kemungkinan adalah noise. Pada komunikasi
serial
RS485
digunakan
sepasang
kabel untuk
mengirimkan satu sinyal. Tegangan antara kedua kabel saluran selalu berlawanan. Logika ditentukan dari beda tegangan antara kedua kabel tersebut. SN75176
21
merupakan IC multipoint RS485 transceiver. Di dalam SN75176 terdapat sebuah driver dan receiver seperti pada Gambar 2.4. DE
G am b ar 2.4 D river dan receiver p ad a SN75176 SN75176 dapat mendukung 32 unit paralel dalam satu jalur. Sensitivitas tegangan input receiver 0,2 V dan jarak maksimum 4000 feet. Pada mode pengiriman (transmitting), kaki enable kirim DE diberi logika 1. Keluaran A dan B ditentukan oleh masukan driver D, dimana keluaran A akan sesuai dengan logika driver D, sedangkan B berkebalikan. Jika input D berlogika 1, maka output A akan bertegangan 5 Volt dan output B 0 Volt. Sebaliknya jika input D berlogika 0 maka output A bertegangan 0 Volt dan output B 5 Volt. Pada mode penerimaan (receiving), kaki enable terima RE diberi logika 0. Output receiver R ditentukan oleh tegangan diferensial antara input A dan B (VA - VB). Jika tegangan diferensial VB A - VB lebih besar dari +0,2 Volt, maka receiver R akan berlogika 1, sedangkan jika VA - VBB lebih kecil dari -0,2 Volt maka receiver R akan berlogika 0. Untuk tegangan VA - VB antara -0,2 Volt sampai +0,2 Volt, maka level logika keluaran tidak terdefinisi. Mode pengiriman dan penerimaan data SN75176 ditunjukkan pada tabel 2.6.
22
Tabel 2.6 M ode pengirim an dan penerim aan d ata SN75176 IN P U T D H L
ENABLE DE H H L
X
D IF F E R E N T IA L IN P U T S (A - B )
v m> < u v -0,2V < Vm < 0j2V Vro < -0.2V X
O PEN
O U TPU T A H L Z
ENABLE RE L L L H L
B
L H Z
O U TPU T R H o L Z
•7
H = H igh Level, L = L ew Level, x = Irrelevant, Z —high im pedance (off), ? = Indeterm inate Jika terdapat gangguan listrik yang menimpa saluran transmisi, maka induksi tegangan gangguan akan diterima kedua kabel saluran sama besar. Karena receiver membandingkan selisih tegangan antara dua kabel saluran, maka induksi tegangan tidak akan berpengaruh pada output. Dengan kemampuan menangkal gangguan yang sangat baik ini, RS485 bisa dipakai untuk membangun saluran transmisi jarak jauh sampai 4000fe e t dengan kecepatan tinggi. 2.4.
Konsep Aplikasi Mobile
2.4.1. Pengertian Aplikasi Aplikasi
menurut Jogiyanto
(1999:12),
adalah penggunaan
dalam
suatu komputer, instruksi (instruction) atau pernyataan (statement) yang disusun sedemikian rupa sehingga komputer dapat memproses input menjadi output.
23
Menurut Kamus Besar Bahasa Indonesia (1998 : 52), “Aplikasi adalah penerapan dari rancang sistem untuk mengolah data yang menggunakan aturan atau ketentuan bahasa pemrograman tertentu”. Aplikasi adalah suatu program komputer yang dibuat untuk mengerjakan dan melaksanakan tugas khusus dari pengguna. Aplikasi merupakan rangkaian kegiatan atau perintah untuk dieksekusi oleh komputer. Program merupakan kumpulan instruction set yang akan dijalankan oleh pemroses, yaitu berupa software. Bagaimana sebuah sistem komputer berpikir diatur oleh program ini. Program inilah yang mengendalikan semua aktifitas yang ada pada pemroses. Program berisi konstruksi logika yang dibuat oleh manusia, dan sudah diterjemahkan ke dalam bahasa mesin sesuai dengan format yang ada pada instruction set. Program aplikasi merupakan program siap pakai. Program yang direka untuk melaksanakan suatu fungsi bagi pengguna atau aplikasi yang lain. Contohcontoh aplikasi ialah program pemproses kata dan WebBrowser. Aplikasi akan menggunakan system operation (OS) komputer dan aplikasi yang lainnya yang mendukung. Istilah ini mulai perlahan masuk ke dalam istilah Teknologi Informasi semenjak tahun 1993, yang biasanya juga disingkat dengan app. Secara historis, aplikasi adalah software yang dikembangkan oleh sebuah perusahaan. Aplikasi adalah software yang dibeli perusahaan dari tempat pembuatnya. Industri PC tampaknya menciptakan istilah ini untuk merefleksikan medan pertempuran
24
persaingan yang baru, yang paralel dengan yang terjadi antar sistem operasi yang dimunculkan. 2.4.2. Aplikasi M obile Aplikasi adalah suatu perangkat lunak atau program yang ditulis oleh manusia untuk melakukan tugas-tugas atau memecahkan masalah tertentu. Sedangkan mobile dapat diartikan sebagai perpindahan yang mudah dari suatu tempat ke tempat yang lain. Aplikasi mobile merupakan aplikasi yang dapat digunakan walaupun pengguna berpindah dengan mudah dari satu tempat ke tempat lain tanpa terjadi pemutusan atau terputusnya komunikasi. Aplikasi ini dapat diakses melalui perangkat nirkabel seperti handphone, smartphone, tablet dan PDA (Romdani, 2010). Berikut ini merupakan karakteristik perangkat mobile, yaitu: 1.
Ukurannya kecil; perangkat mobile memiliki ukuran yang kecil, konsumen menginginkan perangkat yang terkecil untuk kenyamanan dan mobilitas mereka.
2.
Memory yang terbatas; perangkat mobile juga memiliki memory yang kecil yaitu primary (RAM) dan secondary (disk).
3.
Daya akses yang terbatas; sistem mobile tidaklah setangguh desktop.
4.
Mengkonsumsi daya yang rendah; perangkat mobile menghabiskan sedikit daya dibandingkan dengan mesin desktop.
5.
Konektivitas yang terbatas; perangkat mobile memiliki bandwidth rendah bahkan beberapa perangkat tidak tersambung.
25
6.
Kuat dan dapat diandalkan; karena perangkat mobile selalu dibawa kemana saja, mereka harus cukup kuat untuk menghadapi benturanbenturan, gerakan, dan sesekali tetesan air.
7.
Masa hidup yang pendek; perangkat konsumen ini menyala dalam hitungan detik kebanyakan dari mereka selalu menyala.
2.5.
Sim ulator Simulator dalam Depdiknas (2005: 1068) adalah program yang berfungsi
untuk menyimpulkan suatu peralatan, tetapi kerjanya agak lambat daripada keadaan yang sebenarnya. Simulator juga dapat diartikan sebagai simulasi atau objek fisik-benda nyata. Simulasi dalam Depdiknas (2005: 1068) adalah metode pelatihan yang meragakan
sesuatu
dalam
bentuk
tiruan
yang
mirip
dengan
keadaan
sesungguhnya. Bambang Sridadi (2009: 65) mengemukakan bahwa simulasi adalah proses implementasi model menjadi program komputer (software) atau rangkaian
elektronik dan
mengeksekusi software tersebut
sedemikian
rupa
sehingga perilakunya menirukan atau menyerupai sistem nyata (realitas) tertentu untuk tujuan mempelajari perilaku (behaviour) sistem, pelatihan (training), atau permainan yang melibatkan sistem nyata (realitas). Arief S. Sadiman (2010: 76 77)
berpendapat
tentang
simulasi
yang
merupakan
suatu
model
hasil
penyederhanaan suatu realitas. Selain harus mencerminkan situasi yang sebenarnya, simulasi harus bersifat operasional, artinya simulasi menggambarkan proses yang sedang berlangsung. Simulasi dapat bersifat fisik (misalnya simulasi ruangan pengemudi
26
pesawat
terbang),
verbal
(misalnya
simulasi
untuk
pelajaran
membaca
permulaan), ataupun matematis (untuk mengajarkan sistem ekonomi). Anderson (1987: 181) berpendapat tentang pengaruh objek fisik atau benda nyata digunakan dalam pendidikan akan memberikan rangsangan yang amat penting bagi siswa dalam mempelajari tugas yang menyangkut keterampilan psikomotorik. 2.6.
Google A ndroid Android adalah sistem operasi untuk perangkat mobile seperti handphone,
smartphone dan tablet p c yang berbasis Linux. Android menyediakan platform terbuka bagi para pengembang untuk menciptakan aplikasi mereka sendiri untuk digunakan oleh bermacam-macam piranti bergerak.
Awalnya,
Google.Inc
membeli Android.Inc, pendatang baru yang membuat piranti lunak untuk ponsel. Kemudian untuk mengembangkan Android, dibentuklah Open Handset Alliance, konsorsium dari 34 perusahaan piranti keras, piranti lunak dan telekomunikasi, termasuk Google, HTC, Intel, Motorola, Qualcomm, T-Mobile dan Nvidia. Pada saat perilisan perdana Android, 5 November 2007 Android bersama Open Handset Alliance menyatakan mendukung pengembangan standar terbuka pada perangkat seluler. Di lain pihak, Google merilis kode-kode Android dibawah lisensi Apache, sebuah lisensi perangkat lunak dan standar terbuka perangkat seluler. Di dunia ini terdapat dua jenis distributor sistem operasi Android. Pertama, yang mendapat dukungan penuh dari Google atau Google M ail Services (GMS) dan kedua adalah yang benar-benar bebas distribusinya tanpa dukungan langsung dari Google, atau dikenal sebagai Open Handset Distribution (OHD).
27
w G am b ar 2.5 Logo Android 2.6.1. A rsitek tu r A ndroid Arsitektur sistem terdiri atas lima layer, pemisahan layer bertujuan untuk memberikan abstraksi sehingga memudahkan pengembangan aplikasi. Layerlayer tersebut adalah layer aplikasi, layer framework aplikasi, layer libraries, layer run-time, dan layer kernel. Gambar 2.6 memberikan gambaran umum komponen-komponen dalam arsitektur sistem operasi Android.
G am b ar 2.6 S tru k tu r Android
28
•
Applications Adalah semua aplikasi yang user miliki pada perangkat Android dimana aplikasi utama Android berjalan seperti email client, program SMS, kalender, peta,
browser,
dan
lain-lain
Semua
aplikasi
ditulis
dalam
bahasa
pemrograman java. •
A pplication Fram ew ork Adalah bagian dari struktur Android yang berisi framework API yang dapat digunakan oleh pengembang / programmer. Android tidak membedakan core applications dengan third-party applications dimana semuanya mempunyai akses ke API yang sama. Framework Android dirancang untuk memudahkan konsep re-use dari komponen.
•
L ibraries Android memiliki satu set library, merupakan inti yang menjalankan aplikasi yang bertujuan agar pengembang dapat langsung mengaksesnya. Beberapa library inti tersebut adalah:
•
-
Freetype ,berfungsi untuk rendering huruf bitmap dan vector.
-
SQLite ,engine untuk database relasional yang ringan.
-
LibWebCore ,engine untuk web browser.
-
SGL ,engine untuk grafik 2D.
A ndroid R untim e Terdapat 2 bagian penting dalam struktur ini yaitu Library Core dan Dalvik Virtual Machine. Library Core berisi core libraries yang menyediakan sebagian besar fungsionalitas yang serupa dengan API standar pada
29
pemrograman Java. Dalvik Virtual Machine merupakan register bases sementara dari JVM (Java Virtual Machine) atau stack based. DVM menggunakan kernel linux untuk menangani fungsionalitas tingkat rendah. Ini memungkinkan user untuk menulis aplikasi C/C+ sama hal nya seperti pada OS linux kebanyakan. •
L in u x Kernel Google menggunakan kernel linux versi 2.6 untuk membangun sistem Android,
yang mencakup
manajemen memori,
pengaturan keamanan,
manajemen proses dan beberapa driver hardware. Kernel berperan sebagai abstraksi atau penghubung antara hardware dan keseluruhan software. 2.6.2. F itu r Android Dalam perkembangannya ada beberapa fitur-fitur pokok yang ditawarkan dari sistem operasi Android yang di implementasikan pada perangkat yang digunakan. Adapun beberapa fitur yang terdapat pada Android, antara lain : •
Kerangka Aplikasi : Memungkinkan penggunaan dan penghapusan komponen yang tersedia.
•
Dalvik Virtual Mesin : Mesin virtual yang dioptimalkan untuk perangkat mobile.
•
Grafik : Grafik di 2D dan 3D berdasarkan pada pustaka OpenGL.
•
SQLite : Tempat penyimpanan data yang terinstal didalam operating sistem.
•
Dukungan Media : Android mendukung berbagai media audio, video dan format gambar.
30
•
Kamera,
GPS
(Global Positioning System), NFC
dan Accelerometer
(tergantung perangkat yang digunakan. •
M ulti
Touch
: Kemampuan
layaknya
handset
modern
yang
dapat
menggunakan dua jari atau lebih untuk berinteraksi dengan perangkat. •
Lingkungan Development : Android menyediakan lingkungan development yang lengkap dan kaya, termasuk perangkat emulator, tools untuk debugging, profil dan kinerja memori dan plugin untuk Eclipse IDE.
•
Market : Seperti kebanyakan telepon selular yang memiliki tempat penjualan aplikasi, Android juga memiliki tempat khusus bernama Android market yang kini berganti nama menjadi Google Play Store yang merupakan katalog aplikasi yang dapat di unduh dan di install pada perangkat Android melalui media internet.
2.6.3. Versi Sistem O perasi Android Dalam sistem operasi nya Android memiliki beberapa versi yang selalu diperbaharui yang berguna untuk memberikan interface dan layanan yang terbaik bagi pengguna nya. Berikut ini beberapa versi Android yang pernah dirilis : 1. Android versi 1.0 beta Merupakan Android beta, pertama kali dirilis tanggal 5 november 2007 dan versi SDK (Software Development Kit) dirilis 7 hari setelah sistem operasi nya yaitu pada tanggal 12 november 2007.
31
2. Android versi 1.0 Merupakan versi software Android komersial pertama yang dirilis pada tanggal 23 September 2008. Perangkat Android pertama yang menggunakan dan memperkenalkan Android 1.0 ialah ponsel HTC Dream (G1). 3. Android versi 1.1 Android versi 1.1 dirilis pada tanggal 9 februari 2009 dan pada awalnya versi ini hanya diperuntukan untuk T-Mobile G1. Versi ini diluncurkan guna untuk memecahkan masalah (bug), merubah API dan menambah sejumlah fitur dari versi sebelumnya. 4. Android versi 1.5 (cupcake)
G am b ar 2.7 Logo Android versi 1.5 (Cupcake) Dirilis pada tanggal 30 April 2009 dan pada versi ini diberikan sebutan lain yaitu cupcake. Dengan berbasis Linux Kernel 2.6.29 update ini membawa sejumlah fitur dan perubahan pada antarmuka (user interface) dipercantik dengan penambahan efek-efek animasi. Inovasi yang dikembangkan pada versi ini lebih ke segi multimedia seperti kemampuannya yang dapat merekam dan memutar video, dapat mengunggah foto ke Picasa dan video ke YouTube, dilengkapi dengan soft keypad dengan fitur autocomplete, mendukung
32
penggunaan Bluetooth A2DP, dan ada penambahan Widget baru mengikuti pola pada desktop. 5. Android versi 1.6 (donut)
G am b ar 2.8 Logo Android versi 1.6 (Donut) Pada 15 September 2009 google kembali merilis versi terbaru dari sistem operasi Android yaitu versi 1.6 yang diberi nama donut. Didalamnya terdapat sejumlah fitur terbaru seperti pengintegrasian antara kamera, kamera video dan galeri foto, penggunaan baterai indikator dan kontrol applet VPN, penambahan fitur seleksi multi untuk foto pada galeri foto, peningkatan fitur voice search dan pengembangan fitur voice dial, pengembangan fitur pencarian untuk bookmark kontak dan halaman web beserta kecepatan pencarian, peningkatan teknologi jaringan CDMG (EVDO), wifi, gesture dan mesin text-to-speech, mendukung layar dengan resolusi WVGA. 6. Android versi 2.0 / 2.1 (eclair)
G am b ar 2.9 Logo Android versi 2.0/2.1 (Eclair)
33
Versi yang dirilis pada tanggal 3 desember 2009 ini banyak mengalami pembaruan dari segi optimasi hardware dan juga segi perangkat lunaknya. Perubahan user interface dengan browser baru dan dukungan HTML 5, pengingkatan Google Maps 3.1.2, daftar kontak baru, dukungan tambahan cahaya / flash pada kamera 3,2 Mega Pixel, keyboard virtual, Bluetooth versi 2.1. 7. Android versi 2.2 (frozen yoghurt/ froyo)
G am b ar 2.10 Logo Android versi 2.2 (Froyo) Merupakan versi penyempurnaan dari Android versi 2.0 eclair. Dirilis pada tanggal 20 mei 2010 dan perbaikan pada 20 juni 2010. Pada versi ini kinerja hardware bekerja lebih cepat, dapat melakukan instalasi aplikasi pada memori eksternal, didukung dengan Adobe Flash 10.1, fitur Wifi portable dapat digunakan pada area hotspot, dan fungsi update otomatis pada Android Market sudah tersedia.
34
8. Android versi 2.3 (gingerbread)
i s k
G am b ar 2.11 Logo Android versi 2.3 (Gingerbread) Versi ini dirilis pada tanggal 6 desember 2010. Perubahan-perubahan umum yang didapat dari Android versi ini antara lain peningkatan kemampuan permainan (gaming), peningkatan kemampua copy-paste, layar user interface di desain ulang menjadi lebih atraktif dan menarik, mendukung tingkat resolusi yang lebih besar. Namun tidak semua perangkat selular bisa di upgrade ke versi ini, ada spesifikasi minimum agar dapat di upgrade ke versi gingerbread seperti kapasitas CPU 1 GHZ, RAM 512 MB dan diagonal layar minimal 3.5 inci. 9. Android versi 3.0 / 3.1 (honeycomb)
T G am b ar 2.12 Logo Android versi 3.0/3.1 (Honeycomb) Pada tanggal 22 februari 2011 versi Android 3.0 atau yang disebut honeycomb dirilis. Merupakan versi Android pertama yang diperuntukan untuk tablet. Mendukung layar yang lebih besar karena memang didesain khusus untuk
35
tablet. Honeycomb juga mendukung multi prosesor dan juga akselerasi perangkat keras (hardware) untuk grafis. Perangkat tablet komputer pertama yang menggunakan Android versi honeycomb ini adalah Motorola Xoom yang dirilis 24 februari 2011. 10. Android versi 4.0 (ice cream sandwich)
G am b ar 2.13 Logo Android versi 4.0 (Ice Cream Sandwich) Dirilis pada tanggal 19 oktober 2011, versi terbaru ini banyak menawarkan cukup banyak perbaikan dan perkembangan, versi ini membawa fitur honeycomb untuk dapat digunakan pada smartphone dan menambahkan fitur baru termasuk membuka kunci dengan pengenalan wajah, jaringan data pemantauan penggunaan dan pengaturan, kontak jejaring sosial yang dapat terhubung dengan aplikasi jejaring sosial lainnya beserta kontak secara terpadu, dapat mencari email secara offline. 11. Android versi 4.1 (jelly bean)
G am b ar 2.14 Logo Android versi 4.1 (Jelly Bean)
36
Pada Android versi terbaru ini membawa sejumlah keunggulan dan fitur baru diantaranya seperti meningkatkan input keyboard, desain baru pada fitur pencarian, user interface dengan desain yang lebih menarik menawarkan bentuk icon aplikasi yang lebih besar, pencarian melalui voice search yang lebih responsive, serta kemampuannya dalam mengetahui informasi cuaca, lalu lintas ataupun hasil pertandingan olahraga. 2.6.4. K elebihan dan K ekurangan Android Pada
dasarnya
setiap
sistem
operasi
memiliki
keunggulan
dan
kekurangannya masing-masing, begitupun pada sistem operasi Android. Berikut ini beberapa kelebihan / keunggulan yang terdapat pada sistem operasi Android, antara lain : •
Menawarkan kepada user untuk dapat menyesuaikan platform Google Android yang membuka kesempatan membuat aplikasi untuk pemain kecil dan baru yang tidak memiliki kekuatan financial untuk berinteraksi dengan operator nirkabel seperti AT&T dan Orange.
•
Android
merupakan
sistem
operasi terbuka
(open
source)
yang
memungkinkan pengembang untuk menciptakan aplikasi nya sendiri untuk Android. •
Dengan berbasis open source maka banyak pengembang yang
rajin
melakukan upgrade atas aplikasi yang mereka buat. •
User dapat memiliki
berbagai aplikasi mobile sebagai pilihan lain sejak
monopoli mobile phone yang dipecahkan oleh Google Android.
37
•
User dapat mengkostumasi perangkat Android menggunakan platform Google Android dari mulai tampilan layar hingga aplikasi, namun tergantung dari operator.
•
Fitur seperti rincian cuaca, membuka layar, RSS feed dan bahkan ikon pada layar pembukaan dapat disesuaikan.
•
Dikarenakan banyaknya ponsel yang menggunakan Android sehingga banyak juga perusahaan pengembang yang menawarkan produk aplikasi inovatif seperti layanan berdasarkan lokasi dan menyediakan informasi yang dibutuhkan.
•
Terkoneksi dengan seluruh layanan milik Google seperti youtube, picasa, google talk, google search, dll.
•
Dapat membuka lebih dari satu aplikasi / multitasking tanpa harus menutup salah satunya.
•
Terdapat widget di homescreen sehingga user dapat dengan mudah mengakses berbagai pengaturan dengan cepat dan mudah.
Selain terdapat kelebihan pasti ada kekurangan dalam setiap sistem operasi. Berikut ini beberapa kekurangan / kelemahan yang terdapat pada sistem operasi Android, antara lain : •
Karena banyak aplikasi yang bisa didapat secara mudah dan gratis maka terdapat pula konsekuensinya seperti banyaknya iklan terpampang pada aplikasi tersebut.
38
•
Diperlukannya koneksi internet yang simultan atau terus menerus guna memaksimalkan penggunaan aplikasi-aplikasi pada perangkat Android, karena perangkat berbasis sistem operasi seperti ini memerlukan koneksi internet.
•
Akses data tidak dibatasi dan tidak memiliki kompresi, sehingga user sendiri yang harus mengontrol ukuran file yang akan di download.
2.7.
Basis D ata (Database) Basis data ( database ) adalah kumpulan dari berbagai data yang saling
berhubungan satu dengan lainnya. Basis data tersimpan di perangkat keras, serta dimanipulasi dengan menggunakan perangkat lunak. Pendefinisian basis data meliputi spesifikasi dari tipe data, struktur, dan batasan dari data atau informasi yang akan disimpan. Database merupakan salah satu komponen yang penting dalam aplikasi, karena merupakan basis dalam menyediakan informasi pada para pengguna. 2.8.
Software / P eran g k at lunak Dalam membuat suatu aplikasi diperlukan adanya perangkat lunak /
software. Perangkat lunak sendiri dapat terdiri dari beberapa macam, misalnya perangkat lunak utama maupun perangkat lunak pendukung. Untuk membangun program aplikasi SCADA berbasis Android diperlukan beberapa software, berikut adalah beberapa software yang digunakan dalam membuat program aplikasi pada Android : 2.8.1. Eclipse Eclipse adalah sebuah software library berbasis
IDE (Integrated
Development Environment) untuk mengembangkan perangkat lunak dan dapat
39
dijalankan di semua platform. Eclipse pada saat ini merupakan salah satu IDE favorit dikarenakan gratis / freeware dan bersifat open source, yang berarti setiap orang boleh melihat kode pemrograman perangkat lunak ini dan juga karena kemampuannya untuk dapat dikembangkan oleh pengguna dengan komponen pendukung yang dinamakan plug-in. 2.8.2. Android SDK (Software Development Kit) Android SDK (Software Development Kit) merupakan alat atau tool yang digunakan untuk membuat aplikasi platform Android menggunakan bahasa pemrograman Java (Supardi, 2011:10). Android SDK mencakup proyek sampel source code, alat-alat untuk membangun sebuah aplikasi, sebuah emulator dan perpustakaan yang dibutuhkan untuk membangun aplikasi Android. Aplikasi yang ditulis menggunakan bahasa Java dan berjalan di DVM, mesin virtual yang dirancang khusus untuk penggunaan embedded yang berjalan diatas kernel Linux. Android
SDK
dapat
di
unduh
secara
gratis
di
situs
http://www.developer.Android.com . Instalasi Android SDK sebenarnya bukan seperti menginstal perangkat lunak kebanyakan karena sebenarnya hanya menyalin folder yang berisi tentang versi sistem operasi Android yang akan dibuatkan aplikasinya. 2.8.3. Jav a Java merupakan perangkat lunak produksi Sun Microsystem Inc. Untuk pemrograman beberapa tujuan (multi purpose), multi platform (dapat berjalan di beberapa sistem operasi), mudah dipelajari dan powerful (Supardi, 2011:1).
40
Bahasa pemrograman Java merupakan multiplatform, karena dapat berjalan di beberapa sistem operasi seperti sistem operasi Android, namun Android hanya menyediakan lingkungan runtime/sebagai interpreter. Dimana kode sumber yang telah kita compile dengan compiler Java akan dioptimasi dengan Delvik. Sebuah virtual machine yang memang dibuat dengan bahasa pemrograman Java yang terbentuk menjadi sebuah Class. Kemudian oleh dex tools (merupakan bagian dari DVM) mengubah Java Class yang telah di compile oleh Java compiler ke lingkungan native dengan format *.dex (format dalvik executable), yang teroptimasi untuk lingkungan perangkat keras dengan komputasi yang rendah.
Java G am b ar 2.15 Logo Jav a Berikut adalah beberapa keutamaan yang dimiliki Java, antara lain : 1. Compatibility dan stability Kode program Java dapat berjalan pada sistem operasi yang memiliki runtime environment dan telah banyak kesalahan yang dibenahi, serta keberadaan sebuah virtual machine juga mendukung stabilitas Java. 2. Monitoring dan management Java menyediakan fungsi untuk memonitor dan mengelola aplikasi yang biasanya mempunyai skala enterprise dengan menggunakan teknologi Java management extentension.
41
3. Enterprise desktop Java menyediakan integrasi dengan fasilitas desktop untuk mengatasi keterbatasan yang dimiliki oleh aplikasi berbasis browser. 4. XML Java juga mendukung penggunaan xml, diantaranya adalah digital signature dan streaming A P I untuk xml. 2.8.4. SQLite SQLite adalah sebuah embedded database yang sangat terkenal karena menggabungkan antarmuka SQL dengan memori yang sangat kecil dan kecepatan yang baik: Murphy (2010, p225). SQLite adalah sebuah open source database yang telah ada cukup lama, cukup stabil, dan sangat terkenal pada perangkat kecil, termasuk Android: Gargenta (2011, p119). Android menyediakan database relasional yang ringan untuk setiap aplikasi menggunakan SQLite: Meier (2010, p7). Aplikasi dapat mengambil keuntungan dari itu untuk mengatur relational database engine untuk menyimpan data secara aman dan efisien. Murphy (2010, p225) Untuk Android, SQLite dijadikan satu di dalam Android runtime, sehingga setiap aplikasi Android dapat membuat basis data SQLite. Karena SQLite menggunakan antarmuka SQL, cukup mudah untuk digunakan orang orang dengan pengalaman lain yang berbasis database. Terdapat
beberapa
alasan
mengapa
pengembangan aplikasi Android, yaitu:
SQLite
sangat
cocok
untuk
42
•
Database dengan konfigurasi nol, artinya tidak ada konfigurasi database untuk para developer. Ini membuatnya relatif mudah digunakan.
•
Tidak memiliki server, tidak ada proses database SQLite yang berjalan. Pada dasarnya satu set libraries menyediakan fungsionalitas database.
•
Single-file database, ini membuat keamanan database secara langsung.
•
Open source, hal ini membuat developer mudah dalam pengembangan aplikasi.
2.9.
Library / Classpath Disebut juga dengan istilah Classpath (Kelas dalam bentuk biner) Menurut
M. Huda dan B.Nugroho, dengan definisi pendekatan atas Classpath, memiliki pemisahan definisi atas Path yaitu "Pemetaan suatu direktori pada sistem operasi agar direktori tersebut bisa dikenal secara global pada sistem". Kemudian fungsi utama dari Classpath/Library adalah berkomunikasi pada Java bahwa sebuah class pada Java tertentu (bisa berbentuk .jar atau .class) disimpan pada direktori/alamat file tertentu. “Contoh dari classpath/library adalah sebuah file berformat jar yang bisa dipakai untuk driver database mysql dengan alamat filenya adalah c:\libku\mysqlconbin.jar. Maka, untuk mengenalkan pada Java Engine tentang driver tersebut adalah dengan melakukan pengaturan classpath/library (M. Huda-B. Nugroho, 2010)”. Dalam definisi yang penulis simpulkan, Library merupakan paket dari kumpulan program atau syntax yang telah ada pada compiler untuk memudahkan pemrogram membuat program dan tidak perlu mengakses langsung sistem
43
komputer untuk memprogram. Misalnya dapat kita pada bahasa pemrograman Java dibagian paling atas kode program ditambahkan sintaks import java.match. 2.10.
Jav a M odbus Library (Jam od) Java Modbus Library adalah sebuah library khusus yang didesain dengan
Object Oriented Programming yang sangat baik dalam dipahami, digunakan dan dikembangkan oleh pengembang yang menggunakan library ini sebagai hak atas open source (gratis) menyediakan dukungan untuk protocol Modbus Master dan Slave. Menurut sumber Thesis dari Ulrik L .J - Adaptive Energy Controller dari University IT Copenhagen Denmark (kutipan terjemahan, p41): “Bahwa dengan memanfaatkan popularitas Java yang semakin baik ada kesempatan baik untuk menemukan library tambahan dengan fungsionalitas yang diperlukan. Hal ini berlaku untuk Library Modbus TCP/ IP. Ada ada dua library “Open source” dengan dukungan Modbus TCP / IP yang ditulis di Bahasa pemrograman Java. Salah satunya adalah Modbus4j (Modbus4j) yang mudah untuk menggunakan implementasi protokol Modbus yang mendukung ASCII dan RTU komunikasi. Kemudian adalah Java fo r Modbus (Jamod) yang juga mendukung Modbus ASCII dan komunikasi RTU.” Kemudian proses dan konsep dasar yang dapat diadaptasi adalah: “Hal ini diimplementasikan dengan menggunakan perpustakaan Modbus TCP / IP bernama Jamod (Jamod). Ketika menulis atau membaca dari alamat Modbus, perlu untuk membuat sambungan ke unit Modbus Slave. Membuat koneksi dilakukan dengan menggunakan TCP MasterConnection, bila menggunakan
44
protokol TCP. Untuk koneksi tertentu adalah batas waktu yang ditetapkan. Timeout adalah periode dalam milidetik yang memungkinkan untuk menunggu respon ketika mengirimkan permintaan. Nomor port ke unit Modbus slave juga harus ditentukan. Untuk Modbus TCP / IP, port 502 adalah nomor port default yang digunakan. Ketika konfigurasi dilakukan, sambungan dapat dibentuk dengan memanggil metode koneksi seperti yang digambarkan. ” sumber Thesis dari Ulrik L .J - Adaptive Energy Controller-University IT Copenhagen Denmark (kutipan terjemahan, p:80) 2.11.
Open C SV Library OpenCSV Library adalah sebuah dukungan Library untuk file khusus
dalam menerima/membaca dan juga penyimpanan data hasil akuisis ke dalam format CSV. Definisi tentang CSV dari Wisconsin Valley Library Service (WVLS.org-terjemahan) adalah: “CSV Comma-Separated-Value, Format data yang sangat sederhana yang menyimpan informasi dalam sebuah file teks. CSV popular justru karena dapat dengan mudah dibaca oleh banyak aplikasi yang berbeda, termasuk spreadsheet, pengolah kata, eitor teks pemrograman dan web browser.” Dalam hal ini Open CSV Library dikususkan untuk Android. Library ini dapat diakses di http://sourceforge.net/projects/opencsv/ . 2.12.
M odbusPal Dalam pengenalan di dalam terjemahan dalam inggris (menu help ) pada
aplikasi tersebut, ModbusPal adalah simulator Modbus-Slave (penjelasan tentang slave sudah dikemukakan pada Modbus) . Tujuannya adalah untuk menawarkan
45
antarmuka yang mudah digunakan dengan kemampuan untuk mereproduksi environment Modbus secara realistis. Alat simulasi lainnya menawarkan built-in fungsi untuk "menghidupkan" data dari para Slave Modbus secara virtual. Tapi selalu ada situasi di mana fungsi yang telah ditetapkan tidak dapat mereproduksi realitas. Pendekatan ModbusPal adalah untuk membiarkan pengguna menulis skrip eksternal sehingga dapat memahami atas fungsi standar tidak bisa dilakukan pada aplikasi lain, namun pengguna bisa memasukkan perintah berbentuk skrip ke dalamnya, disamping itu, ModbusPal bersifat opensource dan gratis. Fitur kunci ModbusPal
kedua ModbusPal
adalah
"Learning"
mode.
Sebagai
menerima permintaan Modbus dari master, secara dinamis akan
menciptakan sumber daya yang hilang: slave, register dan koil dihasilkan secara on-the-fly.
Menurut
sumber
definisi
terjemahan
dari
Modbus.org
(http://www.Modbus.org/tech.php), ModbusPal adalah pengembangan proyek Java untuk membuat realistis dari Modbus slave secara simulator. Daftar nilai-nilai yang dihasilkan secara dinamis berkat fungsi matematika yang telah ditetapkan dan / atau skrip Python. Dalam pengembangan selanjutnya, ModbusPal meningkatkan mekanisme
dukungannya
terhadap
otomatisasi lebih.
standar Modbus
ModbusPal bergantung
dan
menawarkan
pada RxTx untuk
komunikasi serial, dan Jython untuk dukungan skrip. Tujuannya adalah untuk menawarkan antarmuka yang mudah digunakan dengan kemampuan untuk mereproduksi lingkungan Modbus kompleks dan realistis. Beberapa data tentang
46
fungsi dan keterbatasan yang dapat dilakukan oleh simulator ini dapat dilihat pada keterangan dibawah ini : Fungsi yang didukung Fungsi
D idukung
0x01 Read coils
ya
0x02 Read discrete inputs
tidak
0x03 Read holding registers
Ya
0x04 Read input registers
tidak
0x05 Write single coil
ya
0x06 Write single register
ya
0x07 Read exception status
tidak
0x08 Diagnostics
Tidak
0x0B Get comm. Event counter
Tidak
0x0C Get comm. Event log
tidak
0x0F Write multiple coils
ya
0x10 Write multiple registers
ya
0x11 Report slave ID
tidak
0x14 Read file record
Tidak
0x15 Write file record
Tidak
0x16 M ask write register
tidak
0x17 Read/write multiple registers
ya
0x18 Read FIFO queue
tidak
47
0x2B Encapsulated interface transport User-defined functions
tidak ya (Menggunakan Skrip)
(sumber : http://ModbusPal.sourceforge.net/ - ModbusPal help menu ) Inti dari ModbusPal ditulis dengan bahasa Java. TCP / IP didukung secara native, dan komunikasi serial didukung jika perpustakaan RxTx diinstal pada komputer. Dalam proses identifikasi dari ModbusPal, terkadang dijumpai tentang identifikasi khusus untuk pengalamatan dalam protokol Modbus. Menurut terjemahan eecs.umich.edu, Register Address merupakan bentuk Data yang dibangun menggunakan set dua digit heksadesimal, di kisaran 00 sampai FF heksadesimal. Ini dapat dibuat dari sepasang karakter ASCII (register), atau dari satu karakter RTU, sesuai dengan mode transmisi serial jaringan. Bidang data pesan yang dikirim dari master ke perangkat budak mengandungInformasi tambahan
dari slave harus
digunakan untuk mengambil tindakan yang
didefinisikan oleh kode fungsi (sumber: http://web.eecs.umich.edu/-M odbus! documents/PI_MBU S_300.pdf, p11). Dalam penetapan di setiap Register Address, terdapa pula istilah untuk menetapkan
bentuk
format
dari Register
yang
diinput.
Bentuk
bentuk
kombinasinya biasanya atas banyaknya byte 2 hingga 4 byte diikuti bentuk data seperti integer, flo a t dan discrete. Setelah alamat atas register ditetapkan dan format sudah jelas, dalam Modbus hendaknya dapat ditentukan bentuk dari setiap masukan setiap register dalam menentukan fungsi dari format yang ditetapkan, menurut sumber yang didapat dari m-system, sebuah perusahaan otomasi dari
48
Jepang, http://www.m-system.co.jp/mssenglish/service/emModbus.pdf-p7, telah membagi Address data yang digunakan dalam pesan request pada protokol Modbus ketika membaca atau memodifikasi data yang akan ditransmisikan. Empat jenis data yang digunakan: Coil, Input Status, Input Register dan Holding Register. A. Coil Coil digunakan untuk memaksa ON / OFF keadaan output diskrit (DO) ke lapangan, atau memodifikasi modus atau status Slave pada perangkat. Data Coil baik ON atau OFF, yang dapat menjadi membaca dan dimodifikasi. Alamat yang valid berada dalam kisaran 1-9.999. B. In p u t Status Status input digunakan untuk ON / OFF keadaan input diskrit (DI) dari lapangan, atau status perangkat slave. Status masukan entah ON atau OFF, yang dapat dibaca saja. Alamat yang valid berada di kisaran 10.001-19.999. C. In p u t Register Register masukan digunakan untuk nilai input analog (AI) dari lapangan, atau informasi dari perangkat slave. Input register 16-bit yang panjang, yang dapat dibaca saja. Address yang valid berada di kisaran 30.001 - 39999. Mengambang atau double floating. Data dapat ditangani ketika alamat berkali-kali diakses. D. H olding Register Holding Register digunakan untuk nilai output analog (AO) ke lapangan, atau untuk mengatur informasi perangkat slave. Holding register 16-bit yang panjang, yang dapat menjadi membaca dan dimodifikasi. Address yang valid
49
berada di kisaran 40.001 - 49999. Single Floating atau data Double Floating dapat ditangani penggunaan ketika Address yang berturut-turut diakses. Alat simulasi lainnya menawarkan built-in fungsi untuk "menghidupkan" data dari Slave Modbus secara virtual. Tapi selalu ada situasi di mana fungsi yang telah ditetapkan tidak dapat mereproduksi realitas. Pendekatan ModbusPal adalah untuk membiarkan pengguna menulis skrip eksternal: apakah fungsi standar tidak bisa melakukan, maka dengan rumus secara “Scripting” dapat melakukannya Fitur kunci kedua ModbusPal adalah "Learning" mode. Sebagaimana prosesnya, ModbusPal menerima permintaan MODBUS dari Master, secara dinamis akankah menciptakan sumber daya yang hilang: slave, register dan koil dihasilkan on-the-fly. ModbusPal gratis dan open source, dirilis di bawah lisensi GPL (General Public License). 2.13.
Agile Software Development Kata Agile berarti bersifat cepat, ringan, bebas bergerak dan waspada. Kata
Agile diambil dari kata Agility. Menurut Steven Goldman et al., Agility adalah dinamis, konten yang spesifik, perubahan yang agresif, dan berorientasi pada pembangunan. Konsep Agile Software Development dicetuskan oleh Kent Beck dan 16 rekannya. Mereka tergabung dalam Agile Alliance, lalu mereka menandatangani “Manifesto fo r Agile Software Development” yang isinya: 1. Interaksi dan personel lebih penting dari pada proses dan alat. 2. Software yang berfungsi lebih penting daripada dokumentasi yang lengkap. 3. Kolaborasi dengan klien lebih penting dari pada negosiasi kontrak. 4. Sikap tanggap terhadap perubahan lebih penting daripada mengikuti rencana.
50
Namun demikian, sama seperti model proses yang lain, Agile Software Development memiliki kelebihan dan tidak cocok untuk semua jenis proyek, produk, orang dan situasi. Agile Software Development memungkinkan proses model yang toleransi terhadap perubahan kebutuhan sehingga perubahan dapat cepat ditanggapi. Namun di sisi lain menyebabkan produktifitas menurun. Menurut Agile Alliance dalam Agile Manifesto, ada 12 prinsip bagi mereka yang ingin berhasil dalam penerapan Agile Software Development: 1. Kepuasan klien adalah prioritas utama dengan menghasilkan produk lebih awal dan terus menerus. 2. Menerima perubahan kebutuhan, sekalipun diakhir pengembangan. 3. Penyerahan hasil/software dalam hitungan waktu dua minggu sampai dua bulan. 4. Bagian bisnis
dan pembangun kerja sama tiap hari selama proyek
berlangsung. 5. Membangun proyek di lingkungan orang-orang yang bermotivasi tinggi yang bekerja dalam lingkungan yang mendukung dan yang dipercaya untuk dapat menyelesaikan proyek. 6. Komunikasi dengan berhadapan langsung adalah komunikasi yang efektif dan efisien. 7. Software yang berfungsi adalah ukuran utama dari kemajuan proyek. 8. Dukungan yang stabil dari sponsor, pengembang, dan pengguna diperlukan untuk menjaga perkembangan yang berkesinambungan.
51
9. Perhatian kepada kehebatan teknis dan desain yang bagus meningkatkan sifat agile. 10. Kesederhanaan adalah penting. 11. Arsitektur, kebutuhan dan desain yang bagus muncul dari tim yang mengatur dirinya sendiri. 12. Secara periodik tim evaluasi diri dan mencari cara untuk lebih efektif dan segera melakukannya. 2.14.
Extrem e Programming (XP) M odel Model proses ini diciptakan dan dikembangkan oleh Kent Beck. Extreme
Programming (berikutnya akan disingkat sebagai XP) adalah sebuah pendekatan atau model pengembangan perangkat lunak yang mencoba menyederhanakan berbagai tahapan dalam proses pengembangan tersebut sehingga menjadi lebih adaptif dan fleksibel. Walaupun menggunakan kataprogramming, XP tidak hanya terfokus pada coding tetapi meliputi seluruh area pengembangan perangkat lunak. s im p le d e s ig n
C R C cards
p r o to ty p e s
G am b ar 2.16 Skema Model XP
52
Menurut Kent Beck, XP adalah ringan, efisien, resiko rendah, mudah disesuaikan, dapat diprediksi, ilmiah dan mudah dikembangkan. Suatu model yang menekankan pada keterlibatan user secara langsung, pengujian dan pay-asyou-go design. Keterangan skema: 1. Planning, pengumpulan user stories
dari klien yang klien tetapkan
prioritasnya. Setiap story ditetapkan harga dan lama pembangunan, jika terlalu besar, story dapat dipecah menjadi beberapa story yang lebih kecil. Periksa dan pertimbangkan resiko. 2. Design
(berprinsip
sederhana),
memanfaatkan
kartu
CRC
(Class-
Responsibility-Collaborator) untuk identifikasi dan mengatur class-class di konsep Object Oriented. Jika menemui kesulitan, prototype dibangun (ini namanya spike solution). Lakukan refactoring, yaitu mengembangkan desain setelah pengkodean. 3. Coding, menyiapkan unit test sebelum pengkodean dipakai sebagai fokus pemrogram untuk membuat program. Pair programming dilakukan untuk real time program solving dan real time quality assurance. 4. Testing, merupakan proses bila terpenuhinya requirement dari pemrograman yang sudah diimplementasikan dengan coding dan sudah berjalan. Untuk konsep testing dapat dibahasa pada pembahasan selanjutnya. 2.15.
Konsep Blackbox Testing (Pengujian K otak H itam ) Blackbox testing yaitu pengujian terhadap perangkat lunak dari segi
fungsional tanpa menguji desain dan kode program. Pengujian dimaksudkan
53
untuk mengetahui apakah fungsi-fungsi, masukan dan keluaran dari perangkat lunak sesuai dengan spesifikasi yang dibutuhkan (Julian Supardi, diterjemahkan oleh Rosa, 2011:213 Blackbox testing). Pengujian kotam hitam dilakukan dengan membuat kasus uji yang bersifat mencoba semua fungsi dengan memakai perangkat lunak, apakah sesuai dengan spesifikasi yang dibutuhkan. Kasus uji yang dibuat untuk melakukan pengujian kotak hitam harus dibuat dengan kasus benar dan kasus salah. Misalkan untuk kasus proses login maka kasus uji yang dibuat adalah : 1. Jika user memasukkan nama pemakai (username) dan kata sandi (password) yang benar. 2. Jika user memasukkan nama pemakai (username) dan kata sandi (password) yang salah, misalnya nama pemakai benar tapi kata sandi salah atau sebaliknya, atau keduanya salah.
BAB III M ETO D O LO G I PEN ELITIA N
Pembahasan bab tiga meliputi mengumpulkan data-data informasi sebagai bahan yang mendukung kebenaran materi uraian pembahasan. Selain itu untuk menyelesaikan masalah yang ada dalam sebuah perancangan sistem, maka diperlukan beberapa tahap yang harus dilakukan. Dalam bab ini dijelaskan mengenai tempat dan waktu penelitian, bahan dan alat serta metodologi penelitian yang digunakan dalam pengembangan sistem. 3.1.
Tem pat dan W aktu Penelitian Dalam
Implementasi
IMPLEMENTASI
SCADA
PADA
ANDROID
DENGAN SIMULATOR MODBUSPAL STUDI KASUS: PERUSAHAAN X. dilaksanakan di Perusahaan X yang bergerak di bidang Otomasi Oil & Gas yang beralamat di Jl TB Simatupang no 41, Cilandak Jakarta Selatan dan di laksanakan mulai bulan Desember tahun 2014 hingga selesai. 3.2. M etode Pengum pulan D ata Untuk mendapatkan bahan-bahan sebagai dasar penelitian, perancangan dan implementasi, dilakukan riset terlebih dahulu seperti yang terdapat dibawah ini: 3.2.1. Studi P ustaka 1. Kent B, Martin.2007. F-Planning Extreme Programming 2. Julian Supardi, diterjemahkan oleh Rosa. (2011:213) Blackbox testing. (http://julian.unsri.ac.id/userfiles/file/blackboxtesting.pdf)
54
55
Pembahasan tentang setiap metodologi dapat dilihat di dalam Bab 2 dan Bab 4 pada dukungan terhadap studi pustaka yang menjadi dasar teori pendukung dan petunjuk, dalam pengembangan penulisan ini, juga mengambil arahan atas perbandingan dari Literatur sejenis yang diambil dari tiga skripsi dengan judul sebagai berikut: 1. Skripsi dengan judul: “Desain Sistem Supervisory Control A nd Data Acquisition (SCADA)” oleh Septian Ari Septian Ari Nugroho tahun 2013. Skrisi ini membuat desain sistem SCADA pada sistem parkir ramah lingkungan berbasis PLC yang dapat menampilkan secara otomatis data keadaan tempat parkir yang kosong, harga/tarif parkir, waktu parkir dan dapat mengontrol serta memonitoring keadaan parkir secara real-time dengan serial port RS-232 2. Skripsi dengan judul: “Perancangan SCADA pada Mini Warehouse dengan P L C ” oleh Bachtiar Salim Winarno 2009 - UI. Skripsi ini menggunakan miniature warehouse yang menggunakan Motion Detector sensor dan Smoke Detector Sensor menggunakan VB 6 sebagai Bahasa pemrograman dan Microsoft Access sebagai databasenya,
SCADA menggunakan Master
Terminal Unit pada Simulasi Miniatur Warehouse. 3.
Skripsi dengan judul: “Sistem Monitoring Miniatur Water Level Control dengan SCADA WonderWare dan PLC Glofa” oleh Winda Widjayanti & Linda
Sinaga
Politeknik
Negeri
Bandung
tahun
2011.
Skripsi
ini
menggunakan SCADA dari WonderWare dengan PLC Glofa tentang pengukuran atas Sistem Miniatur Water Level Control.
56
Dari ketiga literatur sejenis tersebut penulis membandingkannya sebagai berikut: Tabel 3.1. Perbandingan L iteratu r Sejenis Nama
Judul
Septian Ari Nugroho UNDIP
Bachtiar Salim Winarno - UI Perancangan SCADA
Winda Widjayanti & Linda Sinaga - PNB Sistem Monitoring
Desain Sistem
pada Mini Warehouse
Miniatur Water
Supervisory Control And
dengan PLC
Level Control
Data Acquisition
dengan SCADA
(SCADA)
WonderWare dan PLC Glofa
Monitoring sistematis
Kelebihan
- Menggunakan
- Virtualisasi atas
untuk lahan parkir,
protocol tersendiri
pemahaman area
dengan jangkauan areal
dari RS 232, dengan
yang dimonitoring
tertentu dalam
dua sensor khusus
langsung pada area
pemantauan areal parker
ditujukan untuk
miniatur Water
yang kosong, ticketing
mengukur Motion
Level yangjuga
system juga real time in-
Detector dan Smoke
disertakan gambar
out pada tiap kendaraan
Detection dalam
dari object di
sebuah simulasi
dalam PC
miniatur warehouse -Kerumitan berada pada
Kekurangan
- Hanya menyangkut
Penulisan Skripsi
implementasi perangkat
dua aspek dari
menitikberatkan
keras terhadap sistem
monitoring system
pada fungsi COIL
diterapkan juga
atas Asap dan
untuk deteksi nilai
dijalankan, butuh waktu
Gerakan
yang cukup lama dalam
SCADA tidak
ambang batas
implementasi, terutama
mobile
tertentu pada water
bila areal parkir luas
-Bergantung pada
level.
dan berlantai-lantai.
sensor yang
Kurangnya fitur
-
1/0 saja, untuk
57
-Perlu training yang
digunakan
d ari implementasi
cukup memakan waktu
-Protokol tersendiri
sistem atas buatan
bagi sistem
dan tidak dapat
sendiri karena
administrator
dikostumisasi
sudah terdapat
Bila secara real
aplikasi SCADA
time pada tempat
dan PLC nya
luas yang dimonitor
sendiri
tentu akan
(konfigurasi saja)
memakan banyak
Tidak mendukung
sensor untuk suatu
mobilitas dan
ruangan luas
koneksi dengan kabel
Setelah penulis pelajari terdapat sesuatu yang dapat dikembangkan dari ketiga literatur sejenis, yaitu: 1. Mengaplikasikan menu yang user friendly sehingga pengaplikasian atas user (pelatihan) dapat memakan waktu yang singkat karena mudah dipahami. 2. Menggunakan
konektivitas
secara wireless
sehingga
kepraktisan
saat
implementasi berjalan dengan baik. 3. Mobilitas dari perangkat SCADA dengan sistem operasi Android yang didukung untuk monitoring yang fleksibel dengan akurasi yang baik, didukung dengan kustomisasi atas port juga tingginya mobilitas. 4. Dapat digunakan untuk bermacam macam sistem monitoring seperti I/O atas coil, ataupun output berupa angka yang juga dapat dikembangkan dengan interaksi dengan sensor dan protokol khusus yang akan dihubungkan. 5. Dapat didukung oleh Simulator PLC berbasis JAVA yaitu Modbuspal,
58
sehingga pelatihan dan simulasi menjadi murah tanpa membeli sensor dan juga hardware module yang mahal, maka hal inilah yang akan penulis lakukan dalam skripsi ini. 3.2.2. W aw ancara Berdasarkan hasil wawancara penulis (user stories) terhadap calon pengguna aplikasi yaitu engineer di perusahaan X, (Lampiran 1), ternyata aplikasi yang akan di buat oleh peneliti cukup dibutuhkan, dengan syarat cukup simple, ringan dan mobile. Mengingat aplikasi dari literatur skripsi sejenis pada halaman sebelumnya masih
terdapat
beberapa
kekurangan
diantaranya
Mobilitas,
pengaturan port dan perhitungan juga kepraktisan atas user friendly dan dukungan sambungan nirkabel. 3.3.
M etode Pengem bangan Sistem Menggunakan Extreme Programming (XP) mencakup beberapa aturan dan
praktik yang terdiri atas planning, design, coding dan test. 1. Planning a. Meeting dengan Engineer b. Menentukan fitur apa saja yang dibutuhkan untuk aplikasi c. Membuat user story hasil meeting d. Membuat use case berdasarkan user story yang ada 2. Design a. Membuat CRC Card berdasarkan Use Case b. Perancangan design GUI
59
3. Coding Membangun aplikasi berdasarkan desain GUI dan CRC
card
menggunakan IDE eclipse Juno. 4. Testing Melakukan unit testing manual dengan menggunakan device Android yang sudah di install terlebih dahulu. 3.4. K erangka B erfikir Berikut
adalah
kerangka
berfikir
yang
digunakan
implementasi SCADA pada Android dengan Simulator ModbusPal :
untuk
60
G am b ar 3.1 Im plem entasi Scada pada Android dengan Sim ulator M odbuspal Studi Kasus P erusahaan X
BAB IV ANALISA DAN PEMBAHASAN
Pada sistem
bab ini, akan dibahas
yang akan penulis
secara
detail
dan terperinci
mengenai
implementasikan dengan menerapkan metode
pengembangan sistem yaitu metode agile software development dengan Extreme Programming (XP) sebagai proses modelnya. Metode ini menekankan suatu pendekatan interaktif dari proses pengembangan perangkat lunak yang dimaksud untuk mengurangi resiko pada aplikasi dan memaksimalkan hasil akhir dari sebuah aplikasi. Optimalisasi juga dilakukan pada bagian teknologi perangkat lunak pendukung dengan cara menggunakan library open source sehingga penulis bisa lebih fokus pada ide dan konsep bisnis proses. Fokus pada ide dan konsep bisnis proses memberikan ruang lebih banyak pada penulis untuk mencurahkan gagasangagasan baru dalam module dan teknik-teknik baru sehingga bisa terbebas dari paradigma reinvent the wheel. Adapun tahapan yang dilakukan mengacu pada gambar 3.1 yang akan dijelaskan sebagai berikut: 4.1
Planning Tahapan ini merupakan gabungan dari tahap analisis dan planning pada
metode pengembangan klasik. Tahap planning pada agile dibuat sesederhana mungkin agar tidak banyak dokumentasi namun programmer dapat mengerti apa yang harus dikerjakan. Pada tahapan planning dapat diketahui gambaran besar
61
62
dari aplikasi yang hendak dikembangkan dan teknologi-teknologi pendukung yang akan digunakan. 4.1.1
Visi Aplikasi DroidSCADA adalah sebuah system SCADA pada pada android yang akan
memberikan data accuisition. Antar muka system ini memiliki dua pendekatan teknologi yaitu teknologi berbasis mobile dan teknologi berbasis Modbus yang saling terintegrasi dan dapat terhubung dengan koneksi nirkabel dengan kemudahan set up pada protokol pendukung TCP IP yang disesuaikan untuk transfer data oleh Modbus. Antar muka yang berbasis mobile dapat memberikan informasi tag dan device dengan konfigurasi pendukung terkini. Disematkan juga fitur untuk backup up yang memberikan reporting yang lebih kaya informasi meliputi ID, tag ID, value, raw value record data secara akurat yang dapat disimpan dengan format CSV dan dapat dibuka dengan mudah dengan applikasi lain seperti microsoft excel. Di dalam kustomisasi dari setiap device pengenalan driver sangat penting dalam mengetahui device yang terhubung juga Slave ID yang relevant dalam setiap device yang terhubung yang juga dapat mengatur sinkronisasi atas data dan timeout. Dalam kostumisasi tag diperlukan setting untuk penentuan atas register address, juga register type dalam menentukan tipe data yang akan diterima oleh setiap tag. Adapun dukungan kompatibilitas dengan Modbuspal sebagai simulator atas PLC membuat aplikasi ini menjadi sederhana dalam pengaplikasian terutama fitur dasar pendukung dalam konfigurasi terhadap device dan tags.
63
4.1.2
F itu r Kunci Adapun fitur kunci dari aplikasi DroidSCADA yang akan dirancang ini
adalah: 1. Sistem yang mudah untuk diinstal dan dioperasikan. 2. Open source platform dengan penggunaan antarmuka yaitu mobile based android yang didukung dengan SCADA. 3. Low budget, menggunakan teknologi simulator untuk komunikasi data, juga wireless yang praktis. 4. Realtime information, akuisisi data langsung dikirim ke database dan selanjutnya bisa langsung ditampilkan di dalam android. 5. Interaktif, konfigurasi atas device & tag bisa langsung ditampilkan dan disimpan dengan jangka waktu yang dapat dikustomisasi 6. Support untuk further development dan improvisasi dengan peningkatan fitur dan juga performa. 4.1.3
T ujuan Aplikasi Tujuan pembuatan sistem ini diantaranya, yaitu:
1. Dapat mendukung kegiatan terutama untuk user pemula terhadap aplikasi SCADA 2. Menghemat biaya atas pengadaan perangkat keras dengan tersambungnya android dengan simulator open source Modbuspal 3. Menampilkan konfigurasi atas device dengan menentukan port type,protokol dan driver tipe yang mendukung juga sync period & tags yang terhubung
64
dengan kostumisasi yang terkait atas register address, register form at dengan penghitungan skala angka 4. Mengimplementasikan library open source khusus android pada SCADA secara nirkabel. 5. Sistem penyimpanan data (backup) dari hasil akuisisi data dalam format CSV atas nilai value tag. 4.1.4
Pengguna Aplikasi Pihak yang akan menggunakan sistem ini hanya user, yaitu pihak
pengguna applikasi android SCADA yang bernama DroidSCADA. User ini memiliki smartphone android yang sudah dipasang aplikasi DroidSCADA dan melakukan data akuisisi dan monitor di dalam perangkat mobile tersebut. 4.1.5
Inform asi Yang D ibutuhkan Informasi yang akan ditampilkan adalah informasi tentang akuisisi data
yang memuat perhitungan yang melibatkan protokol Modbus melalui wireless 4.1.6
K ebutuhan Aplikasi u n tu k A ndroid Sistem DroidSCADA membutuhkan beberapa teknologi pendukung baik
dari sisi perangkat keras maupun dari sisi perangkat lunak. Berikut adalah penjelasannya: 1. P eran g k at Keras a. Android ICS 4.1.1 b. RAM 512 c. Processor 1.2 Ghz
65
2. P eran g k at L unak a. Eclipse Juno V.23.0.3 fo r android developer b. Java 8.0 c. Android SD K 23.0.5 dengan A P I V.21 4.1.7 K ebutuhan atas Sim ulator Pendukung 1. P eran g k at Keras a. PC desktop dengan prosesor intel Pentium 4 b. RAM minimal 1gb ddr 2 c. 20GB hardisk d. Windows XP SP2 e. Wireless dongle f. Router wireless TP Link 2. P eran g k at L unak a. Modbuspal v1.6b 4.2
Design Dalam mendesain aplikasi ini penulis menggunakan pendekatan yaitu
membuat class design dan GUI design. Maksudnya adalah untuk mempermudah dan mempercepat penyelesaian proses desain. Penulis juga berusaha membuatnya sangat detail supaya pada saat proses pengkodean lebih mudah karena gambaran fungsi-fungsinya sudah jelas. 4.2.1. Use Case Dari analisis kebutuhan di atas dapat kita buat use cases-nya sebagai berikut:
G am b ar 4.1 Use Case u n tu k Aplikasi DroidSCADA 4.2.2. User Stories Dari penjabaran
analisis
pada uses case
di atas,
penulis
dapat
menyimpulkan melalui user stories sebagai berikut: 1. User dapat mengakses menu dengan tampilan sederhana dan informatif 2. User setidaknya menggunakan perangkat keras android yang dipakai dengan minimum requirement : -
Android ICS 4.1.1
-
RAM 512
-
Processor 1.2 Ghz
3. User dapat mengakses aplikasi android dengan aplication requirement dalam fungsi yang dijalankan : - Menggunakan port standar 502 (default Modbus) yang dapat dirubah - Tag memiliki unit dengan tipe data string agar dapat dikostumisasi - Mendukung Modbus dengan protokol TCP/IP
67
- Mencakup jangkauan register address dari 1-65535 - Memiliki opsi penyimpanan data (sampling period) - Memiliki fitur untuk menyimpan data ke format CSV 4. User dapat menggunakan module yang tidak terlalu membebani RAM pada peralatan 5.
User
dapat
menggunakan
android
untuk
monitoring
SCADA
menggunakan protokol Modbus 6.
User dapat menggunakan applikasi Android yang dapat tersambung dengan simulator secara nirkabel untuk menggantikan perangkat keras bermodul seperti Wago
7. User dapat menyimpan data record hasil perhitungan ke dalam sebuah file 8. User dimudahkan untuk tersambung dengan koneksi nirkabel 9. User dimudahkan dengan tampilan pengukuran sederhana yang dikostumisasi terhadap satuan pengukuran 10. User dapat menentukan range untuk Register Address standar dengan jangkauan antara 0-65535 (2 byte). 11. User dapat menyimpan data dengan format database tertentu yang memuat record yang relevan User dapat memilih untuk konfigurasi device 4.2.3. Design CRC Card Proses desain pada tahap ini yaitu menggunakan Class Responsibilities, and Collaboration (CRC) card. Penggunaan CRC card hanya dipakai jika
68
pengembangan software berbasis objek. Setiap CRC card akan menjelaskan tiap objek yang dibutuhkan. Mengacu pada user stories pada tahap planning maka dibuat 18 Class diantaranya: 1. Class Dashboard Tabel 4.1 CRC Card Dashboard Dashboard Responsibilities
Collaborators
Start/Stop Core Display Tag List Receive TagValue Broadcast and update list in realtime Open Device List Add/Edit/Delete Tag Export TagValue Data to CSV Open DeviceForm fo r Update or add new
Core Tag CSV LocalDB SwipeDetector TagListAdapter TagListObject
2. Class Device List Tabel 4.2 CRC Card Device List Tag Form Responsibilities
Collaborators
Display Device List Delete Device Open DeviceForm fo r Update or add new
Device LocalDB SwipeDetector DeviceListAdapter DeviceListObject
3. Class Device Form Tabel 4.3 CRC Card Device Form DeviceForm
Responsibilities
Collaborators
Display Device Info
Device
69
Save Device Change A dd New Device
LocalDB
4. Class Tag Form Tabel 4.4 CRC Card Tag Form TagForm
Responsibilities
Collaborators
Display Tag Info Save Tag Change A dd New Tag
Tag Device LocalDB
5. Class DeviceListAdapter Tabel 4.5 CRC Device List Adapter DeviceListAdapter
Responsibilities
Collaborators
Display Device Info in List Update Display when Needed
DeviceListObject
6. Class TagListAdapter Tabel 4.6 CRC Card Tag List Adapter TagListAdapter
Responsibilities
Collaborators
Display Tag Info in List Update Display when Needed
TagListObject
7. Class Core Tabel 4.7 CRC Card Core Core
Responsibilities
Collaborators
Supply Worker with Device
Worker
70
Info Holds Worker Stay Active in background
LocalDB Device Tag
8. Class Worker Tabel 4.8 CRC Card Worker Worker Responsibilities
Collaborators
Continuously grab TagValue Data from Modbus Device Continuously Save acquisited Tagvalue data to database in bulk Broadcast taken value
Device Tag LocalDB Converter Modbus
9. Class Converter Tabel 4.9 CRC Card Converter Converter
Responsibilities
Collaborators
Convert Raw TagValue based on Tag Specification
Scale Tag
10. Class CSV Tabel 4.10 CRC Card CSV CSV
Responsibilities
Collaborators
Export Existing stored Tagvalue data
LocalDB
11. Class LocalDB Tabel 4.11 CRC Card LocalDB LocalDB
Responsibilities
Collaborators
Manage Device Database
Device
71
Manage Tag Database Manage TagValue Database
Tag TagValue
12. Class Device Tabel 4.12 CRC Card Device Device
Responsibilities
Collaborators
Hold Device Data
13. Class Tag Tabel 4.13 CRC Card Tag Tag
Responsibilities
Collaborators
Hold Tag Data
14. Class Tag Value Tabel 4.14 CRC Card Tag Value TagValue
Responsibilities
Collaborators
Hold TagValue Data
15. Class Scale Tabel 4.15 CRC Card Scale Scale
Responsibilities Hold Scale Data
Collaborators
72
16. Class DeviceListObject Tabel 4.16 CRC CardDeviceListObject DeviceListObject
Responsibilities
Collaborators
Hold Device Visual Data Hold Device
Device
17. Class TagListObject Tabel 4.17 CRC Card TagListObject TagListObject Responsibilities
Collaborators
Hold Tag Visual Data Hold Tag
Tag
18. Class Modbus Tabel 4.18 CRC Card Modbus Modbus
4.2.4.
Responsibilities
Collaborators
Check i f Device working Connect to Device Disconnect from Device Read Tag from device
Tag Device
Desain GUI Desain GUI dirancang untuk memberikan luas maksimal pada setiap
tampilannya dan akan di pasang sebuah button di bagian bawah sebagai penanda itu adalah fungsi paling utama dari setiap tampilan. Fungsi - fungsi tambahan akan di sematkan dengan memanfaatkan framework android option menu di bagian kanan atas.
73
G am b ar 4.2 Desain Dashboard Tampilan dashboard dibuat seluas mungkin untuk setiap tag, mengingat inti utama aplikasi ini adalah monitor nilai tag secara realtime. Sebuah button untuk memulai atau menghentikan core service disematkan dibawah sebagai perintah utama dan navigasi di sematkan di kanan atas sebagai popup.
G am b ar 4.3 Desain Device List
74
Tampilan device list tidak berbeda jauh dengan tampilan dashboard, dibuat seluas mungkin untuk setiap device, Sebuah button untuk menambah device baru disematkan di bawah.
G am b ar 4.4 Desain Tag Form Tampilan Tag Form dibuat dengan linear layout karena tata letak hanya turun kebawah untuk setiap control. Sebuah button untuk menyimpan data tag disematkan dibawah.
; ■' Device Form
IH
Device Name IP A ddress Port Slave ID Suspend Driver Protocol Location Retry Times
Sync Period Time Out
Save Tag
G am b ar 4.5 Desain Device Form
75
Tampilan Device Form juga dibuat dengan linear layout karena tata letak hanya turun kebawah untuk setiap control. Sebuah button untuk menyimpan data device disematkan dibawah.
4.2.5. Desain D atabase Pada tahap ini, keseluruhan perancangan database aplikasi dilakukan.
G am b ar 4.6 R ancangan D atabase
76
Penulis membuat tiga tabel yaitu device, tag dan tag value table untuk penyimpanan datanya. Adapun rancangan dati ketiga table tersebut adalah: 1. Device
Nama Field
Tabel 4.19 Struktur Database Device Panjang Keterangan Tipe
ID
Text
-
ID Device
IPAddress
Text
-
Alamat IP Device
Port
Integer
-
Port Device
Name
Text
-
Nama Device
SlaveID
Integer
-
Alamat Slave Modbus
Location
Text
Lokasi Device
DeviceDriver
Integer
Jenis Driver yang digunakan
DeviceProtocol
Integer
Jenis Protokol yang digunakan
TimeOut
Integer
Batas waktu koneksi
RetryTimes
Integer
Batas waktu mengulang koneksi sampai dinyatakan gagal Frekuensi pengambilan data
SyncPeriod
Pada tabel Device berfungsi untuk menyimpan informasi mengenai device yang ingin dihubungkan dan dibaca datanya. Device menyimpan status suspend yang digunakan untuk menentukan apakah device akan aktif dihubungkan dan diambil data atau tidak. Ketika terjadi gagal koneksi ke device, status suspend akan aktif.
77
2. Tag ________________ Tabel 4.20 Struktur Database Tag Panjang Keterangan Nama Field Tipe ID
text
-
ID Tag Value
DeviceID
text
-
DeviceID dari Tag
Name
Text
-
Nama Tag
RegisterAddress
integer
-
Alamat Register pada Modbus
RegisterFormat
integer
-
Format Data yang di ambil
Registertype
Integer
-
Jenis Register
EnableScaling
Integer
-
MinValue
Float
-
MaxValue
Float
-
DecimalNumber
Integer
-
Status apakah nilai data di convert atau tidak Nilai minimum data setelah di convert Nilai maksimum setelah di convert Jumlah 0 dibelakang koma
EnableStorage
Integer
-
Unit
Text
-
Status penanda nilai disimpan atau tidak di database Satuan nilai
Pada tabel Tag berfungsi untuk menyimpan informasi mengenai tag yang terdapat pada suatu device. Tag juga menentukan jenis dan tipe register yang akan diambil datanya, kapan diambil dan apakah diperlukan konversi atau tidak. 3. TagValue ________________ Tabel 4.21 Struktur Database TagValue Panjang Keterangan Nama Field Tipe ID
Text
-
ID Tag Value
TagID
Text
-
TagID dari TagValue
Value
Float
-
Nilai yang sudah di convert
TagValue
Integer
-
Nilai mentah dari Modbus
78
RecordDate
Integer
-
waktu pengambilan nilai
Pada tabel TagValue berfungsi untuk menyimpan nilai yang sudah diperoleh dari suatu device. Nilai yang disimpan adalah nilai setelah konversi dan nilai mentah dari device. 4.3
Coding Pada tahap ini penulisan kode dilakukan. Tahap ini merupakan tahapan
yang paling utama dari model proses extreme programming. Tahap ini dapat berulang kali dilakukan sesuai dengan kebutuhan fungsional yang dapat berubah sewaktu-waktu. Penulisan kode menggunakan Eclipse for android developer yang didukung dengan Java SDK. Untuk mempermudah penulis dalam pengaplikasian Java Android yang menerapkan protokol Modbus untuk SCADA, maka digunakan Library Jamod (Java for Modbus ) untuk interoperability di dalam Bahasa pemrograman Android terhadap dukungan Protokol Modbus sehingga kompatibel dengan Simulator yang diguanakan yaitu Modbuspal yang dibangun dengan Bahasa pemrograman Java. Sedangkan untuk ekspor data menjadi file csv akan menggunakan library opencsv. 4.3.1. Pem bahasan Fungsi Berdasarkan use case yang sudah dibuat, ada beberapa fitur penting yang akan di buat: 1. Start / Stop Core Service: Fitur ini berfungsi untuk menjalankan atau menghentikan core service untuk akuisisi data. Fungsi ini akan mengecek terlebih dahulu apakah servis sudah berjalan atau belum, apabila belum, maka
79
dia akan menjalankan service dengan catatan sudah ada device yang di simpan didalam database. Namun apabila servis sudah berjalan, maka akan berlaku hal sebaliknya, dia akan menghentikan servis. Berikut Snippet code yang digunakan : bo o le a n S erviceS tatus=fa ls e ; p u b lic v o id ToggleC ore(V iew view ){ Button btn=(Button) findView ById(R .id. db_btnToggleCore); if(isM yS erviceR unning(C ore.c la s s )) {S erviceS tatus=fa ls e ; btn.setText("S tart Service"); C oreS ervice.stopService(); unbindS ervice(serviceC onnection); LocalBroadcastM anager.get/nstance(th is ).unregisterR eceiver(receiver); stopService(serviceIntent); } e ls e { if( D evices.size()>0){ startCoreService(); ServiceS tatus=tr u e ; bindService(service Inte nt, serviceC onnection, Context. B /N D _ A U T O _ C R E A T E ); LocalBroadcastM anager.get/nstance(th is ).registerR eceiver((receiver), new Intent Fi lter(Core. C O R E _ R E S U L T) ) ; btn.setText("Stop S ervice"); } e ls e { alert("No D evice", "No device available, please insert atleast 1 device first!"); } } }
2. Export Data: Fungsi ini akan melakukan eksport data dari database table TagValue menjadi file CSV dengan yang akan di simpan di memory Device. Format
penamaan
file
yang
dibuat
adalah
sebagai
berikut
“TAGExportdd_MM_yyyy_hhmmss_SSS.CSV”, sebagai contoh apabila kita eksport pada tanggal 10 Maret 2014 jam 10.00 pagi, maka file yang dibuat adalah TAGExport10_03_2014_100000_000.CSV, Hal ini akan mencegah penumpukan file dengan nama yang sama. Sebelum Export dilakukan, sistem akan mengecek apakah ada 1 atau lebih data TagValue yang bisa di eksport. Apabila data masih kosong, maka akan memunculkan notifikasi bahwa tidak ada data yang di ekspor. Apabila ada data yang diekspor, maka sistem dengan memanfatkan library opencsv
80
akan melakukan loop / iterasi dan memasukkan setiap data ke dalam object opencsv. Objek ini secara otomatis dengan 1 panggilan fungsi akan mengubah data yang sudah diinput menjadi file csv di memory storage device. Berikut adalah snippet Code yang digunakan : p u b lic in t ExportTagValue() { in t counter=0; File exportD ir = ne w File(Environm ent. getExternalStorageDirectory(), ""); if (!exportD ir.exists()) { exportD ir.m kdirs(); } String currentDate= new Sim pleD ateForm at("dd _M M _yyyy_hhm m ss_S S S ").form at(C alendar.get/nstance().getT im e( )); File file = n e w File(exportDir, filenam e+currentD ate+csvForm at); try { file.createNew File(); C S VW riter csvW rite = new C S VW riter(n e w FileW riter(file)); //orm lite core method Cursor c=LocalD B.get/nstance(_context).getR aw TagV alues(); // this is the Colum n of the table and sam e for Header of C S V file String header[] ={"ID ","TagID ", "V alue ", "R aw V alue", "R ecordD ate"}; S im pleD ateForm at sdf=n e w S im pleD ateForm at("dd-M M -yyyy hh:m m :ss.SS S "); if (c != n u ll ) { if (c.m oveToFirst()) { csvW rite.w riteN ext(header); do { String datee=sdf.form at(c.getLong(c.getC olum nIndex("R ecordD ate"))); String row[] ={ c.getS tring(c.getC olum nIndex("ID")), c.getS tring(c.getC olum nIndex("TagID ")), c.getS tring(c.getC olum nIndex("Value")), c.getS tring(c.getC olum nIndex(" RawValue") ) , datee}; csvW rite.w riteN ext(row ); counter++; }w h ile (c.m oveToNext()); csvW rite.close(); } } re tu rn counter; } c a tc h (IO Exception e){ Log.e("M ainA ctivity", e.getM essage(), e); re tu rn counter; } }
3. Core Service: Sebuah service yang merupakan fitur utama dari DroidSCADA, service inilah yang akan melakukan akuisisi data dengan skema sebagai berikut: Service pada saat inisiasi akan membuat kumpulan worker berdasarkan device yang sidah disimpan dalam database, idealnya adalah 1 worker untuk 1 device. Tiap worker akan melakukan koneksi ke perangkat
81
hardware. Worker akan bekerja dalam interval yang sudah ditentukan di device, setiap percobaan koneksi ke perangkat PLC akan diulang sejumlah dengan parameter retryTimes
dan akan menunggu selama beberapa detik
sebelum timeout. Waktu tunggu sebelum timeout ini mengikuti parameter timeout pada device. if (!_ d e v ic e .S uspend) { fo r (Tag tg : _ta g s) { try { in t[] data = _ D riv e r.Read(tg); if (!_ D rive r.isD riverW ork()) { if (_ D riv e r.readE rror().length O > 0) { Log.d("W A LK E R ","Tag " + tg .ID +" " +_ d e vice .S laveID +" get Value error on " + _ D riv e r.readError()); _ D riv e r.clearError(); } else { status = R oundtrip_S tatus_D isconnected; Log.d("W A LK E R ","device " + _d e vice .ID + " D isconnected!"); sendR esult("device D isconnected!",tg .DeviceID); Stop(); } } String rVal = ""; Date date =C alendar.gef/nsfance().getTim e(); if (data.length > 1) { rVal=String. valueOf( ModbusUtil.makeWord(data[0],data[1 ]));
} else { rVal = S tring .value0 f(d ata[0 ]); } String val = C onverter.gef^alue(tg, rVal); tag s.put(tg.ID , val); lo n g d1=date.getTim e(); lo n g d 2 = LastT agS ave.get(tg.I D).g etT im e(); lo n g diff= d1-d2; if(diff >tg.S torageS am pling) { SaveToM em ory(tg, val, rVal, date); } if (showlog) { Log. d ("W A LK E R ","Tag " + tg.Name + " (" + tg .ID + ") R A ddress:" + tg .RegisterAddress + " get Value :" + S tring.value0f(data[0])); } } c a tc h (Exception p) { Log.d("W A LK E R ","Tag " + tg .ID + " get V alue failed" + p.getM essage()); }
}
82
4. Save Tag : Fitur ini Untuk Menyimpan Data Tag, berikut code snippet untuk memasukkan Data Tag: p u b lic v o id S ave(View view) { Spinner spinner = (Spinner) findView B yId(R .id. tf_spDeviceNam e); Device device=(D evice)spinner.getS electedItem (); EditText txtTagN am e = (EditText) findView B yId(R .id. tf_txtTagName); EditText txtTagR egisterA ddress = (EditText) findView ById(R .id. tf_txtTagRegisterAddress); EditText txtT agR egisterF orm at = (EditText) findView ById(R .id. tf_txtTagRegisterFormat); EditText txtTagR egisterType = (EditText) findView ById(R .id. tf_txtTagRegisterType); Switch sw itchTagE nableS caling=(Sw itch) findView B yId(R .id. tf_lblTagEnableScaling); EditText txtM inValue = (EditText) findView ById(R .id. tf_txtTagMinValue); EditText txtM axV alue = (EditText) findView B yId(R .id. tf_txtTagMaxValue); Switch sw itchTagE nableS torage=(Sw itch) findView B yId(R .id. tf_lblTagEnableStorage); EditText txtS torageSam pling = (EditText) findView ById(R .id. tf_txtTagStorageSampling); EditText txtD ecim alN um ber = (EditText) findView ById(R .id. tf_txtTagDecimaNumber); EditText txtTagU nit = (EditText) findView ById(R .id. tf_txtTagUnit); b o o le a n status=fa ls e ; if(option.equalsIgnoreC ase( Constants. /N T E N T _ O P T /O N _ N E W )) { tag= ne w Tag(); ta g .ID=U U ID . random UU/D (); ta g .A sset="ta g "; ta g .Type="ta g "; ta g .G roup="ta g"; ta g .Location="ta g"; ta g .S torageP eriod=1000; } ta g .DeviceI D=device. ID ; ta g .Name=txtTagN am e.getText().toString(); ta g .Detai l=txtT agNam e.getText().toS tring(); ta g .R egisterForm at=(C onstants.R egisterForm at. valueO f(txtTagR egisterForm at.getText().toS tring())).g etCode(); ta g .RegisterType=(C onstants.R egisterType. valueO f(txtTagR egisterType.getText().toS tring())).getC od e(); ta g .R egisterAddress=Integer.parse/nt(txtTagR egisterA ddress.getText().toString()); ta g .E nableScaling=sw itchT agE nableS caling.isC hecked(); ta g .D ecim alNum ber=Integer. parse/nt( txtD ecim alN um ber.getText().toS tring()); ta g .E nableStorage=sw itchTagE nableS torage.isC hecked(); ta g .S torageS am pling=Integer.parse/nt( txtS torageSam pling.getText().toS tring()); ta g .Unit=txtTagU nit.getText().toString(); ta g .M axValue= D ouble.parseD ouble(txtM axV alue.getText().toS tring());//65535; ta g .M inV alue=D ouble.parseD ouble(txtM inV alue.getText().toS tring());//0; //tags.add(tag); if(option.equalsIgnoreC ase( Constants. /N T E N T _ O PT /O N _ E D /T )) { status=LocalD B .get/nstance(th is ).updateTag(tag);} else { status=LocalD B .get/nstance(th is ).insertT ag(tag);} if(status) { th is .finish(); } else { new A lertD ialog.B uilder(TagForm .th is ).setTitle("Tag").setM essage("G agal masukin tag") .setN eutralButton("tu tup", n u ll).show(); }
}
83
5. Save Device : Fitur ini untuk menyimpan data device, berikut code snippet untuk memasukkan data device : p u b lic v o id S ave(View view) { EditText txtD eviceN am e = (EditText) findView ById(R .id. df_txtDeviceName); EditText txtD eviceIP = (EditText) findView B yId(R .id. df_txtDevice/P); EditText txtD evicePort = (EditText) findView B yId(R .id. df_txtDevicePort); EditText txtD eviceR etryTim es = (EditText) findView B yId(R .id. df_txtDeviceRetryTimes); EditText txtD eviceSyncPeriod = (EditText) findView B yId(R .id. df_txtDeviceSyncPeriod); EditText txtD eviceTim eO ut = (EditText) findView B yId(R .id. df_txtDeviceTimeOut); fin a l EditText txtD eviceSlaveID = (EditText) findView B yId(R .id. df_txtDeviceSlave/D); fin a l EditText txtD eviceD river = (EditText) findView B yId(R .id. df_txtDeviceDriver); fin a l EditText txtD eviceProtocol = (EditText) findView B yId(R .id. df_txtDeviceProtoco); Switch sw itchD eviceSuspend = (Switch) findView B yId(R .id. df_switchSuspend); b o o le a n status=fa ls e ; if(option.equalsIgnoreC ase( Constants. /N T E N T _ O P T /O N _ N E W )) { device= n e w Device(); device.I D=UUI D. random UU/DQ ; device.Detail=" " ; device.Location="Indonesia"; device.ProjectID = 1 ; } device.Name=txtD eviceN am e.getText().toS tring(); device.IP A ddress=txtD eviceIP.getText().toS tring(); device.Port=Integer.parse/nt( txtD evicePort.getText().toS tring()); device.Tim eO ut= Integer.parse/nt( txtD eviceTim eO ut.getText().toS tring()); device.RetryTim es=Integer. parse/nt( txtD eviceR etryTim es.getText().toS tring()); device.S yncP eriod=Integer. parse/nt( txtD eviceSyncPeriod.getText().toS tring()); device.D eviceD river=(C onstants.D eviceD river.valueO f(txtD eviceD river.getText().toS t ring())).getCode(); device.D eviceProtocol=(C onstants.D eviceP rotocol.valueO f(txtD eviceP rotocol.getText().toString())).ge tCode(); device.S laveID = Integer.parse/nt( txtD eviceSlaveID .getText().toString()); device.S uspend=sw itchD eviceS uspend.isC hecked(); if(option.equalsIgnoreC ase( Constants. /N T E N T _ O P T /O N _ N E W )) status=
{ LocalD B.get/nstance(th is ).insertD evice(device);
} e ls e { status=LocalD B .get/nstance(th is ).updateD evice(device); } if(status) { t h is .finish(); } else { N ew A lertD ialog.B uilder(D eviceForm .th is ).setTitle("D evice").setM essage("G agal masukin device") .setN eutralButton("tu tup", n u ll).show(); } }
6. Delete Tag : Fitur ini untuk menghapus data tag, berikut code snippet untuk menghapus tag : p u b lic b o o le a n deleteTag(U U ID ID) { S Q LiteD atabase db=t h is .getW ritableDatabase(); re tu rn db.delete(T A B L E _ N A M E _ T A G , "ID='" + ID .toString()+..., n u ll) > 0;
}
84
7. Delete Device : Fitur ini Untuk Menghapus Data Device, berikut code snippet untuk menghapus device : p u b lic b o o le a n deleteD evice(U U ID ID) { S Q LiteD atabase db=t h is .getW ritableDatabase(); re tu rn db.delete(T A B L E _ N A M E _ D E V /C E , "ID='" + ID .toString()+..., n u ll) > 0; }
4.4
Testing Pada tahap ini dilakukan pengujian masing-masing modul (unit) program
apakah sesuai dengan tugasnya. Pengetesan ini dilakukan dengan menggunakan metode black box testing yaitu pengetesan menggunakan metoda pengujian logika program yaitu contoh perkasus atau masalah yang diajukan. Pada tahap akhir akan diujikan pada kondisi sebenarnya yaitu dengan implementation testing. 4.4.1
Pengujian dengan Unit Testing Karena penulis menggunakan extreme programming sebagai model
prosesnya maka pengujian hanya dilakukan dengan metode unit testing. Tabel 4.22 merupakan hasil pengujian dengan unit testing.
Tabel 4.22 Hasil Pengujian Dengan Unit Testing
No. 1.
2.
3.
M odul Dashboard
Device form
Device list
P rasy arat Telah diinstal dan menjadi tampilan awal Tap pada add device Tap pada menu device
Hasil yang d iharapkan Menu utama dapat ditampilkan Menu edit form dapat diakses dan disimpan Melihat list atas device yang tersimpan di dalam DroidSCADA
Hasil Pengujian OK
OK
OK
85
4.
Tag Form
Tap pada menu add tag
Dapat mengakses dan mengatur konfirgurasi atas tag baru yang dibuat hingga proses menyimpan tag baru selesai dan ditampilkan dalam tag list
OK
Dari hasil pengujian di atas hampir semua modul dapat berjalan sesuai dengan yang diharapkan. 4.4.2. Pengujian dengan Implementation Testing Pada tahap ini aplikasi akan diuji pada keadaan sebenarnya yaitu kondisi pada saat sistem sudah berjalan. Perangkat yang digunakan adalah Acer A1-811 dengan sistem operasi Android 4.1.2 (Jelly Bean). Alat-alat yang digunakan pada pengujian ini diantaranya: 1. Satu buah PC atau laptop yang memiliki koneksi secara nirkabel dan sudah terpasang Modbuspal dengan detail atas konfigurasi: -
OS Windows 7
-
Ram 8GB
-
Hardisk 640GB
2. Router nirkabel yang sudah terhubung dengan PC dan android, tanpa set up atas firewall. 3. Sebuah perangkat keras Android yang terhubung dengan router secara nirkabel dan telah diketahui IP Address dari PC dan Android tersebut. Tabel 4.23 Hasil Pengujian Im plem entasi No.
M odul
P rasy arat
Hasil yang
Hasil
86
d iharapkan
Pengujian
1.
Dashboard
Telah diinstal dan menjadi tampilan awal
Menu utama dapat ditampilkan
Pada screenshot tentang Menu Dashboard
2.
Device form
Tap pada add device
Menu edit form dapat diakses dan disimpan
Pada screenshot tentang add device
3.
Device list
Tap pada menu device
Melihat list atas device yang tersimpan di dalam DroidSCADA
Pada Screenshot pada list device
4.
Tag Form
Tap pada menu add tag
Dapat mengakses dan mengatur konfirgurasi atas tag baru yang dibuat hingga proses menyimpan tag baru selesai dan ditampilkan dalam tag list
Pada screenshot di dalam menu add tags
Dari hasil pengujian di atas hampir semua modul dapat berjalan sesuai dengan yang diharapkan.
4.4.2.I. Bukti Pengujian Im plem entasi Bukti pengujian implementasi yaitu meliputi : 1.
Pem asangan Aplikasi
B B
custom ized-ca pa bi 1ity .x m 1 Feb2.2015 10:05:31 PM
DroidSCADA.apk Feb2.20159:58:11 PM a
146B
default-capability.xm l Feb2.2015 T0:05:31 PM
Qv Find "53
E L Filter
1 Sort -ft-
14.1 KB
’
535.0KB
'
::: View
11 Paste
87
G am b ar 4.7 File Instalasi DroidSCADA.apk Kumpulan coding yang sudah terpasang akan dicompile dan menghasilkan package android dengan format .apk yang sudah diunduh akan dimasukkan ke dalam drive penyimpanan pada Android. Saat mengakses dapat menekan .apk dan memulai untuk menginstall applikasi DroidSCADA tersebut.
G am b ar 4.8 M enu instalasi DroidSCADA.apk
G am b ar 4.9 Proses instalasi DroidSCADA.apk 2.
Aplikasi DroidSCADA sudah terpasang di dalam Android
88
Di bawah ini merupakan tampilan gambar DroidSCADA yang sudah terpasang di dalam android
G am b ar 4.10 Icon DroidSCADA terpasang di perangkatA ndroid 3.
Akses tam pilan aw al pada A plikasi DroidSCADA Di bawah ini merupakan tampilan gambar awal pada aplikasi
DroidSCADA
89
D GB Jk =
1" D -.lICSl 22:11 ADDTAU
DroidSCADA
j
S tart Service
G am b ar 4.11 File Instalasi DroidSCADA.apk Pada gambar diatas adalah tampilan awal dashboard pada DroidSCADA yang dapat memberikan pilihan untuk menambahkan Start Service ataupun Add Tab pada menu tersebut sebagai bentuk dalam kostumisasi yang dapat dilakukan selanjutnya. 4.
Tam pilan saat tid ak te rd a p at Device yang sudah dim asukkan Di bawah ini merupakan tampilan gambar saat tidak terdapat device yang
sudah dimasukkan.
N o D evice No device available, please in s e rt a tle a s t 1 device firs t! Close
G am b ar 4.12 G am bar Notifikasi atas belum adanya Device yang sudah dim asukkan Pada gambar tersebut telah memberikan informasi pada user terkait dengan tidak ada device satu pun sehingga akan menampilkan notifikasi yang diperlukan.
90
5.
Tam pilan u n tu k A d d Tag M enu Gambar di bawah memberikan informasi tentang tampilan menu add tag
yang dapat memberikan opsi opsi berupa export data, device list dan juga setting untuk pengaturan tertentu vO,
22:16 ADD TAG
Device list Export Data
1
Settings
G am b ar 4.13 M enu pada Dashboard DroidSCADA
G am b ar 4.14 Notifikasi apabila tid ak ad a d ata pad a aplikasi Pada gambar di atas menerangkan tentang menu export yang dimana kondisi yang didapat adalah saat tidak ada input data yang telah tersimpan sementara di dalam DroidSCADA untuk selanjutnya diproses dalam backup data. Notifikasi yang ada pada gambar di atas, digunakan untuk memperjelas tampilan muka proses dan sebagai informasi detil tambahan pada aplikasi.
91
a a. J& <
v a T
Device List
add Device
G am b ar 4.15 Tam pilan Device L ist Dari gambar di atas menerangkan tentang awal dari Device List menu yang akan menampilkan kumpulan dari beberapa device device yang sudah di masukkan dan sudah disimpan ke dalam DroidSCADA yang selanjutnya dapat diatur atau dihubungkan dengan tag tertentu sehingga menampilkan hasil Akuisisi data yang dapat disimpan.
G am b ar 4.16 Tam pilan input Sync Period pada Device Editor
92
Pada gambar diatas adalah pengaturan untuk Input Sync Period pada tag yang akan di kustomisasi di dalam DroidSCADA. Input Sync Period memastikan pada device untuk menarik data dengan kendala atas waktu dalam satuan Miliseconds (seperseribu detik). L.I Saving screenshot...
<
D e v ic e Ed ito r
IP A d d ress 19 2 .1 6 8 .1 .1 1 4
Port 502
Slave ID 1 OFF
Suspend Driver M odbus
P rotocol TC P IP
Lo ca tio n Local
Retry T im es 10
S ync Period lOOO
T im e Out 20 0 0 S a v e D e v ice
-tS-
a1
G am b ar 4.17 Detail Device Editor Gambar diatas menampilan beberapa tampilan atas konfigurasi dari Device Editor yang mendukung detil dari proses dalam mendapatkan data dari device yang relevan untuk ditampilkan di dalam DroidSCADA.
93
B
Sa ving screenshot...
<
D e v ic e E d ito r D evice N a m e IP A d d r e s s 192. 168. 1.1 14
Port 502
S la v e tD
1
Suspend Driver
off
Modbus
P ro to co l TCPIP
L o c a tio n Local
Retry T im e s 10
S y n c Period 1000 S a v e D e v ic e
tD
[31
G am bar 4.18 G am bar Detail konfigurasi untuk Suspend terh ad ap Device Dari gambar diatas, setiap user memiliki kendali atas device seperti menghentikan proses sementara atau mematikan perhitungan atas akuisisi data. Dengan pilihan Suspend o ff / Suspend On dalam waktu yang diharapkan user menjadi lebih interaktif
G am bar 4.19 Tam pilan pada device list di yang sudah tersim pan. Dari gambar diatas adalah kelanjutan setelah user berhasil untuk menginput device editor dari aplikasi sehingga tersimpan dan dapat ditampilan sebagai device list. Berikut gambar untuk awal Tag Editor
94
P IB ^ <
'Q 'f '
O . . l l ' I S 22:19
T a g E d ito r
Register Address 2 Register Form at Two_Bytes_Unsi gned_l nt eger Register Type Output_Holdings Decim al Number 2
Enable Scaling
OFF
Scale M in Value 0 Scale M ax Value 100
Enable Storage
OFF
Storage Sam pling 5000 Unit Save Tag
T>
O
O
G am b ar 4.20 G am bar Tag Editor Gambar diatas untuk mewakili input yang sangat perlu dari tag editor meliputi Nama device hingga unit kemudian memasuki data dengan tap pada Save Tag terhadap aplikasi DroidSCADA.
G am b ar 4.21 G am b ar tam pilan u n tu k m engatur Register Format Gambar diatas meliputi pengaturan pada Tag Editor dimana form at pada input register dapat ditentukan terhadap form at data yang akan ditampilkan dengan runutan format yang telah disediakan di dalam aplikasi DroidSCADA.
95
Input Register Type lnput_R egisters OutputJHoldings OutpLrt_Coils C ancel
OK
G am b ar 4.22 G am b ar Tentang P engaturan tipe Register Gambar di atas menerangkan atas tipe dari input dari register type dari tag editor terutama untuk menentukan tipe angka yang digenerate oleh protokol Modbus melalui aplikasi Modbuspal. Tentunya dengan sinkronisasi yang sama akan memberikan dampak tampilan data yang diatur secara akurat. B IS & r
DroidSCADA
'Q T
0 , .il( ^ ]2 2 :2 1 ADD TAG
Tag sim RPM
G am b ar 4.23 G am bar Tag yang sudah a tu r dan tersim pan Dari gambar diatas merupakan hasil dari setiap
tag yang telah
dikostumisasi dengan baik dan tersimpan di dalam aplikasi DroidSCADA. Untuk mengetahui apakah tag berjalan / tidak berjalan dapat melihat pada tampilan warna di sebelah nama tag. Untuk mengaktifkan atau menghentikan sementara tag, setiap user dapat melakukan tap pada start device atau tap pada stop device untuk menjalankan kembali.
96
4.5.
Evaluasi Sistem Sistem akan berjalan sempurna dan lancar jika beberapa hal berikut ini di
perhatikan: 1. Konektivitas sambungan nirkabel berjalan lancar sehingga transfer data antara Modbuspal dan android data berjalan lancar di dalam DroidSCADA. 2. Untuk melihat pergerakan lokasi realtime secara halus maka diperlukan koneksi internet yang cukup yaitu minimal 128 Kbps. 3. Validator input seperti batas register address dan batas input skala lainnya layaknnya ditentukan untuk menghidari error value karena digit yang berlebihan terutama di dalam database. 4.6.
Contoh Training dan Simulasi
4.6.1. Contoh kasus
Melakukan proses pengawasan atas tekanan angin pada sebuah landasan helikoputa yang khusus ditempatkan di sebuah lahan seluas 10mx10m. Di areal tersebut telah terpasang sebuah router outdoor wireless untuk mendukung transfer data yang terkoneksi dengan beberapa sensor pengukur angin (digantikan dengan simulator Modbuspal pada sebuah PC).
Tugas:
1. Gunakan konfigurasi sebagai berikut : Pastikan simulator sudah terhubung dengan router Cek sambungan pada Android terhubung dengan router IP router adalah 192.168.3.3
97
Modbuspal Port secara default port 502, dengan Slave ID = 1 Range Register Address 12201-12204 Register form at dengan two bytes unsigned integer Register Type dengan output holding register Satuan dengan Knot 2. Lakukan pengamatan angin melalui perangkat Android dengan aplikasi DROIDSCADA selama 1 jam 3. Simpan hasil pengukuran selama satu jam dalam form at CSV 4. Hitung kecepatan rata-rata dari seluruh hasil pengukuran 5. Perhatikan penjelasan dari instruktur dan bilang ada hal yang kurang jelas jangan ragu untuk bertanya. 6. Pemahaman anda dapat berpengaruh dari penjelasan Instruktur, dan penilaian atas ujian praktik dan teori setelah ujian praktek selesai (sumber : perusahaan X) 4.6.2. Pem bahasan Kasus Pertama, Pelatih akan mengaktifkan aplikasi modbuspal di sebuah PC dengan alamat IP 192.168.3.3. Konfigurasi yang digunakan dapat dilihat pada gambar 4.24.
98
G am b ar 4.24 K onfigurasi m odbuspal Peserta Training akan segera mengaktifkan aplikasi DroidSCADA dan langsung melakukan langkah sebagai berikut : 1. Membuka menu Device List. 2. Menambah Device dengan IP 192.168.3.3 dan port default (502) sesuai dengan konfigurasi device pada gambar 4.25. 3. Kembali ke tampilan Device List akan menampilkan 1 buah device (Gambar 4.26).
99
V,. 0 f - D ..ll ® S 12:03 <
Device Editor
■
Device Name Outdoor Router
IP Address 192.168.3.3
Port 502
Slave ID
l Suspend
o ff
Driver Modbus
Protocol TCPIP
Location Local
Retry Tim es 10
Sync Period(m s) 1000 Save Device
tD
-£>
[3
G am b ar 4.25 K onfigurasi Device
G am b ar 4.26 Device List
100
4. Kembali ke Tampilan Dashboard dan menambah 4 Tag, konfigurasi 4 tag tersebut sama, yang berbeda hanya Register address yaitu 12201 sampai 12004, adapun konfigurasi lengkapnya dapat dilihat pada gambar 4.27.
y
'0 , 0 1
<
D ,.il (M l 12:05 1 j
Tag Editor Device Outdoor Router
Register Address 12240 Register Format Two_Bytes_Unsigned_lnteger Register Type Output_Holdings Decimal Number 2 ON
Enable S ca lin g Scale Min Value 0.0 Scale Max Value 70.0
ON
Enable S to ra g e Storage Sampling 5000 Unit Save Tag
□>
G am b ar 4.27 K onfigurasi Tag
5. Kembali Ke tampilan dashboard akan terdapat 4 buah Tag (gambar 2.28). Saat ini yang perlu dilakukan hanya menekan tombol Start Service untuk menjalankan service, tampilan akan berubah seperti pada gambar 4.29 dimana nilai dari sensor sudah terlihat pada dashboard.
101
B
©
E
'0 , 0 ®
y
DroidSCADA
□ .. i l ®
12:09
ADD TAG
wind sensor north Knot
O
Wind Sensor West Knot
Wind Sensor South Knot
Wind Sensor East Knot
Start Service
G am bar 4.28 Dashboard setelah m enam bah 4 sensor B
E
©
'0 , 0 ®
y
DroidSCADA
D ..il®
12:10
ADD TAG
wind sensor north 42.93 Knot
W
[3
Wind Sensor West 42.93 Knot
w
Wind Sensor South 42.93 Knot
Wind Sensor East 42.93 Knot
Stop Service
G am b ar 4.29 Dashboard setelah service dijalankan
6. Peserta akan membiarkan perangkat android mereka bekerja melakukan akuisisi data selama 1 jam dan segera menekan tombol Export Data pada menu dashboard dan aplikasi akan memberikan notifikasi berapa jumlah tag value yang di ekspor seperti pada gambar 4.30.
102
Gambar 4.30 Notifikasi ekspor data
7. Peserta sudah selesai dalam penggunaan aplikasi dan menekan tombol Stop Service pada dashboard. 8. Peserta mengambil file csv dari perangkat android masing - masing dan membuka file tersebut di PC dengan aplikasi MS. Excel seperti pada gambar 4.31. a t>- <*- | IQME
TAGE*port19_02_2015_084757_015.csv - Excel (Product Activation Failed]
INSERT
PAGE LAYOUT
□
Foxit Reader PDF
VIEW
St
B]g Conditional Formatting
Sot ^
Pa!tt
x.
e
i
u -
Eh -
£> • A
•
X
Sign in ^
TEAM
Format as Tables
Delete ’ ■
[Tl ’ (Hi
Cell Styles-
FormatT
•£_ •
ID
TagID
Value
1155eel9-5f35-432c-alde-7ad646fl6eb8
3
aef723b8-2bce-4448-8557-dceaa5042cc6
4
e9ac&c48-f81b-4f46-bb05-c497cb3000a2
5 5al067c9-d9el-4e45-b79a-f698fl4df522
|
1
11 al40e751-47e6-422e-baaf-855be2bf7cb6
c
Editing
RecordDate
19.69
18432 19-02-2015 07:31:20.473
1155eel9-5f35-432c-alde-7ad646fl6eb8
57.97
54272 19-02-2015 07:31:26.472
1155 e e 19- 5 f35-432c- a 1 d e - 7a d 646f16e bS
58.24
54528 19-02-2015 07:31:31.480
1155 e e 19- 5 f 35-432c- a 1 d e - 7a d646f 16e b8
41.56
38912 19-02-2015 07:31:36.489
6
c0137b62-974a-487a-ale2-829b9f7de&02
1155eel9-5f35-432c-alde-7ad646fl6eb8
25.98
24320 19-02-2015 07:31:41.491
7
b d 61391a- a df6-4bc2-9f 78- d c411Se 1971f
daf32ae8-fee9-4073-8b0e-e6fb2d2729bl
19.69
18432 19-02-2015 07:31:20.464
8 4425a9al-9601-4583-a071-80f5aaa25e57
daf32ae8-fee9-4073-8b0e-e6fb2d2729bl
2.46
2304 19-02-2015 07:31:25.467
9
daf32ae8-fee9-4073-8b0e-e6fb2d2729bl
9.57
8960 19-02-2015 07:31:30.474
10 9959e9b6-4283-4325-8fea-b8a93dca0a4a
daf32ae8-fee9-4073-8b0e-e6fb2d2729bl
25.16
23552 19-02-2015 07:31:35.479
11 blee9132-aa23-4434-a66e-479eb6176bdc
daf32ae8-fee9-4073-8b0e-e6fb2d2729bl
2.19
2048 19-02-2015 07:31:40.484
'2 8fcb471a-adda-4914-bb2d-el553942150e
3e7a0615-bd6c-4beb-a250-5d91098488aa
19.69
18432 19-02-2015 07:31:20.483
13 5all6620-30bd-4030-S500-f9ed3b92aac5
3e 7a0615- b d 6c-4b e b- a250-5d91098488a a
57.97
54272 19-02-2015 07:31:26.483
91480545-3676-4el3-a6dl-4e8d72761820
TAGExportl 9_02_2015_G84757_015 READY
©
i
RT
1
a
1a
E
--------- 1--------- +
M 100%
G am b ar 4.31 File hasil ekspor dibuka pada aplikasi MS Excel
103
9. Karena yang diminta adalah rata - rata keseluruhan. Maka peserta hanya perlu menjumlahkan semua nilai dan membagi sesuai jumlah data yang ada. Dalam hal ini : - I x x = —— n
Dimana x=rata-rata x i =jumlah semua nilai pada setiap record n=jumlah record data 10. Hasil Hitung berdasarkan file CSV, jika kita blok semua column value maka Excel akan otomatis segera memberikan nilai rata - rata pada bagian bawah (gambar 4.32) yaitu 34,80 Knot.
B *3- <*Icfib ri I
-1 1 U
-
L id -
-' A'
= ■ = =
A'
& - A -
Font
? s
general
-
S fe ife l tE IE V 'T (a
Alignm ent
,r
$ - % *
I f 3Insert T
Form at as Table T
Delete T
Cell Styles T
.00 ->.0
(1
Ej§] C onditional Form atting T
Q
[gfl F o rm a tT
Styles
□ Sign in
Foxit Reader PDF
= E
m -
TAG Export! 9_Q2_2015_034757_015,csv - Excel (Product A ctivation Failed) PAGE LAYOUT
x ^
S - i* - * [7] t itft t ^ -
Cells
Editing
✓ f* A
C
B
E
TagID
2 a140e751-47e 6-422e- baaf-855be 2bf 7cb6
1155eel9-5f35-432c-alde-7ad646fl6eb8
19.69
3 aef723b 8- 2b ce-4448-S55 7- dcea a5042cc6
1155 e e l9 -5 f35-43 2c-a lde-7ad 646f16e b8
57.97
54272 19-02-2015 07:31:26.472
4 e9a c8c48-f81b-4f46-bb05- c497cb3000a 2
1155eel9-5f35-432c-alde-7ad646fl6eb8
58.24
54528 19-02-2015 07:31:31.480
5al067c9-d9el-4e45-b79a-f698fl4df522
1155eel9-5f35-432c-alde-7ad646fl6eb8
41.56
38912 19-02-2015 07:31:36.489
C0137b62-974a-487a-ale2-829b9f7de602
1155eel9-5f35-432c-alde-7ad646fl6eb8
24320 19-02-2015 07:31:41.491
bd61391a-adf6-4bc2-9f78-dc4118el971f
d af 32a e8-f e s 9-4073 - 8b0e-e6f b2d 2729bl
25.98 19.69
4425a9al-9601-45S3-a071-80f5aaa25e67
daf 32a e8-f e e9-4073 -Sb0e-e6fb 2d 2729b 1
2.46
2304 19-02-2015 07:31:25.467
91480545- 3676-4el3-a6dl-4e8d72761820
d af 32a e 8-f e e 9-4073- 8b0e-e6f b2d 2729bl
9959e9b6-4283-4325-8fea-b8a93dca0a4a
daf 32a e8-f e e9-4073 -8b0e-e6f b 2d2729b 1
blee9132-aa23-4434-a66e-479eb6176bdc
d af 32a eS-f e e 9-4073 - 8b0e-e6f b2d 2729bl
Sfcb471a-adda-4914-bb2d-el553942150e
3e7a0615-bd6c-4beb-a250-5d91098488aa
5all6620-30bd-4030-8500-f9ed3b92aac5
3e7a0615-bd6c-4beb-a250-5d91098488aa
9.57 25.16 2.19 19.69 57.97
5 6 7 8 9 10 11 12 13
TAGExportl 9_02_2015_0S4757_015
Value
D
1 ID
COUNT: 3491
s
18432 19-02-2015 07:31:20.473
18432 19-02-2015 07:31:20.464 8960 19-02-2015 07:31:30.474 23552 19-02-2015 07:31:35.479 2048 19-02-2015 07:31:40.484 18432 19-02-2015 07:31:20.483 54272 19-02-2015 07:31:26.483
a:
©
AVERAGE 34,80130335
RawValue RecordDate
SUM: 121491.35
G am b ar 4.32 Hasil ra ta - ra ta d ari program MS Excel
E
BAB V PENUTUP
Bab ini berisi kesimpulan terhadap masalah yang ada dan pemecahan masalahnya serta saran kepada pihak yang ingin mengembangkan aplikasi ini 5.1
K esim pulan Berdasarkan Implementasi Scada pada Android dengan Simulator
Modbuspal, maka dapat disimpulkan beberapa hal sebagai berikut: 1. Aplikasi SCADA ini menggunakan Mobile System Android OS yang mendukung monitoring dan akuisisi data yang juga ditujukan untuk pelatihan (training) terhadap User. 2. Sebagai solusi dari perangkat modul yang mahal seperti beberapa alat yang sudah ada di pasaran, penulis telah menggunakan simulator modbuspal sebagai pengganti dalam aplikasi yang ditujukan untuk training ini. Modbuspal
sebagai
simulator dinilai
memiliki nilai
kepraktisan
dan
kemudahan dalam menentukan input, sehingga memudahkan pelatihan. 3. Penentuan protokol dengan koneksi nirkabel
(wireless) menggunakan
TCP/IP yang didukung dengan batas register address dengan dukungan penyimpanan backup data dengan Sampling storage dalam format CSV. 4. User Story yang telah dikumpulkan melalui proses wawancara terhadap internal
dari
perusahan
(termasuk
engineer
lapangan)
menghasilkan
beberapa point penting dalam pembuatan aplikasi android ini (10 point
104
105
penting hasil user story pada bab 3-4), termasuk penggunaan library Jamod yang dinilai tepat sebagai jawaban atas identifikasi masalah. 5. Penulis telah melakukan total implementasi Extreme Programming dari tahap awal identifikasi hingga pengerjaan atas aplikasi telah selesai termasuk fasilitas untuk perubahan konfigurasi juga fungsi untuk backup data yang disimpan dalam format csv. 5.2
S aran Berdasarkan kesimpulan-kesimpulan yang telah dikemukakan, dapat
diajukan beberapa saran untuk pengembangan lebih lanjut antara lain: 1. Diharapkan aplikasi yang
terdapat pada smartphone Android ini dapat
dikembangkan untuk akuisisi data dengan lebih banyak tipe module yang juga tidak sebatas dengan TCP namun juga berkolaborasi dengan protokol yang lebih luas (semisal bluetooth) 2. Simulator pendukung pelatihan yang berinteraksi
dengan smartphone
Android, dapat dikembangkan pula dengan fungsi yang lebih baik, juga memungkinkan untuk lebih reliable dengan module dan juga sensor tertentu. 3. Kustomisasi atas penempatan waktu dapat dikembangkan lagi dengan menambahkan service yang relevan seperti sampling storage. Tentunya backup yang dilakukan juga diharapkan dalam pengembangan selanjutnya dapat melakukan import data terhadap konfigurasi tentang device dan tags di dalam aplikasi. 4. Untuk pengembangan selanjutnya, penulis berpendapat tentang pengukuran atas
batasan
dari
library
Jamod
yang
digunakan
sehingga
dapat
106
memungkinkan untuk melakukan pengembangan dari Jamod menjadi library yang lebih baik terutama bagi sesama pengguna open source. 5. Untuk sisi keamanan dalam akuisisi data, dalam tahap pengembangan selanjutnya dinilai sangat perlu, terutama menghindari risiko atas kerusakan yang ditimbulkan oleh pihak yang tidak bertanggung jawab. Pengembangan dengan memulai pada uji stabilitas dapat dilakukan selayaknya dengan uji ketahanan jangka panjang (long durability test).
DAFTAR PUSTAKA
A.Tiyono. 2007. Jurnal: Sistem Telekontrol Scada D engan Fungsi D asar M odbus M enggunakan M ikrokontroler AT89S51 D an K om unikasi SerialR S485. Semarang: UNDIP A G Subarsono.2005. A nalisis Kebijakan Publik. Yogyakarta: Pustaka Pelajar A nderson (1987) - Bam bang W arsita. (2008). Aplikasinya. Jakarta: Rineka Cipta.
Teknologi Pembelajaran, Landasan dan
A rief S. Sadiman. (2010). M ed iapendidikan: pengertian, pengem bangan, dan pem anfaatannya. Jakarta: rajawali pers Depdiknas. (2005). K am us Besar Bahasa Indonesia. Jakarta: Balai Pustaka http://elib.unikom .ac.id/files/disk1/459/jbptunikom pp-gdl-ahm adzaena-22924-2-unikom a-i.pdf http://m odbuspal. sourceforge.net/ - M odbuspal help menu http: //j amod. sourceforge.net/ http: // sourceforge.net/proj ects/openc sv/ http://w w w .w vls.org/sites/default/files/2013% 20G lossary% 20of% 20Term s.pdf http://ww w .m -system .co.jp/m ssenglish/service/em m odbus.pdf - p7 Julian
Supardi,
diterjem ahkan
oleh
Rosa.
(2011:213)
Blackbox
testing.
(http://julian.unsri.ac.id/userfiles/file/blackboxtesting.pdf) K ent B. 2006. “M anifesto fo r Agile Software D evelo p m en t’ K ent B, M artin.2007. F -Planning Extrem e Program m ing K. Murphy. 2009. M y SQL A dm in istra to r’s Bible, Indiana, USA: W iley Publishing M odbus.org. 2002. M odbus M essaging On Tcp/Ip Im plem entation Guide. M A, USA M. Gargenta. 2011. L earning Android. 1005 Gravenstein H ighw ay N orth, Sebastopol, CA 95472 : O ’Reilly M edia, Inc., M iftakhul H - Bunafit.N. 2010. Trik Rahasia pem grogram an database dengan Java. Jakarta: Elex M edia K om putindo
107
108
Nazruddin, Safaat. 2011. M em bangun Aplikasi M obile Berbasis Android. Bandung: Inform atika Bandung. R. Meier. 2012. P rofessional A n d ro id 4 Application Development, Indiana, USA : John W iley & Sons, Inc Supardi, Yuniar. 2011. Sem ua B isa M enjadi Program m er Android. Jakarta: Elex M edia K om putindo Thesis-Ulrik. L.J-2011. Adaptive E nergy Controller-U niversity IT o f Copenhagen. D enm ark Wisconsin Valley Library Service - W V LS.org - C SV definition
109
LAMPIRAN 1 HASIL WAWANCARA
W aktu
: M onday, 1 D esem ber 2014
N am a Responden
: Tuan A
Status
: QA/QC di Perusahaan X
Tempat
: Cilandak, Jakarta
Pertanyaan : 1. Apakah sudah ada m etode yang selalu ditetapkan dalam pem bangunan aplikasi ? 2. Pada saat training, apa yang menjadi kendala dalam prosesnya (terutam a pengadaan)? 3. Apa yang menjadi tolak ukur dari hasil sebuah akuisisi data yang didapat? 4. Apakah yang menjadi concern dalam pem bangunan aplikasi ini? 5. Fungsi apa saja yang biasanya dilakukan dalam kustom isasi peralatan SCADA? Jaw aban : 1. D apat m enggunakan m etode apa saja yang sederhana, ringkas dan dapat dipantau dalam jangka w aktu tertentu 2. K endala yang sering ditemui adalah besarnya dana yang dikeluarkan mengingat perangkat pendukung memiliki harga yang sangat mahal, disamping itu mem akan w aktu yang cukup lama dalam proses instalasi sehingga manajem en w aktu sangat terkendali terutam a dalam dukungan pem aham an terhadap SCADA.
Beberapa poin tam bahan yang menjadi kendala :
- Kami tidak memiliki sarana yang memadai untuk menunjang pelatihan, ruang kantor pun cukup kecil. - Engineer kurang paham penggunaan aplikasi SCADA misal: OPC server - Engineer harus belajar aplikasi codesys untuk bisa m em baca data yang dikeluarkan oleh perangkat M odbus TCP yang digunakan, dan data yang dihasilkan berupa 2 Byte Integer.
110
3. Adalah proses track record atas pengawasan dan akuisisi data terutam a dalam mendukung proses pengarsipan data. 4. Adalah m enerapkan sebuah applikasi android yang sudah mendukung SCADA, yang juga mendukung dalam proses export - back-up data dan diharapkan dapat menggunakan library khusus yang sudah didesain oleh pem buat yang dipercaya. 5. Aplikasi hendaknya dapat mendukung pengaturan dinamis atas perubahan konfigurasi, dan backup dalam aplikasi m onitoring SCADA
111
W aktu
: M onday, 2 D esem ber 2014
Jenis W aw ancara
: M O M meeting
N am a R esponden
: Tuan A dan CEO
Status
: QA/QC di Perusahaan X
Tempat
: Cilandak, Jakarta
Topik : 1. Pengadaan sarana pendukung Training dan testing Hasil M O M : 1. Pengadaan sarana pendukung untuk training dan testing dilaksanakan dalam w aktu dibawah 1 bulan dengan m enggunakan m etode Extreme P ro g ra m m in g . 2. Pelatihan harus didukung oleh sarana untuk m engecek apakah konfigurasi benar berjalan atau tidak, m enerapkan Sim ulator yang sudah terintegrasi dengan kom puter dan jaringan nirkabel. 3. Kalau m em ungkinkan dibuat sebuah platform yang expandable dan dapat di kem bangkan ke depannya terutam a proses back-up data. 4. U ntuk saat ini yang dibutuhkan adalah aplikasi m obile yang simple dan ringan dengan dukungan library khusus yang dapat digunakan karena alat yang tersedia adalah android versi 4.1.1 (Jelly Bean). 5. Rangkum an hasil meeting terhadap aplikasi yang akan dibuat : -
D alam aplikasi, user diharuskan membuat device dan tag, device adalah alat / modul M odbus plc yang memiliki 1 atau lebih sensor dimana tiap - tiap sensor itu disebut dengan tag. Pada saat memulai aplikasi, user dapat menekan icon droidscada dan android akan mem unculkan tam pilan dashboard.
-
D ashboard mem unculkan daftar tag yang sudah di m asukkan sebelumnya. Dalam dashboard user dapat menambah tag baru atau pun merubah tag yang ada dan juga menghapus tag.
-
U ser dapat mengakses device list dari dashboard dimana devicelist akan menam pilkan daftar list yang tersedia. D alam devicelist user dapat m enambah device baru atau pun merubah device yang ada dan juga m enghapus device.
112
-
D ashboard juga memiliki fitur untuk m elakukan ekspor data ke sebuah file dalam form at csv.
-
Fitur utam a dashboard adalah m elakukan start / stop core service dim ana core inilah yang m enjalankan semua request data terhadap device sesuai dengan masing2 tag disetiap device.
-
K etentuan device dan tag, •
Setiap device dapat di ak tif atau nonaktifkan, device yang non aktif, maka setiap tagnya tidak akan diambil datanya.
•
K onfigurasi device harus memiliki : alam at IP, port, slavelD.
•
aplikasi akan m elaksanakan koneksi ke device dengan opsi retrytim es,tim eout, syncperiod
•
Setiap tag memiliki unit atau satuan nilai yang bebas (free text)
•
K onfigurasi tag harus memiliki : registeraddress, register format dan register type
•
Nilai yang didapat oleh tag dapat memiliki konfigurasi untuk melakukan scaling, dim ana skala dapat ditentukan jarak minimum dan maksimumnya, serta berapa angka dibelakang koma.
•
Nilai tag juga dapat ditentukan dalam konfigurasi untuk disim pan atau tidak. Hal ini akan memakan m emory storage sehingga dibutuhkan opsi untuk interval sampling data.
M engetahui,
QA/QC Perusahaan X
A .P
113 L am p iran 2 - Koding 1. ActivityBase.java return true;
package com.audy.droidscada; imp ort j ava.util.Arrays; import j ava.util.Locale; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityManager; import android.app.AlertDialog; import android.app.ProgressDialog; import android.app.ActivityManager.RunningServiceInfo; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.text.format.Time; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.EditText; import android.widget.NumberPicker; @SuppressLint("InflateParams") public class ActivityBase extends Activity {
public static String[] getNames(Class> e) { return Arrays.toString(e.getEnumConstants()).replaceAll("A .|.$", "").split(", "); } @Override protected void onCreate(Bundle savedInstanceState) {
} else { return super.onOptionsItemSelected(item); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { overridePendingTransition(R.anim.animsl ideinleft, R.anim.animslideoutright); }
protected boolean isMyServiceRunning(Class serviceClass) { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE )) { if (serviceClass.getName().equals(service.service.getCl assName())) { return true; } } return false; } protected ProgressDialog pBar; protected Handler mHandler = new Handler();
super.onCreate(savedInstanceState); getActionBar().setDisplayHomeAsUpEna bled(true); //loadLang(); } @Override protected void onPause() { super.onPause(); }
protected void showPBar(String Title, String Message) { final String title=Title; final String message=Message; mHandler.post(new Runnable() { public void run() { pBar = new ProgressDialog(ActivityBase.this); pBar.setCancelable(false);
@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { // This ID represents the Home or Up button. finish();
pBar.setTitle(title); pBar.setMessage(message); pBar.show(); } }); }
overridePendingTransition(R.anim. animsl ideinleft,
protected void showPBar(int Title,String R.anim.animslideoutright); return true; } else if (item.getItemId() == R.id.action_settings) {
Message) { showPBar(Resource(Title), Message); }
114 { protected void showPBar(int Title,int Message) showPBar(Resource(Title), Resource(Message)); } protected void updateControlValue(int ControlID,String Value) { EditText control=(EditText) findViewById(ControlID); control.setText(Value); } protected void setDialListener(final EditText control,final String Title,final int minValue,final int maxValue) { int cv=0; try { cv=Integer.parseInt(control.getText().toSt ring()); } catch (Exception e) { cv=minValue; } final int currentValue=cv; control.setFocusable(false); control.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {
showNumericDial(control.getId(),Title,mi nValue,maxValue,currentValue); } }); } protected void setStringDialListener(final EditText control,final String Title,final String[] items) { int cv=0; try { cv=Arrays.asList(items).indexOf(control. getText().toString()); } catch (Exception e) { cv=0; } final int currentValue=cv; control.setFocusable(false); control.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showStringDial(control.getId(),Title,curre ntValue,items); } }); }
protected void showStringDial(final int ControlID,String title,int currentvalue,final String[] Items)
AlertDialog.Builder builder = new AlertDialog.Builder(this); View view = getLayoutInflater().inflate(R.layout.dialpopup, null); final NumberPicker picker = (NumberPicker) view.findViewById(R.id. myNumber); picker.setMinValue(0); picker.setMaxValue(Items.length-1); picker.setValue(currentvalue); picker.setDisplayedValues(Items); builder.setView (view); builder.setTitle("Input "+title);
builder.setPositiveButton(android.R.string .ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { int pickerValue=picker.getValue(); updateControlValue(ControlID,Items[pic kerValue]); } }); builder.setNegativeButton(android.R.strin g.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { return; } }); final AlertDialog dialog = builder.create(); dialog.getWindow(). setFlags(WindowMa nager.LayoutParams.FLAG_ALT_FOCUSABLE_I M, WindowManager.LayoutParams.FLAG_ ALT_FOCUSABLE_IM); dialog.getWindow(). setSoftInputMode(W indowManager.LayoutParams.SOFT_INPUT_STAT E_ALWAYS_HIDDEN); dialog.show(); } protected void showNumericDial(final int ControlID,String title,Integer minValue,Integer maxValue,int currentvalue) { AlertDialog.Builder builder = new AlertDialog.Builder(this); View view = getLayoutInflater().inflate(R.layout.dialpopup, null); final NumberPicker picker = (NumberPicker) view.findViewById(R.id. myNumber); picker.setMinValue(minValue); picker.setMaxValue(maxValue); picker.setValue(currentvalue); builder.setView (view); builder.setTitle("Input "+title);
115
builder.setPositiveButton(android.R.string .ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { int pickerValue=picker.getValue();
AlertDialog.Builder(ActivityBase.this).setTitle(Reso urce(title)) .setMessage(message) .setNeutralButton(Resource(R.string.butto n_close), null).show(); }
updateControlValue(ControlID,String.val ueOf(pickerValue)); return; } });
protected void alert(String title, String message) { new AlertDialog.Builder(ActivityBase.this).setTitle(title). setMessage(message)
builder.setNegativeButton(android.R.strin g.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { return; } }); final AlertDialog dialog = builder.create();
.setNeutralButton(Resource(R.string.butto n_close), null).show(); } protected void alertOnUI(int title, int message) {
dialog.getWindow().setFlags(WindowMa nager.LayoutParams.FLAG_ALT_FOCUSABLE_I M,
final int Title=title; final int Message=message; runOnUiThread(new Runnable() {
WindowManager.LayoutParams.FLAG_ ALT_FOCUSABLE_IM);
public void run() { alert(Title,Message); }});
dialog.getWindow().setSoftInputMode(W indowManager.LayoutParams.SOFT_INPUT_STAT E_ALWAYS_HIDDEN); dialog.show();
} protected void alertOnUI(int title, String message) {
}
final int Title=title; final String
protected void updatePBar(String Message) { final String message = Message; mHandler.post(new Runnable() { public void run() {
Message=message; runOnUiThread(new Runnable() { public void run() { alert(Title,Message); }});
pBar.setMessage(message); } }); }
} protected void alertOnUI(String title, String message) { final String Title=title; final String Message=message; runOnUiThread(new Runnable() { public void run() {
protected void closePBar() { mHandler.post(new Runnable() { public void run() { pBar.dismiss(); }
alert(Title,Message);
});
}});
} } protected void alert(int title, int message)
protected String Resource(int id) { return getResources().getString(id); }
{ AlertDialog.Builder(ActivityBase.this).setTitle(Reso urce(title))
protected String getCurrentDate() { Time now = new Time(); now.setToNow(); return now.format("%d-%m%Y %H:%M:%S"); }
.setMessage(Resource(message)) .setNeutralButton(Resource(R.string.butto n_close), null).show(); } protected void alert(int title, String message) { }
116 2. C onstants.java package com .audy.droidscada; im port android.annotation.SuppressLint; im port java.util.Enum Set; im port java.util.H ashM ap; im port java.util.M ap; @ SuppressLint(,,U seSparseA rrays") public class C onstants { //ID m eans IntentDATA static final public String ID_DEVICES="devices"; static final public String ID_TAGS="tags"; static final public String ID_DEVICE="device"; static final public String ID _TA G ="tag"; static final public String ID _TA G ID ="tagid"; static final public String ID _DEVICEID="deviceid"; static final public String IN TEN T_O PTIO N ="intentoption"; static final public String IN TEN T_O PTIO N _N EW ="intentnew "; static final public String IN TEN T_O PTIO N _ED IT="intentedit"; static final public String BC_N O T_W O RK IN G ="now ork";
public enum DeviceProtocol { /// <sum m ary> /// Read only bit /// T C PIP (0); private static final M ap lookup = new HashM ap(); static { for(DeviceProtocol w : EnumSet. allOf(DeviceProtocol.class)) lookup.put(w.getCode(), w); }
private static final M ap lookup = new H ashM ap(); static { for(DeviceDriver w : EnumSet.allOf(DeviceDriver.class)) lookup.put(w.getCode(), w); } private int code; private DeviceDriver(int code) { this.code = code; } public int getCode() { return code; } public static DeviceDriver get(int code) { retu rn lookup. get(code); } } public enum RegisterType { /// <sum m ary> /// Read only bit /// Input_C ontacts (0), /// <sum m ary> /// Read only 16 bit /// Input_Registers (1), /// <sum m ary> /// Read w rite 16 bit /// Output_Holdings (2), /// <sum m ary> /// Read w rite bit /// Output_Coils (3); private static final M ap lookup = new HashM ap(); static { for(RegisterType w : EnumSet.allOf(RegisterType.class))
private int code; private DeviceProtocol(int code) { this.code = code; > } public int getCode() { retu rn code; }
lookup.put(w.getCode(), w); } private int code;
public static DeviceProtocol get(int code) {
private RegisterType(int code) {
return
this.code = code;
lookup.get(code);
} }
}
public int getCode() { return code; }
public enum DeviceDriver { /// <sum m ary> /// Read only bit /// M odbus (0);
public static RegisterType get(int code) { retu rn lookup. get(code); }
117 public static R egisterForm at get(int code) { retu rn pu b lic en u m R e g iste rF o rm a t
lookup. get(code); } }
Four_B ytes_Unsigned_Integer (0), Four_Bytes_Integer(1), Four_Bytes_Float(2),
public static String rv_NotOK ="not ok";
Two_Bytes_Unsigned_Integer(3), T wo_Bytes_Integer(4), T wo_Bytes_Discrete(5); private static final M ap lookup = new H ashM ap(); static { for(RegisterForm at w : EnumSet.allOf(RegisterForm at.class)) lookup.put(w.getCode(), w);
private int code; private R egisterForm at(int code) { this.code = code; } public int getCode() { return code; }
public static String rv_UnknownID ="unknow nid"; public static String rv_U nsupportedV ersion = "unsupportedversion" public static String rv_Nothing ="nothing"; public static String rv_Full ="full"; public static String rv_OK ="ok"; public static String cfg_usernam e="usernam e"; public static String cfg_userid="userid"; public static String cfg_passw ord="passw ord"; public static String cfg_verificationID="verificationid"; public static String cfg_w orkPerm itID ="w orkperm itid"; public static String cfg_NDA="NDA" public static String cfg_noKey="nokey"; public static String cfg_logindate="logindate"; public static String cfg_licensedate="licensedate";
3. D eviceForm .java package com .audy.droidscada; im port java.util.UUID; im port com.audy.droidscada.entities.Device; im port com.audy.droidscada.util.LocalDB; im port android.app.AlertD ialog; im port android.content.Intent; im port android.os.Bundle; im port android.view.M enu; im port android.view.M enuItem ; im port android.view.View; im port android.widget.EditText; im port android.widget.Switch; public class DeviceForm extends ActivityBase { Device device=null; String option=Constants.INTENT_O PTION_NEW ;
@ Override protected void onCreate(Bundle savedInstanceState) {
final EditText txtDevicePort = (EditText) findViewById(R.id.df_txtDevicePort); final EditText txtDeviceRetryTimes = (EditText) findViewById(R.id.df_txtDeviceRetryTimes); final EditText txtDeviceSyncPeriod = (EditText) findViewById(R.id.df_txtDeviceSyncPeriod); final EditText txtDeviceTim eOut = (EditText) findViewById(R.id.df_txtDeviceTimeOut); final EditText txtDeviceSlaveID = (EditText) findViewById(R.id.df_txtDeviceSlaveID); final EditText txtDeviceProtocol = (EditText) findViewById(R.id.df_txtDeviceProtocol); final Switch switchDeviceSuspend = (Switch) findViewById(R.id.df_switchSuspend); final EditText txtDeviceDriver = (EditText) findViewById(R.id.df_txtDeviceDriver);
super. onCreate(savedInstanceState); setContentView(R.layout.act_device_fo rm);
if(option.equalsIgnoreCase( Constants.INTENT_OPTION_ED IT)) {
Intent intent =getIntent(); option=Constants.INTENT_O PTION_ option=intent.getStringExtra(Constant s.INTENT_OPTION);
EDIT;
118
device=(Device)intent.getSerializableExtra(Const ants.ID_DEVICE); EditText txtDeviceName = (EditText) findViewById(R.id.df_txtDeviceName); EditText txtDeviceIP = (EditText) findViewById(R.id.df_txtDeviceIP); txtDeviceN ame. setT ext(device. Name); txtDeviceIP.setText(String.valueOf(dev ice.IPAddress)); txtDevicePort.setText(String.valueOf( device.Port)); txtDeviceRetryTim es.setText(String.val ueOf(device.RetryTimes)); txtDeviceSyncPeriod.setText(String.val ueOf( device.SyncPeriod)); txtDeviceTimeOut.setText(String.value Of(device.TimeOut)); txtDeviceDriver.setText(Constants.Dev iceDriver.get(device.DeviceDriver).toString()); txtDeviceProtocol.setText(Constants.D eviceProtocol.get(device.DeviceProtocol).toString( )); switchDeviceSuspend.setChecked(devic e.Suspend); txtDeviceSlaveID.setText(String.value Of(device.SlaveID)); } setDialListener(txtDeviceSlaveID, Resource(R.string.df_lblDeviceSlaveID), 1, 5); //setDialListener(txtDevicePort, Resource(R.string.df_lblDevicePort), 1, 65535); setDialListener(txtDeviceRetryTimes, Resource(R.string.df_lblDeviceSlaveID), 1, 10); String[] timeout=new String[]{"1000","2000","3000","4000","10000"} String[] syncperiod=new String[]{"1000","2000","5000","10000","30000" }; String[] devicedriver=getNam es(Constants.DeviceDriver.c lass); String[] deviceprotocol=getNames(Constants.DeviceProtoc ol.class); setStringDialListener(txtDeviceDriver, Resource(R.string.df_lblDeviceDriver),devicedriv er); setStringDialListener(txtDeviceProtoco l, Resource(R.string.df_lblDeviceProtocol), deviceprotocol); setStringDialListener(txtDeviceTimeO
ut, Resource(R.string.df_lblDeviceTim eout),tim eout); setStringDialListener(txtDeviceSyncPe riod, Resource(R.string.df_lblDeviceSyncPeriod), syncperiod); } @ O verride public boolean onC reateO ptionsM enu(M enu menu) { // Inflate the menu; this adds items to the action bar if it is present. getM enuInflater().inflate(R.m enu.devic e_form, menu); retu rn true; } @ O verride public boolean onOptionsItem Selected(M enuItem item) { // Handle action bar item clicks here. The action bar will // autom atically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidM anifest.xml. int id = item .getItemId(); if (id == R.id.action_settings) { retu rn true; } return super.onOptionsItem Selected(item ); } public void Save(View view) { EditText txtDeviceName = (EditText) findViewById(R.id.df_txtDeviceName); EditText txtDeviceIP = (EditText) findViewById(R.id.df_txtDeviceIP); EditText txtDevicePort = (EditText) findViewById(R.id.df_txtDevicePort); EditText txtDeviceRetryTimes = (EditText) findViewById(R.id.df_txtDeviceRetryTimes); EditText txtDeviceSyncPeriod = (EditText) findViewById(R.id.df_txtDeviceSyncPeriod); EditText txtDeviceTimeOut = (EditText) findViewById(R.id.df_txtDeviceTimeOut);
final EditText txtDeviceSlaveID = (EditText) findViewById(R.id.df_txtDeviceSlaveID); final EditText txtDeviceDriver = (EditText) findViewById(R.id.df_txtDeviceDriver); final EditText txtDeviceProtocol = (EditText) findViewById(R.id.df_txtDeviceProtocol); Switch switchDeviceSuspend = (Switch) findViewById(R.id.df_switchSuspend); boolean status=false; if(option.equalsIgnoreCase( Constants.INTENT_OPTION_NEW )) { device=new Device();
119
device.ID=UUID.randomUUID(); device.Detail="";
device.SlaveID=Integer.parseInt( txtDeviceSlaveID.getText().toString());
device.Location="Indonesia";
device.Suspend=switchDeviceSuspend.i sChecked();
device.ProjectID=1; }
device.Name=txtDeviceName.getText(). toString(); device.IPAddress=txtDeviceIP.getText( ).toString(); device.Port=Integer.parseInt( txtDevicePort.getText().toString()); device.Tim eO ut=Integer.parseInt( txtDeviceTimeOut.getText().toString()); device.R etryTim es=Integer.parseInt( txtDeviceRetryTimes.getText().toString()); device.SyncPeriod=Integer.parseInt( txtDeviceSyncPeriod.getText().toString()); device.DeviceDriver=(Constants.Device D river.valueOf(txtDeviceDriver.getText().toStrin g())).getCode(); device.DeviceProtocol=(Constants.Devi ceProtocol.valueOf(txtDeviceProtocol.getText().to String())).getCode();
if(option.equalsIgnoreCase( Constants.INTENT_OPTION_NEW )) { status= LocalDB.getInstance(this).insertDevice (device); } else{ status=LocalDB.getInstance(this).updat eDevice(device); } if(status) { this.finish(); } else { new AlertDialog.Builder(DeviceForm.this).setTitle("D evice").setM essage("Gagal m asukin device") .setN eutralB utton("tutup", null).show(); } } }
4. DeviceList.java package com .audy.droidscada; setContentView(R.layout.act_device_lis im port java.util.A rrayL ist; im port java.util.List;
t);
im port com .audy.droidscada.A dapter. DeviceListAdapter
@ O verride protected void onResume() { // TODO Auto-generated m ethod stub super.onResume(); startFolder();
im port com.audy.droidscada.entities.Device; im port com .audy.droidscada.entities.DeviceListObject; im port com.audy.droidscada.util.LocalDB; im port com .audy.droidscada.util.SwipeDetector; im port im port im port im port im port im port im port im port im port im port im port
android.app.Activity; android.app.AlertD ialog; android.content.DialogInterface; android.content.Intent; android.os.Bundle; android.view.M enu; android.view.M enuItem ; android.view.View; android.widget.AdapterView; android.widget.ListView; android.widget.Toast;
public class DeviceList extends ActivityBase { ArrayList Devices; @ Override protected void onCreate(Bundle savedInstanceState) {
}
} @ O verride protected void onPause() { super.onPause(); } public void adddevice(View view) { goOpenDeviceForm (null,Constants.IN TENT_OPTION_NEW ); } public List getDevices() { List list = new ArrayList(); LocalDB lb =LocalDB.getInstance(this); list = lb.getDevices(); retu rn list; }
super. onCreate(savedInstanceState);
120 public List TurnToList() { List devices = getDevices(); List listobject = new ArrayList(); for (int i = 0; i < devices.size(); i++) { DeviceListObject obj = new DeviceListObject(); Device device = devices.get(i); obj.ID = device.ID; obj. Name = device.Name;
List.setOnTouchListener(swipeDetecto r); L ist.setA dapter(adapter); List.setClickable(true); List.setLongClickable(true); // tam bahkan listener u ntuk m em buat list clickable List.setOnItem ClickListener(new A dapterV iew .O nItem ClickListener() { @ O verride public void onItem Click(A dapterView arg0, View arg1,
obj. Unit=device.Detail; obj.content =
int position, long arg3) {
device; obj.isactive=false;
if (swipeDetector.swipeDetected()) { listobject.add(obj); } retu rn listobject; }
if (swipeDetector.getAction().name().equals("RL"))
public void goOpenDeviceForm(Device device, String IntentO ption) { Intent intent = new Intent(this, DeviceForm.class);
DeviceListObject selected = (DeviceListObject) List
.getItemAtPosition(position); intent.putExtra(Constants.ID _D EV IC Device device
E, device); (Device) selected.content; intent.putExtra(C onstants.IN TEN T_O PTION, IntentOption); startActivity(intent); overridePendingTransition(R .anim .ani m slideinright,R.anim .anim slideoutleft);
public boolean removeDevice(Device
goOpenDeviceForm (device,Constants.I NTENT_OPTION_EDIT); } else if (swipeDetector.getAction().name()
.equals("L R ")) {
device) { return LocalDB.getInstance(this).deleteDevice(device.ID)
public void startFolder() { try { final D eviceListAdapter adapter = new DeviceListAdapter(this, TurnToList()); final ListView List = (ListView) findViewById(R.id.dl_deviceList); final SwipeDetector swipeDetector = new SwipeDetector();
Toast. m akeText(getApplicationContext
"Bac k Swype", Toast.LENGTH_SHORT).show(); } else if (swipeDetector.getAction().name()
.equals( "T B ")) {
Toast. m akeText(getApplicationContext runO nU iThread(new Runnable() {
@ Override public
"down Swype", Toast.LENGTH_SHORT).show();
void run() { } else { // TODO A uto-generated m ethod stub Toast. m akeText(getApplicationContext (), "UP Swype",
121
R.array.list_item _option,
Toast.LENGTH_SHORT).show(); }
DialogInterface.OnClickListener() { } else { DeviceListObject selected (DeviceListObject) List
public void onClick(DialogInterface dialog,
int which) {
.getItemAtPosition(position); Device device = (Device)
// The 'w hich' argum ent
selected.content; contains the goOpenDeviceForm(device,Constants.I NTENT_OPTION_EDIT);
// index position
if (which == 0) { }); final Activity act = goOpenDeviceForm (device,Constants.I NTENT_OPTION_EDIT);
DeviceList.this;
List.setOnItem LongClickListener(new AdapterView.OnItem LongClickListener() {
} else {
@ Override public boolean onItem LongClick(AdapterView arg0, View arg1,
AlertDialog.Builder builder = new AlertDialog.Builder(
int position, long arg3) { if (swipeDetector.swipeDetected()) {
act);
DeviceListObject selected = (DeviceListObject) List builder.setTitle(Resource(R.string.w_c onfirm_delete)) .getItemAtPosition(position); Device device = (Device) selected.content;
.setMessage(Resource(
goOpenDeviceForm(device,Constants.I NTENT_OPTION_EDIT); R.string. w_confirm_device_delete)) } else { DeviceListObject selected = (DeviceListObject) List
. setC ancel able(false)
.getItemAtPosition(position); .setPositiveButton( final Device device = (Device) selected.content;
Resource(R.string.notification_answer_ AlertDialog.Builder builder new AlertDialog.Builder(
yes),
act); D ia lo g In te rfac e .O n C lic k L iste n er() {
builder.setTitle("O ption").setItem s(
122
public
void onClick(
DialogInterface dialog, @ Override
int id) {
public void run() {
recreate(); new T hread(new Runnable() {
public void run() {
show PBar("Please }});
W ait", "Removing Device");
if (removeDevice(device)) {
} else {
//startFolder(); alertOnUI(Resource(R.string.w_device delete),
alertOnUI(Resource(R.string.w_device delete), Resource(R.string.w_failed));
Resource(R.string.w_success));
}
runO nU iThread(
closePBar();
new
Runnable() {
}
123
builder.create().show(); }).start(); dialog.dismiss();
}
} })
retu rn true; } });
.setNegativeButton( Resource(R.string.notification_answer no), new DialogInterface.OnClickListener() {
} }); } catch (Exception e) { DeviceList.this.finish();
public void onClick(
//alertO nU I(R.string.notification_title_j obcreation, e.getMessage()); } }
DialogInterface dialog,
int id) {
dialog.cancel(); } }); AlertDialog alert = builder .create();
alert.show();
}
} });
@ O verride public boolean onOptionsItem Selected(M enuItem item) { // Handle action bar item clicks here. The action bar will // autom atically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidM anifest.xml. int id = item .getItemId(); if (id == R.id.action_settings) { retu rn true; } return super.onOptionsItem Selected(item ); } @ O verride public boolean onC reateO ptionsM enu(M enu menu) { // Inflate the menu; this adds items to the action bar if it is present. getM enuInflater().inflate(R.m enu.devic e_list, menu); retu rn true; } }
5. ScadaD ashboard.java package com .audy.droidscada; im port java.util.A rrayL ist; im port java.util.H ashM ap; im port java.util.List; im port java.util.UUID; im port com .audy.droidscada.A dapter.TagListA dapter; im port com.audy.droidscada.entities.Device; im port com .audy.droidscada.entities.Tag; im port com .audy.droidscada.entities.TagListObject; im port com .audy.droidscada.services.Core; im port com .audy.droidscada.services.Core.LocalBinder; im port com .audy.droidscada.util.CSV; im port com.audy.droidscada.util.LocalDB; im port com .audy.droidscada.util.SwipeDetector; im port android.app.Activity; im port android.app.A ctionBar; im port android.app.AlertD ialog; im port android.app.Fragm ent;
im port android.app.Fragm entM anager; im port android.content.BroadcastReceiver; im port android.content.Com ponentNam e; im port android.content.Context; im port android.content.DialogInterface; im port android.content.Intent; im port android.content.IntentFilter; im port android.content.ServiceConnection; im port android.os.Bundle; im port android.os.IBinder; im port android.util.Log; im port android.view .LayoutInflater; im port android.view.M enu; im port android.view.M enuItem ; im port android.view.View; im port android.view.ViewGroup; im port android.support.v4.content.LocalB roadcastM ana ger; im port android.support.v4.w idget.D raw erLayout; im port android.widget.AdapterView; im port android.widget.Button;
124 im port android.widget.ListView; im port android.widget.Toast;
for(int i=0;i
public class SCADADashboard extends ActivityBase implements NavigationD raw erFragm ent.N avigationD raw erC allbacks { ArrayList Devices; A rrayL ist tags; Intent serviceIntent ; List tlo; Core CoreService; T agListA dapter adapter; //if(str != null & & !str.isEmpty())
{ String data=hashM ap.get(tlo.get(i).ID); if(data!=null){
tlo.get(i).Value=hashM ap.get(tlo.get(i).I D);
tlo.get(i).isactive=true; BroadcastReceiver receiver; @ Override protected void onCreate(Bundle savedInstanceState) { super. onCreate(savedInstanceState);
}else {tlo. get(i). isactive=false;} } } else{
setContentView(R.layout.activity_scad adashboard); m N avigationD raw erFragm ent = (NavigationD raw erFragm ent) getFragm entM anager() .findFragm entById(R.id.navigation_dr awer);
for(int i=0;i
if(tlo.get(i).content.DeviceID.toString() ==intent.getStringExtra(Constants.ID _D EV IC EI D)){
mTitle = getTitle(); // Set up the drawer. m N avigationD raw erFragm ent.setU p(R .id.navigation_drawer,
tlo.get(i).Value=intent.getStringExtra( Core.CORE_M ESSAGE);
tlo. get(i). isactive=false;
(Draw erLayout) findViewById(R.id.drawer_layout));
} protected void startCoreService() { //run the service serviceIntent = new Intent(this,Core.class); serviceIntent.putExtra(Constants.ID _D EVICES,Devices); bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); startService(serviceIntent); //load broadcast catcher receiver = new BroadcastReceiver() { @ Override public void onReceive(Context context, Intent intent) { String s intent.getStringExtra(Core.CO RE_M ESSA G E); if(s=="DATA") {
} } adapter.notifyD ataSetChanged(); } }; } @ O verride protected void onPause() { if(ServiceStatus){
unbindService(serviceConnection); LocalBroadcastM anager.getInstance(th is).unregisterReceiver(receiver); super.onPause();
} @ O verride protected void onStart() { super.onStart();
@ SuppressW arnings("unchecked") } HashM ap hashM ap = (HashM ap)intent.getSerializableExtra(C ore.C O RE_ DATA);
@ O verride protected void onResume() {
125 obj.Device=""; obj.content = tag; obj.isactive=false;
// TODO Auto-generated m ethod stub super. onResume(); //get data from database LocalDB db= LocalDB.getInstance(this); Devices=db.getDevices(); tlo=TurnToList(); startFolder(); serviceIntent=new Intent(this,Core.class); if(isM yServiceRunning(Core.class))
listobject.add(obj); } retu rn listobject; } public void goOpenTagForm (Tag tag, String IntentO ption) { Intent intent = new Intent(this, TagForm.class);
L og.d("D ashboard", "S tarting up");
intent.putExtra(Constants.ID _TA G , tag);
ServiceStatus=true; Button btn=(Button) findViewById(R.id.db_btnToggleCore); btn.setText("Stop Service"); } else
intent.putExtra(C onstants.IN TE N T_O PTION, IntentOption); startActivity(intent);
overridePendingT ransition(R. anim. ani m slideinright, R.anim.anim slideoutleft);
L og.d("D ashboard", "Service already running"); if(ServiceStatus){
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); LocalBroadcastM anager.getInstance(th is).registerReceiver((receiver), new IntentFilter(C ore.CO RE_RESU LT));
public void startFolder() { try { adapter = new T agListA dapter(this, tlo); final ListView List = (ListView) findViewById(R.id.JobList); final SwipeDetector swipeDetector = new SwipeDetector(); runO nU iThread(new Runnable() {
// CoreService.updateDevice();
@ Override public void run() {
@ Override protected void onStop() { super. onStop(); }
// TODO A uto-generated method stub
List.setOnTouchListener(swipeDetecto public List getTags() { List list = new ArrayList(); LocalDB lb =LocalDB.getInstance(this); list = lb.getTags(); retu rn list; }
r); List.setA dapter(adapter); List.setClickable(true); List.setLongClickable(true); // tam bahkan listener untuk m em buat list clickable
public List TurnToList() { List tags = getTags(); List listobject = new ArrayList(); for (int i = 0; i < tags.size(); i++) { TagListO bject obj = new TagListO bject(); Tag tag = tags.get(i); obj.ID = tag.ID; obj.Name = tag.Name; obj.Unit=tag.Unit;
List.setOnItem ClickListener(new AdapterV iew .O nItem ClickListener() { @ Override public void onItem Click(A dapterView arg0, View arg1, int position, long arg3) {
if (swipeDetector.swipeDetected()) {
126
if (swipeDetector.getAction().name().equals("RL"))
TagListO bject selected = (TagListObject) List
goO penTagForm (tag,Constants.IN TE NT_OPTION_EDIT);
});
final Activity act = SCADADashboard.this;
.getItemAtPosition(position);
Tag tag = (Tag) selected.content;
goO penTagForm (tag,Constants.IN TE NT_OPTION_EDIT); } else if (swipeDetector.getAction().name()
List.setOnItem LongClickListener(new AdapterView.OnItem LongClickListener() { @ O verride public boolean onItem LongClick(AdapterView arg0, View arg1, int position, long arg3) {
.equals("L R ")) {
Toast. m akeText(getApplicationContext
"B ack Swype" Toast.LENGTH_SHORT).show(); } else if
if (swipeDetector.swipeDetected()) {
TagListO bject selected (TagListObject) List
.getItemAtPosition(position);
(swipeDetector.getAction().name() Tag tag = (Tag) selected.content; .equals("TB ")) {
Toast. m akeText(getApplicationContext
goO penTagForm (tag,Constants.IN TE NT_OPTION_EDIT); } else {
"down Swype", Toast.LENGTH_SHORT).show();
TagListO bject selected (TagListObject) List
} else { .getItemAtPosition(position); Toast. m akeText(getApplicationContext (), "UP Swype",
final Tag tag = (Tag) selected.content;
Toast.LENGTH_SHORT).show(); }
AlertDialog.Builder builder = new AlertDialog.Builder(
} else { act); TagListO bject selected = (TagListObject) List
builder.setTitle("O ption").setItem s(
.getItemAtPosition(position);
R.array.list_item _option,
Tag tag (Tag) selected.content; D ia lo g In te rfac e .O n C lic k L iste n er() {
127 p u b lic void
onClick(DialogInterface dialog,
public void onClick(
int which) { DialogInterface dialog, // The 'w hich' argum ent contains the
// index
int id) {
position
if (which == 0) { new T hread(new Runnable() { goO penTagForm (tag,Constants.IN TE NT_OPTION_EDIT); public } else {
void run() {
AlertDialog.Builder builder = new AlertDialog.Builder( show PBar("Please W ait", "Removing T ag"); act);
builder.setTitle(Resource(R.string.w_c onfirm_delete))
if (removeTag(tag)) {
.setMessage(Resource( //startFolder();
R .string.w confirm tag delete))
alertOnUI(Resource(R.string.w_tag_de .setCancelable(false)
lete),
.setPositiveButton( Resource(R.string.w_success));
Resource(R.string.notification_answer yes),
runO nU iThread( new D ialo g In te rfac e .O n C lic k L iste n er()
{
new Runnable() {
128
dialog.dismiss();
@ Override }
})
public void run() {
.setNegativeButton( recreate();
Resource(R.string.notification_answer no),
}}); new DialogInterface.OnClickListener() {
} else { public void onClick(
alertOnUI(Resource(R.string.w tag de lete),
DialogInterface dialog,
int id) { Resource(R.string.w_failed));
dialog.cancel(); }
} closePBar();
}); }
AlertDialog alert = builder
}).start();
.create();
129 public void o n S e c tio n A tta ch e d (in t
num ber) { switch (num ber) { case 1: mTitle = getString(R.string.title_section1); break; case 2: mTitle = getString(R.string.title_section2); break; case 3: mTitle = getString(R.string.title_section3); break; } }
alert.show();
});
builder.create().show(); } retu rn true; }
boolean ServiceStatus=false; public void ToggleCore(View view) { Button btn=(Button) findViewById(R.id.db_btnToggleCore);
}); } }); } catch (Exception e) { SCADADashboard.this.finish(); //alertO nU I(R.string.notification_title_j obcreation, e.getMessage());
public boolean removeTag(Tag tag) { return LocalDB.getInstance(this).deleteTag(tag.ID);
if(isMyServiceRunning(Core.class)) {ServiceStatus=false; btn.setT ext("S tart Service"); CoreService.stopService(); unbindService(serviceConnection); LocalBroadcastM anager.getInstance(th is).unregisterReceiver(receiver); stopService(serviceIntent); } else
if(Devices.size()>0){ private ServiceConnection serviceConnection = new ServiceConnection() { @ Override public void onServiceConnected(Com ponentName name, IB inder service) { CoreService = ((LocalBinder) service).getService();
@ Override public void onServiceDisconnected(ComponentName name) { CoreService = null; } }; @ Override public void onNavigationDrawerItem Selected(int position) { // update the main content by replacing fragm ents F ragm entM anager fragm entM anager = getFragm entM anager(); fragm entM anager .beginTransaction() .replace(R.id.container, P laceholderFragm ent.new Instance(posi tion + 1)).commit();
startCoreService(); ServiceStatus=true; bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); LocalBroadcastM anager.getInstance(th is).registerReceiver((receiver), new IntentFilter(C ore.CO RE_RESU LT));
btn.setText("Stop Service"); } else{ alert("N o Device", "No device available, please insert atleast 1 device first!");
public void restoreA ctionBar() { ActionBar actionBar = getActionBar(); actionBar.setNavigationM ode(ActionB ar. NAVIGATION_M ODE_ST ANDARD);
130
actionBar.setDisplayShowTitleEnabled (true); actionBar.setTitle(m Title);
@ Override public boolean onOptionsItem Selected(M enuItem item) { // Handle action bar item clicks here. The action bar will // autom atically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidM anifest.xml. int id = item .getItemId(); if (id == R.id.action_addtag)
public boolean onC reateO ptionsM enu(M enu menu) { if (!m NavigationD raw erFragm ent.isD raw erO pen()) // Only show items in the action bar relevant to this screen // if the draw er is not showing. Otherwise, let the draw er // decide what to show in the action bar. getM enuInflater().inflate(R.m enu.scad adashboard, menu); restoreActionBar(); retu rn true; return super.onC reateO ptionsM enu(m enu); /**
if(Devices.size()>0){ goO penTagForm (null,Constants.IN TE NT_OPTION_NEW ); } else{
* Fragm ent m anaging the behaviors, interactions and presentation of the * navigation draw er. */ private N avigationD raw erFragm ent m N avigationD raw erFragm ent;
alert("N o Device", "No device available, please insert atleast 1 device first!"); Used to store the last screen title. For }return true; * {@link #restoreActionBar()}. */ private C harSequence mTitle; /**
else if(id==R.id.action_exportdata) CSV csvhelper=new CSV(this); int row=csvhelper.ExportTagValue(); if(row<1){ alert("E xport D ata", "N othing to export"); else
alert("E xport D ata",row + " rows Exported!"); } retu rn true; } else if(id==R.id.action_devicelist) { Intent intent = new Intent(this, DeviceList.class); startActivity(intent); overridePendingTransition(R .anim .ani m slideinright, R.anim.anim slideoutleft); retu rn true; } else{ return super. onOptionsItemSelected(item);
A placeholder fragm ent containing a simple view. */ public static class PlaceholderFragm ent extends Fragm ent { /** * The fragm ent argum ent representing the section num ber for this * fragment. */ private static final String ARG_SECTION_NUM BER = "section_num ber"; /** * R eturns a new instance of this fragm ent for the given section num ber. */ public static P laceholderFragm ent newInstance(int sectionNumber) { PlaceholderFragm ent fragm ent = new PlaceholderFragm ent(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUM BE R, sectionNumber); fragm ent.setA rgum ents(args); retu rn fragm ent; } public P laceholderFragm ent() {
@ Override
131 public void onAttach(Activity activity) {
@ Override public View onCreateV iew (LayoutInflater inflater, ViewGroup container,
super.onAttach(activity); Bundle
savedInstanceState) { View rootView = inflater.inflate(R .layout.fragm ent_scadadashboar d,
((SCADADashboard) activity).onSectionAttached(getArguments() . getInt(ARG_SECTION_NUM BER)); } }
container, false); retu rn rootView; } } @ Override
6. T agForm .java package com .audy.droidscada; im port java.util.A rrayL ist; im port java.util.UUID; im port com.audy.droidscada.entities.Device; im port com .audy.droidscada.entities.Tag; im port com.audy.droidscada.util.LocalDB; im port im port im port im port im port im port im port im port im port im port
android.app.AlertD ialog; android.content.Intent; android.os.Bundle; android.view.M enu; android.view.M enuItem ; android.view.View; android.w idget.A rrayA dapter; android.widget.EditText; android.widget.Spinner; android.widget.Switch;
public class TagForm extends ActivityBase { ArrayList Devices; ArrayA dapter dataA dapter; Tag tag=null; String option=Constants.INTENT_O PTION_NEW ; @ Override protected void onCreate(Bundle savedInstanceState) {
final EditText txtTagR egisterType = (EditText) findViewById(R.id.tf_txtTagRegisterType); final EditText txtM inValue = (EditText) findViewById(R.id.tf_txtTagM inValue); final EditText txtM axValue = (EditText) findViewById(R.id.tf_txtTagM axValue); final EditText txtStorageSam pling = (EditText) findViewById(R.id.tf_txtTagStorageSampling); final EditText txtDecim alNum ber = (EditText) findViewById(R.id.tf_txtTagDecim aNum ber);
if(option.equalsIgnoreCase( Constants.INTENT_OPTION_ED IT)) { Switch switchTagEnableScaling=(Switch) findViewById(R.id.tf_lblTagEnableScaling); Switch switchTagEnableStorage=(Switch) findViewById(R.id.tf_lblTagEnableStorage); EditText txtTagN am e = (EditText) findViewById(R.id.tf_txtTagName); EditText txtTagU nit = (EditText) findViewById(R.id.tf_txtTagUnit);
super. onCreate(savedInstanceState); setContentView(R.layout.act_tag_form ); LocalDB db = LocalDB.getInstance(this); Devices= db.getDevices(); BindSource();
tag=(Tag)intent.getSerializableExtra(C onstants.ID_TAG); Device device=db.getDevicebyID(tag.DeviceID); int spinnerPostion = dataAdapter.getPosition(device); spinner.setSelection(spinnerPostion);
Intent intent =getIntent(); option=intent.getStringExtra(Constant s.INTENT_OPTION); Spinner spinner = (Spinner) findViewById(R.id.tf_spDeviceName); final EditText txtTagR egisterA ddress = (EditText) findViewById(R.id.tf_txtTagRegisterAddress); final EditText txtT agR egisterForm at = (EditText) findV iew ById(R.id.tf_txtTagRegisterForm at);
txtTagNam e.setText(tag.Name); txtTagRegisterAddress.setText(String. valueOf(tag.RegisterAddress)); txtTagR egisterForm at.setText(Constan ts.R egisterForm at.get(tag.R egisterForm at).toStri ng()); txtTagRegisterType.setText(Constants. RegisterType.get(tag.RegisterType).toString());
132
android.R.layout.sim ple_spinner_item ,
sw itchTagEnableScaling.setChecked(ta g.EnableScaling);
Devices);
txtM inValue.setText(String.valueOf( tag.M inValue));
dataAdapter.setDropDow nViewResour ce(android.R.layout.sim ple_spinner_item );
txtM axValue.setText(String.valueOf(ta g.MaxValue)); sw itchTagEnableStorage.setChecked(ta g.EnableStorage); txtStorageSam pling.setText(String.valu eOf( tag.StorageSam pling)); txtDecim alNum ber.setText(String.valu eOf( tag.DecimalNumber)); txtTagUnit.setText(tag.Unit);
//setDialListener(txtTagRegisterAddres s, Resource(R.string.tf_lblTagRegisterAddress), 1, 65535); setDi alListener(txtDecim alNum ber, Resource(R.string.tf_lblTagDecim aNum ber), 0, 10); String[] storagesampling=new String[]{"5000","10000","30000","60000","3000 00"}; setStringD ialListener(txtStorageSam pli ng, Resource(R.string.tf_lblTagStorageSam pling),sto ragesampling); String[] registerform at=getN am es(C onstants.RegisterFor mat.class); String[] registertype=getNam es(Constants.RegisterType.cl ass); setStringD ialListener(txtTagRegisterF orm at, Resource(R.string.tf_lblTagRegisterForm at),regis terform at); setStringDialListener(txtTagRegisterT ype, Resource(R.string.tf_lblTagRegisterType), registertype);
public void BindSource() { Spinner spinner2 = (Spinner) findViewById(R.id.tf_spDeviceName); /*List<String> list = new ArrayList<String>(); list.add(Resource(R.string.w_select_de vice_here)); for(Device device : Devices)
list.add(device.Name); }*/ dataA dapter = new ArrayA dapter(this,
spinner2.setA dapter(dataA dapter); spinner2.setSelection(0); } @ O verride public boolean onC reateO ptionsM enu(M enu menu) { // Inflate the menu; this adds items to the action bar if it is present. getM enuInflater().inflate(R.m enu.tag_f orm, menu); retu rn true; } @ O verride public boolean onOptionsItem Selected(M enuItem item) { // Handle action bar item clicks here. The action bar will // autom atically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidM anifest.xml. int id = item .getItemId(); if (id == R.id.action_settings) { retu rn true; } return super.onOptionsItem Selected(item );
public void Save(View view) { Spinner spinner = (Spinner) findViewById(R.id.tf_spDeviceName); Device device=(Device)spinner.getSelectedItem(); EditText txtTagN am e = (EditText) findViewById(R.id.tf_txtTagName); EditText txtTagR egisterA ddress = (EditText) findViewById(R.id.tf_txtTagRegisterAddress); EditText txtT agR egisterForm at = (EditText) findV iewById(R.id.tf_txtTagRegisterForm at); EditText txtTagR egisterType = (EditText) findViewById(R.id.tf_txtTagRegisterType); Switch switchTagEnableScaling=(Switch) findViewById(R.id.tf_lblTagEnableScaling); EditText txtM inValue = (EditText) findViewById(R.id.tf_txtTagM inValue); EditText txtM axV alue = (EditText) findViewById(R.id.tf_txtTagM axValue); Switch switchTagEnableStorage=(Switch) findViewById(R.id.tf_lblTagEnableStorage); EditText txtStorageSam pling = (EditText) findViewById(R.id.tf_txtTagStorageSampling);
133 EditText txtDecimalNum ber = (EditText) findViewById(R.id.tf_txtTagDecim aNum ber); EditText txtTagU nit = (EditText) findViewById(R.id.tf_txtTagUnit); boolean status=false; if(option.equalsIgnoreCase( Constants.INTENT_OPTION_NEW )) { tag=new Tag(); tag. ID=UUID. randomUUID(); tag.A sset="tag"; tag.T ype= "tag"; tag.G roup= "tag";
tag.EnableStorage=sw itchTagEnableSt orage.isChecked(); tag.StorageSam pling=Integer.parseInt( txtStorageSam pling.getText().toString()); tag.Unit=txtTagUnit.getText().toString( );
tag.M axValue=Double.parseDouble(txt MaxValue. getText().toString());//65535; tag.M inValue=Double.parseDouble(txt M inValue.getText().toString());//0; //tags.add(tag);
tag.L ocation="tag"; tag.StoragePeriod=1000; } tag.DeviceID=device.ID;
if(option.equalsIgnoreCase( Constants.INTENT_OPTION_ED IT)) {
tag.Nam e=txtTagNam e.getText().toStri
status=LocalDB.getInstance(this).updat eTag(tag);} else
ng(); tag.Detail=txtTagNam e.getText().toStri ng();
{status=LocalDB.getInstance(this).inser tTag(tag);} if(status) {
tag.RegisterForm at=(Constants.Registe rForm at.valueO f(txtTagRegisterForm at.getText() .toString())).getCode(); tag.RegisterType=(Constants.RegisterT ype.valueO f(txtTagRegisterType.getText().toStrin g())).getCode(); tag.R egisterA ddress=Integer.parseInt(t xtTagRegisterAddress.getText().toString());
tag.EnableScaling=switchTagEnableSc aling.isChecked();
this.finish(); } else { new AlertDialog.Builder(TagForm .this).setTitle("Tag ").setM essage("Gagal m asukin tag") .setN eutralB utton("tutup", null).show(); } }
tag.D ecim alN um ber=Integer.parseInt( txtDecimalNum ber.getText().toString());
}
7. D eviceListA dapter.java package com .audy.droidscada.A dapter; im port java.util.List; im port im port im port im port im port im port im port im port im port
android.annotation.SuppressLint; android.app.Activity; android.content.Context; android.view.LayoutInflater; android.view.View; android.view.ViewGroup; android.widget.BaseAdapter; android.widget.ImageView; android.widget.TextView;
im port com.audy.droidscada.R; im port com .audy.droidscada.Loader.Im ageLoader; im port com.audy.droidscada.entities.Device; im port com .audy.droidscada.entities.DeviceListObject; @ S uppressL int("InflateP aram s") public class DeviceListAdapter extends BaseA dapter {
private Activity activity; private List data; private static L ayoutInflater inflater=null; public Im ageLoader im ageLoader; public DeviceListAdapter(Activity a, List d) { activity = a; data=d; inflater = (LayoutInflater)activity.getSystem Service(Contex t.LAYOUT_INFLATER_SERVICE); im ageLoader=new Im ageLoader(activity.getApplicationContext()); } public int getCount() { retu rn data.size(); } public Object getItem (int position) { Object cur=data.get(position); retu rn cur;//position;
134 }
public long getItem Id(int position) { retu rn position; } public View getView(int position, View convertView, ViewGroup parent) { View vi=convertView; if(convertView==null) vi = inflater.inflate(R.layout.comm onlist, null); DeviceListObject cur=data.get(position); TextView tagName=(TextView)vi.findViewById(R.id.cl_txt Name); TextView deviceName=(TextView)vi.findViewById(R.id.cl_t xtDevice); TextView Unit=(TextView)vi.findViewById(R.id.cl_txtUnit)
ImageView image=(ImageView)vi.findViewById(R.id.cl_imgI con); Device device=(Device)cur.content; tagName.setText(cur.Name); deviceName.setText(String.valueOf( device.SyncPeriod)+"ms"); Value.setText(cur.Value); Unit.setText(device.IPAddress+":"+de vice.Port); if(device.Suspend ) { im age.setIm ageResource(R.drawable.st ubok); } else { im age.setIm ageResource(R.drawable.st
TextView Value=(TextView)vi.findViewById(R.id.cl_txtVal ue);
ub); } retu rn vi; } }
8. T aglistA dapter.java retu rn data.size();
package com .audy.droidscada.A dapter; } im port java.util.List; im port android.annotation.SuppressLint; im port android.app.Activity; im port android.content.BroadcastReceiver; im port android.content.Context; im port android.view.LayoutInflater; im port android.view.View; im port android.view.ViewGroup; im port android.widget.BaseAdapter; im port android.widget.ImageView; im port android.widget.TextView; im port com.audy.droidscada.R; im port com .audy.droidscada.Loader.Im ageLoader; im port com .audy.droidscada.entities.TagListObject; @ S uppressL int("InflateP aram s") public class T agListA dapter extends BaseAdapter { BroadcastReceiver receiver; private Activity activity; private List data; private static L ayoutInflater inflater=null; public Im ageLoader im ageLoader; public TagListA dapter(A ctivity a, List d) { activity = a; data=d; inflater = (LayoutInflater)activity.getSystem Service(Contex t.LAYOUT_INFLATER_SERVICE); im ageLoader=new Im ageLoader(activity.getApplicationContext()); } public int getCount() {
public Object getItem (int position) { Object cur=data.get(position); retu rn cur;//position; } public long getItem Id(int position) { retu rn position; } public View getView(int position, View convertView, ViewGroup parent) { View vi=convertView; if(convertView==null) vi = inflater.inflate(R.layout.com m onlist, null); TagListO bject cur=data.get(position); TextView tagName=(TextView)vi.findViewById(R.id.cl_txt Name); TextView deviceName=(TextView)vi.findViewById(R.id.cl_t xtDevice); TextView Unit=(TextView)vi.findViewById(R.id.cl_txtUnit) TextView Value=(TextView)vi.findViewById(R.id.cl_txtVal ue); ImageView image=(ImageView)vi.findViewById(R.id.cl_imgI con); tagName.setText(cur.Nam e); deviceName.setText(cur.Device); Value.setText(cur.Value); Unit.setText(cur.Unit); if(cur.isactive ) {
135
im age.setIm ageResource(R.drawable.st
im age.setIm ageResource(R.drawable.st ubalert);
ubok);
}
} else {
retu rn vi; } }
9. ID eviceDriver.java package com.audy.droidscada.Driver;
Boolean W rite(T ag tag, String value);
im port com .audy.droidscada.entities.*;
Boolean isD riverW ork();
public interface IDeviceDriver { int[] Read(Tag tag);
String readE rror(); void clearE rror(); }
10. M odbus.java package com.audy.droidscada.Driver; im port java.net.InetA ddress; im port java.net.UnknownH ostException; im port android.util.Log; im port im port im port im port
com.audy.droidscada.Constants; com.audy.droidscada.entities.Device; com .audy.droidscada.entities.Tag; com .audy.droidscada.util.C onverter;
im port net.wimpi.modbus.*; im port net.wimpi.modbus.msg.*; im port net.wimpi.modbus.io.*; im port net.wimpi.modbus.net.*; im port net.wim pi.m odbus.procim g.InputRegister; im port net.wimpi.modbus.procim g.Register; im port net.wimpi.m odbus.procimg.SimpleRegister; im port net.wim pi.m odbus.util.BitVector;
public class M odBus implem ents IDeviceDriver { /* The im portant instances of the classes mentioned before */ T C PM asterConnection con = null; //the connection M odbusTC PTransaction tra n s = null; //the transaction /* Variables for storing the param eters */ InetAddress addr = null; //the slave's
@ Override public String readE rror() { return errLog; }
@ Override public void clearE rror() { errL og = ""; isW orking = true; }
public ModBus(Device device) { _device = device; new Thread(new Runnable() { @ Override public void run() { int retry = _device.RetryTimes; Boolean isconnected = false; L og.d("C O R E ","device " + _device.ID + " Establishing Connection"); while (!isconnected & & retry > 0) { port=_device.Port; try { addr = InetAddress.getByName(_device.IPAddress); } catch (UnknownHostException e1) {
address e 1. print St ac kT r ace();
int port = M odbus.DEFAULT_PORT; int startA ddress, num Inputs; int slaveAddress; int registerType; Boolean isW orking = true; Device _device; String errL og = ""; @ Override public Boolean isD riverW ork() { return isW orking; }
}//("192.168.0.101"); con = new TCPM asterConnection(addr); con.setPort(port); con.setTimeout(_device.TimeOut); try { con.connect(); } catch (Exception e) {
136 { e.printStackTrace(); }
isconnected = con.isConnected(); if (!isconnected) { retry-- ; L og.d("C O R E ","device " + _device.ID + " Connection Tim eout retrying.."); } } if (isconnected) { isW orking = true; Log.d("C O R E ","device " + _device.ID+ " Connection Ready"); slaveAddress =_device.SlaveID; clearError(); } else { Log.d("C O R E ","device " + _device.ID + " Connection cannot be establis hed, turning off device"); } }).start();
public M odBus(String IP, int Port, int slaveID) { L og.d("C O R E ","C onnection C reated"); con = new T C PM asterC onnection(addr); con.setPort(port); con.setTimeout(1000); try { con.connect(); } catch (Exception e) { // TODO Auto generated catch block e.printStackTrace(); L og.d("C O R E ","C onnection Ready"); slaveAddress = slaveID; }
public void Stop() { con.close(); } @ Override public int[] R ead(Tag tag) { startA ddress = tag.RegisterAddress; if (tag.RegisterForm at == C onstants.R egisterForm at.Four_Bytes_Float.getC ode()) { num Inputs = 2; } else num Inputs = 1; } registerType = tag.RegisterType; return Read();
public int[] Read()
int[] inputs; inputs = new int[2]; try { if (registerType == Constants.RegisterType.Input_Registers.getCode( )) { //the request ReadInputR egistersR equest req = new R eadInputR egistersR equest(startA ddress, num Inputs); req.setUnitID(slaveAddress); tran s = new M odbusTC PTransaction(con); trans.setRequest(req); trans.execute(); //the response R eadInputR egistersR esponse res = (ReadInputRegistersResponse) trans.getResponse(); InputRegister[] ip=res.getRegisters(); for (int i = 0; i < ip.length; i++) { inputs[i] =ip[i].getValue(); } else if (registerType == Constants.RegisterType.O utput_Holdings.getCod e()) { //the request ReadM ultipleRegistersRequest req = new R eadM ultipleRegistersRequest(startA ddress, num Inputs); req.setUnitID(slaveAddress); tran s = new M odbusTC PTransaction(con); trans.setRequest(req); trans.execute(); //the response ReadM ultipleRegistersResponse res = (ReadM ultipleRegistersResponse) trans.getResponse(); InputRegister[] ip=res.getRegisters(); for (int i = 0; i < ip.length; i++) { inputs[i] =ip[i].getValue(); } else if (registerType == Constants.R egisterType.O utput_Coils.getCode()) { BitVector bv=new BitVector(1); //the request ReadCoilsRequest req = new R eadC oilsR equest(startA ddress, num Inputs); req.setUnitID(slaveAddress); tran s = new M odbusTC PTransaction(con); trans.setRequest(req); trans.execute(); //the response ReadCoilsResponse res = (ReadCoilsResponse) trans.getResponse(); bv =res.getCoils(); if(bv.getBit(0)){inputs= new int[]{1};} else{ inputs = new int[]{ 0 }; }
137 }
else if (registerType == Constants.RegisterType.Input_Contacts.getCode( )) { BitVector bv=new BitVector(1); //the request ReadInputD iscretesRequest req = new ReadInputD iscretesR equest(startA ddress, num Inputs); req.setUnitID(slaveAddress); trans = new M odbusTCPTransaction(con); trans.setRequest(req); trans.execute(); //the response ReadInputD iscretesResponse res = (ReadInputDiscretesResponse) trans.getResponse(); bv =res.getDiscretes(); if(bv.getBit(0)){inputs= new int[]{1};} else{ inputs = new int[]{ 0 }; } } } catch (M odbusIOException e) { e.printStackTrace(); } catch (M odbusSlaveException e) { e.printStackTrace(); } catch (M odbusException e) { isW orking = false; errL og = e.getMessage(); Log.d("C O R E ","Execute erro r"); e.printStackTrace(); } catch (Exception p) { isW orking = false; errLog = p.getMessage() ; } return inputs; } @ Override public Boolean W rite(Tag tag, String value) { startA ddress = tag.RegisterAddress; registerType = tag.RegisterType; if (tag.RegisterForm at == C onstants.R egisterForm at.Four_Bytes_Float.getC ode()) { num Inputs = 2; int[] intValue = C onverter.return2V alue(tag, value); return write(intValue); } else { num Inputs = 1; int intValue = C onverter.returnV alue(tag, value); return W rite(intValue); } } public Boolean W rite(int value) { Boolean stat = false; try {
if (registerType == Constants.RegisterType.O utput_Holdings.getCod e()) { R egister reg = new SimpleRegister(value); W riteSingleRegisterRequest req=new W riteSingleR egisterRequest(startA ddress, reg);
tran s = new M odbusTC PTransaction(con); trans.setRequest(req); trans.execute(); //the response W riteSingleRegisterResponse res = (W riteSingleRegisterResponse) trans.getResponse(); if( res.getFunctionCode() == 6 ) { stat = true; System. out.println( "T ransaction Success!" ); } else { stat=false;} //m aster.W riteSingleRegister(slaveAddress, startA ddress, value); } else if (registerType == Constants.R egisterType.O utput_Coils.getCode()) { Boolean coilvalue = (value == 1); W riteCoilRequest req=new W riteCoilRequest(startA ddress, coilvalue);
tran s = new M odbusTC PTransaction(con); trans.setRequest(req); trans.execute(); //the response W riteCoilResponse res = (W riteCoilResponse) trans.getResponse(); if( res.getFunctionCode() == 6 ) { stat = true; System. out.println( "T ransaction Success!" ); } else { stat=false;} } else { L og.d("C O R E ","w rite disabled for this tag " + _device.ID + "!"); } } catch (Exception e) { // TODO: handle exception L og.d("C O R E ","device " + _device.ID + " Disconnected!"); } finally {
138 //m aster. Dispose(); Log.d("C O RE","D isconnect W rite Device " + _device.ID); isW orking = false; } return stat; }
{ L og.d("C O R E ","w rite disabled for this tag " + _device.ID + "!"); } } catch (Exception e) { // TODO: handle exception L og.d("C O R E ","device " + _device.ID + " Disconnected!");
public Boolean write(int[] values) { Boolean stat = false; try { if (registerType == Constants.RegisterType.O utput_Holdings.getCod e()) {
} finally { //master. Dispose(); isW orking = false; } return stat;
//m aster.W riteM ultipleRegisters(slaveAddress, startA ddress, values); stat = true; } else
}
}
11. Device.java package com .audy.droidscada.entities;
public public public public
im port java.io.Serializable; im port java.util.List; im port java.util.UUID;
int int int int
DeviceProtocol ; Tim eOut ; RetryTim es ; SyncPeriod ;
public String Location ; @ S uppressW arnings("serial") public class Device implements Serializable{
//unused public String Longitude; public String Latitude; public String Area;
public List Tags; public UUID ID ; public long ProjectID ; public String Name; public String Detail;
public public public public
public public public public
public String toString() { return Name; }
String IPA ddress; int P o rt ; int SlaveID; Boolean Suspend;
String C reateD ate ; long CreateB y ; String M odifyDate ; long ModifyBy;
} public int DeviceDriver;
12. DevicelistObject.java public public public public public public
package com.audy.droidscada.entities; im port java.util.UUID; public class DeviceListObject { public UUID ID;
String Name; String ImageURL; String Value; String Unit; Object content; boolean isactive;
}
13. Scale.java public String max ; public String min;
package com.audy.droidscada.entities; public class Scale {
}
139 14. Tag.java package com .audy.droidscada.entities;
public int DecimalNumber;
im port java.io.Serializable; im port java.util.UUID;
public Boolean EnableStorage; public int StorageSampling;
@ S uppressW arnings("serial") public class Tag implements Serializable {
//hidden public String Asset; public String Type; public String Location; public String Group; public short StoragePeriod;
public UUID DeviceID ; public UUID ID; public String Name; public String Detail;
//unused public String CreateDate; public long CreateB y ; public String ModifyDate ; public long ModifyBy ; public String Unit ;
public int RegisterForm at; public int RegisterType; public int RegisterAddress; public Boolean EnableScaling ; public double MaxValue; public double MinValue ; }
15. TaglistO bject.java public public public public public public
package com.audy.droidscada.entities; im port java.util.UUID; public class TagListObject { public UUID ID; public String Name;
String ImageURL; String Device; String Value; String Unit; Tag content; boolean isactive;
}
16. TagV alue.java package com. audy.droidscad a. entities; public public public public
im port java.util.D ate; im port java.util.UUID;
public UUID ID; long rawvalue; double value; Date RecordD ate ; UUID TagID;
public class TagValue { }
17. W orker.java package com .audy.droidscada.entities; im port java.util.D ate; im port java.util.A rrayL ist; im port java.util.C alendar; im port java.util.H ashM ap; im port java.util.List; im port java.util.Tim er; im port java.util.Tim erTask; im port java.util.UUID;
im port com .audy.droidscada.util.C onverter; im port com.audy.droidscada.util.LocalDB; im port net.wimpi.m odbus.util.M odbusUtil; public class W orker { //Properties List tem pTag; String status; Tim er _tim er; Boolean _timerToggle; Boolean _timersaveToggle; Tim er _tim erSave; Device _device; List _tags; HashM ap LastTagSave; HashM ap>
im port android.content.Context; im port android.content.Intent; im port android.support.v4.content.LocalB roadcastM ana ger; im port android.util.Log; im port com.audy.droidscada.Constants; im port com .audy.droidscada.Driver.IDeviceDriver; im port com.audy.droidscada.Driver.M odBus; im port com .audy.droidscada.services.Core;
values; Boolean showlog; HashM ap> Data; int SavePeriod = 30000;
140 IDeviceDriver _D river; LocalDB db; LocalBroadcastM anager broadcaster; // ----------public Boolean updateR oundtrip(D evice newDevice) try {
{ if (!_device.Suspend) { status = R oundtrip_Status_R un; _D river = new ModBus(_device); if (_D river.isDriverW ork()) {
_device = ToggleTimer(true);
newDevice; Boolean togglestart = !_timerToggle; status = Roundtrip_Status_RefreshD evice; if (togglestart) { Start(); } retu rn true; catch(Exception p) { return false; }
//sendResult("device : " + _device.ID + W orking"); else Stop(); //DeviceController DC = DeviceController.getInstance; _device.Suspend = true;
public Boolean updateR oundtrip(List newTags)
//DC. updateDevice(_device, _device.ModifyBy);
try tem pTag =
Log.d("W A LK ER","device : " + _device.ID + " suspended");
newTags; status = R oundtrip_Status_R efresh; retu rn true; } catch(Exception p) { return false; } } public W orker(Device device, List tags, Boolean showLog,Context context) {
//sendResult("device : " + _device.ID + " suspendeda "+_Driver.isDriverW ork().toString()); sendResult(Constants.BC_NOT_W OR KING,_device.ID); } } else { Log.d("W A LK ER","device : " + _device.ID + " suspended from the start"); sendResult("device Suspended",_device.ID);}
broadcaster=LocalBroadcastM anager. getInstance(context);
private void ToggleTimer(Boolean toggle)
db=LocalDB.getInstance(context); LastTagSave = new HashM ap(); // ScriptEngine = new ScriptingEngine(tags); status = Roundtrip_Status_Ready; D ata = new HashM ap>(); tem pTag = new A rrayList(); //A lertD ata = new H ashM ap>(); _tags = tags; for (Tag tag : _tags)
_tim erToggle = toggle; _tim ersaveToggle = toggle; if(!toggle) { _timer.cancel(); _timerSave.cancel(); } else
_tim er.schedule(new Tim erTask() {
@ Override LastTagSave.put(tag.ID, Calendar.getInstance().getTim e()); } showlog = showLog; _device = device; _tim er = new Timer(); _tim erSave = new Timer();
public void run() { _tim er_Elapsed();
}, _device.S yncP eriod,_device.S yncP eriod);
public void Start()
141
_timerSave.schedule(new Tim erTask()
counter++; if (showlog)
{
@ Override public void run() { _timerSave_Elapsed();
L og.d("W A L K E R ","rountrip device : " + _device.ID + " counter:" + counter); } HashM ap tags = new HashM ap(); if (!_device.Suspend) for (Tag tg :
},SavePeriod,SavePeriod);
_tags) { try
} int[] data = _Driver.Read(tg); int counter = 0; int updater = 0; int updatelim it = 1;
// Log.d("W A LK E R ","reading :" + JsonConvert.SerializeObject(tg)); if (!_Driver.isDriverW ork())
public void Stop()
{
_timer.cancel(); _tim erSave.cancel();
if (_D river.readError().length() > 0)
if (status != Roundtrip_Status_Disconnected)
{ Roundtrip_Status_Stop; } else
L og.d("W A LK E R ","T ag " + tg.ID +" " +_device.SlaveID +" get Value erro r on " + _D river.readE rror()); Start();
} _D river.clearE rror(); protected void _tim er_Elapsed()
} else
if (status == R oundtrip_Status_R efresh)
{ _tags = tem pTag; for(Tag tag : _tags)
(!LastTagSave.containsKey(tag.ID)) { L astTagSave.put(tag.ID ,Calendar.getI nstance().getTime()); }
status Roundtrip_Status_D isconnected;
Log.d("W A LK ER","device " + _device.ID + " Disconnected!");
sendResult("device Disconnected!",tg.DeviceID);
tem pTag = new
Stop();
A rrayList(); status = R oundtrip_Status_R un; else if (status == Roundtrip_Status_RefreshD evice) { _D river = new M odBus(_device);//.IPAddress, _device.Port, _device.SlaveID); if (_D river.isDriverW ork()) { status R oundtrip_Status_R un; } else { Stop(); }
String rVal = ""; Date date =Calendar.getInstance().getTim e(); if (data.length > 1) { rVal=String.valueOf( M odbusUtil.m akeW ord(data[0],data[1]));
142
}
updater++; else { rVal = String.valueO f(data[0]); } S tring val = Converter.getValue(tg, rVal); // string serializedData=JsonConvert.SerializeObject(new CloudC ore.SightG ateC EEntities.Packet { Value = val, RealValue = rVal, Alerts = A lerts });
protected void _tim erSave_Elapsed() if (status R oundtrip_Status_R un)
//tags.Add(tg.TagID, serializedData); (!_device.Suspend) //Save tag value to send via signalR SavetoDB(); tags.put(tg.ID, val);
//check interval and save to database if valid sam pling rate
private void SaveToM em ory(Tag tag, String val, String rval, Date date)
//C alendar cal=C alendar.getInstance(); //cal.setTime(LastTagSave.get(tg.ID)); //cal. add(C alend ar. M ILLISECOND, tg.StorageSampling); long d1=date.getTime();
if (!Data.containsKey(tag.ID)) Data.put(tag.ID , new ArrayList()); } TagValue tv=new TagValue();
long d2=LastTagSave.get(tg.ID).getTime(); long diff= d1-d2; if(diff >tg.StorageSampling) {
SaveToMemory(tg, val, rVal,
date);
tv.ID=UUID.randomUUID(); tv.RecordD ate = date; tv.value = Double. parseDouble(val); tv.raw value = Long.parseLong(rval); tv.TagID=tag.ID; Data.get(tag.ID).add(tv);
} } if (showlog) private void updateValues(HashM ap tags)
{ L og.d("W A LK E R ","T ag " + tg.Name + " (" + tg.ID + ") R Address:" + tg.RegisterA ddress + " get Value :" + String.valueOf(data[0]));
if (showlog)
Log.d("W A LK E R ","pushing d a ta to UI");
} catch (Exception p) { L og.d("W A LK E R ","T ag " + tg.ID + " get Value failed" + p.getMessage()); //sendR esult("Tag " + tg.ID + " get Value failed" + p.getMessage()); } if (updater == updatelim it)
sendData(tags);
//result sender public void sendResult(String message,UUID DeviceI D) { Intent intent = new Intent(Core.CORE_RESU LT); if(message != null)
{ intent.putExtra(Core.CO R E_M ESSA G E, message);
updateValues(tags); tags = new HashM ap(); updater
intent.putExtra(Constants.ID _D EV IC EID, DeviceID.toString());
= 0;
} else
broadcaster.sendBroadcast(intent);
143
public void sendData(HashM ap data) { Intent intent = new Intent(Core.CORE_RESU LT); if(data != null)
L og.d("C oreW alker", "Saving to DB Com pleted"); } else{ L og.d("C oreW alker", "Saving to DB failed");
intent.putExtra(Core.CO R E_M ESSA G E,"DATA");
} //release all used memory in values
intent.putExtra(Core.CO R E_D A TA ,da
values=new HashM ap>() ;
broadcaster.sendBroadcast(intent); }
} // constants final private String R oundtrip_Status_R un = "ru n "; final private String R oundtrip_Status_R efresh = "refresh"; final private String Roundtrip_Status_RefreshD evice = "refreshDevice"; final private String R oundtrip_Status_R eady = "ready"; final private String Roundtrip_Status_Stop = "stop"; final private String R oundtrip_Status_D isconnected = "disconnected"; // --------------
ta);
private void SavetoDB() { //clearup memory values=Data; Data=new HashM ap>(); //S tart saving data to database L og.d("C oreW alker", "Saving to DB"); boolean stat=db.bulkInsertTagValue(values); if(stat){
}
18. C ore.java package com.audy.droidscada.services; im port im port im port im port im port im port im port
java.util.A rrayL ist; java.util.H ashM ap; java.util.M ap; com .audy.droidscada.entities.W orker; com.audy.droidscada.entities.Device; com .audy.droidscada.entities.Tag; com.audy.droidscada.util.LocalDB;
im port im port im port im port im port
android.app.Service; android.content.Intent; android.os.Binder; android.os.IBinder; android.util.Log;
public class Core extends Service{ static final public String CORE_M ESSAGE="m essage"; static final public String CORE_RESULT = "com. audy.droidscada.core.REQU EST_PROCES SED"; static final public String CORE_DATA = "DATA"; // Binder given to clients private final IBinder m Binder = new LocalBinder();
} } ArrayList Devices; public M ap<String, W orker> R oundT rips; public void stopService(){stopSCADA();} public void updateDevice(){} public void updateTag(){} protected void setupSCADA() { //initialize R ountrips LocalDB db= LocalDB.getInstance(this); Devices =db.getDevices(); R oundT rips = new HashM ap<String, W orker>(); for (int i = 0; i < Devices.size(); i++) { ArrayList tags=db.getTagsByDevice(Devices.get(i).ID); W orker trip = new W orker(Devices.get(i), tags, false,this);//true for displaying current tag value RoundTrips.put(String.valueOf(Device s.get(i).ID), trip); } }
public class LocalBinder extends Binder { public Core getService() { // R eturn this instance of LocalService so clients can call public methods retu rn Core.this;
protected void runSCADA() { for(W orker corewalker : RoundTrips.values()) {
144
corew alker.Start(); } /* Iterator<E ntry< S tring, CoreW alker>> it = R oundT rips.entrySet().iterator(); while (it. hasNext()) { M ap.E ntry pairs = it.next(); ((CoreW alker) pairs.getValue()).Start(); //it.remove(); // avoids a ConcurrentM odificationException */ } protected void stopSCADA()
@ O verride public IB inder onBind(Intent arg0) { // TODO Auto-generated m ethod stub retu rn mBinder; } @ O verride public int onStartC om m and(Intent intent, int flags, int startId) { // TODO Auto-generated m ethod stub L og.d("C O R E ", "S tarting up"); new T hread(new Runnable() { @ O verride public void run() {
for(W orker corewalker :
setupSCADA();
{
runSCADA();
RoundTrips.values()) corewalker.Stop(); }).start(); retu rn START_STICKY; /* Iterator<E ntry< S tring, CoreW alker>> it = R oundT rips.entrySet().iterator(); while (it. hasNext()) { M ap.Entry pairs = it.next();
} @ O verride public void onCreate() { super.onC reate(); }
((CoreW alker) pairs.getValue()).Stop();
@ O verride public void onDestroy() { stopSCADA(); super.onDestroy(); }
//it.remove(); // avoids a ConcurrentM odificationException
19. C onverter.java package com .audy.droidscada.util; im port java.nio.ByteBuffer; im port java.text.D ecim alForm at; im port java.text.N um berForm at; im port com.audy.droidscada.Constants; im port com.audy.droidscada.entities.Scale; im port com .audy.droidscada.entities.Tag;
retu rn scale;} case Four_Bytes_Unsigned_Integer: { scale.max = "4294967295";//UInt32.M axValue.ToString(); scale. min = "0";//UInt32.M inValue.ToString(); retu rn scale;} case Two_Bytes_Discrete: { scale.max = "1";scale.m in
public class C onverter { = "0" public static Scale getRegisterForm atRange(C onstants.RegisterFor m at format) { Scale scale= new Scale(); switch (form at) { case Four_Bytes_Float: { scale.max =String.valueOf(Float.M AX_VALUE); scale.min =String.valueOf(Float.M IN_VALUE); retu rn scale;} case Four_Bytes_Integer: { scale.max = String.valueOf(Integer.M AX_VALUE); scale.min =String.valueOf(Integer.M IN_VALUE);
retu rn scale;} case Two_Bytes_Integer: { scale.max =String.valueOf(Short.M AX_VALUE); scale. min =String.valueOf(Short.M IN_VALUE); retu rn scale;} default: { scale.max = "65535";//UInt16.M axValue.ToString(); scale. min = "0";//UInt16.M inValue.ToString(); retu rn scale;} } public static String getValue(Tag tag, String value) if (tag.EnableScaling)
145 double
{ Scale scale = Converter.getRegisterForm atRange(String.value Of( Constants.R egisterForm at.get(tag.RegisterForm a t))); double scaling = 0; double result = 0; if (tag.RegisterForm at > 2) { double CVal = Double.parseDouble(value); double range1 = Double.parseDouble(scale.min); double range2 = Double.parseDouble(scale.max); scaling = (range2 - range1) / (tag.MaxValue tag.M inValue); result = tag.M inValue + (CVal - range1) / scaling; } else { double CVal = Double.parseDouble(value); float range1 = Float.parseFloat(scale.m in); float range2 = Float.parseFloat(scale.max); scaling = (range2 - range1) / (tag.MaxValue tag.M inValue); result = tag.M inValue + (CVal - range1) / scaling; } StringB uilder sb = new StringBuilder(); //sb.append("{0:0."); sb.append("0"); for (int i = 0; i < tag.Decim alNumber; i++) { if(i==0) {sb.append(".0");} else{ sb.append("0"); }} // sb.append("}"); N um berForm at form atter = new Decim alForm at(sb.toString()); return form atter.form at(result); } else { return value; } } public static int returnV alue(T ag tag, String value) { if (tag.EnableScaling) { Scale scale = getRegisterForm atRange(String.valueOf( tag.RegisterForm at)); double scaling = 0; double result = 0; if (tag.RegisterForm at > 2) {
CVal =Double.parseDouble(value); double range1 =Double.parseDouble(scale.min); double range2 = Double.parseDouble(scale.max); scaling = (tag.MaxValue - tag.M inValue) / (range2 range1); result = tag.M inValue + (CVal - range1) / scaling; } else { double CVal = Double.parseDouble( value); float range1 = Float.parseFloat(scale.m in); float range2 = Float.parseFloat(scale.max); scaling = (tag.MaxValue - tag.M inValue) / (range2 range1); result = tag.M inValue + (CVal - range1) / scaling; } retu rn convertToInt(result); } else { return convertToInt(value); } } public static int[] return2V alue(Tag tag, String value) { double finale; if (tag.EnableScaling) { Scale scale = getRegisterForm atRange(String.valueOf(tag.Regi sterForm at)); double scaling = 0; double result = 0; if (tag.R egisterForm at > 2) { double CVal = Double.parseDouble(value); double range1 = Double.parseDouble(scale.min); double range2 = Double.parseDouble(scale.max); scaling = (tag.MaxValue - tag.M inValue) / (range2 range1); result = tag.M inValue + (CVal - range1) / scaling; } else { double CVal = Double.parseDouble(value); float range1 = Float.parseFloat(scale.m in); float range2 =Float.parseFloat(scale.m ax); scaling = (tag.MaxValue - tag.M inValue) / (range2 range1); result = tag.M inValue + (CVal - range1) / scaling; } finale = result; }
146 else { finale =Double.parseDouble(value); } byte[] bytes = toByteA rray(M ath.floor(finale)); int upper =ByteBuffer.wrap(new byte[]{ bytes[0]}).getInt(); int lower = ByteBuffer.wrap(new byte[]{ bytes[1]}).getInt(); int[] data = new int[2]; data[0] = upper; data[1] = lower; retu rn data; } public static byte[] toByteArray(double value) { byte[] bytes = new byte[8]; ByteBuffer.wrap(bytes).putDouble(val ue); retu rn bytes; }
private static int convertToInt(String value) { try { return Integer.parseInt(value); } catch(Exception p) { return 0; } } public static long getLong(String value) { try { return Integer.parseInt(value); } catch(Exception p) { return 0; } } public static C onstants.R egisterForm at ParseR egisterForm at(String data) { return C onstants.R egisterForm at.valueO f(data);
public static double toDouble(byte[] bytes) { return ByteBuffer.wrap(bytes).getDouble();
private static int convertToInt(double result)
public static Scale getRegisterForm atRange(String RegisterForm at) return getR egisterForm atR ange(ParseR egisterForm at(R egisterForm at));
retu rn (int) (M ath.floor(result));
20. CSV.java package com .audy.droidscada.util; im port java.io.File; im port java.io.FileW riter; im port java.io.IOException; im port java.text. SimpleDateFormat; im port java.util.C alendar; im port im port im port im port im port
android.annotation.SuppressLint; android.content.Context; android.database.C ursor; android.os.Environm ent; android.util.Log;
} String currentD ate= new Sim pleDateForm at("dd_M M _yyyy_hhm mss_SSS ").form at(Calendar.getInstance().getTim e()); File file = new File(exportDir, filenam e+currentDate+csvForm at); try { file.createNewFile(); CSV W riter csvW rite = new CSVW riter(new FileW riter(file)); //orm lite core
im port com.opencsv.CSVW riter;
method
@ S uppressLint("Sim pleD ateForm at") public class CSV {
C ursor c=LocalDB.getInstance(_context).getRawTagValu es();
Context _context; public CSV(Context context) { _context=context; } String filenam e="TA G Export"; String csvForm at=".csv"; public int ExportTagValue() { int counter=0; File exportD ir = new File(Environm ent.getExternalStorageDirectory(), ""); if (!exportDir.exists()) { exportD ir.m kdirs();
// this is the Column of the table and same for H eader of CSV file String header[] = {"ID ","T agID ", "V alue", "R aw V alue", "RecordD ate"}; Sim pleDateForm at sdf=new Sim pleDateForm at("dd-M M -yyyy hh:m m:ss.SSS"); if (c != null ) { if (c.moveToFirst()) { csvW rite.writeNext(header); do {
147
String datee=sdf.form at(c.getLong(c.getColum nIndex(" RecordDate")));
datee}; csvW rite.writeNext(row); counter++;
String row[] ={
}while (c.moveToNext()); csvWrite.close(); c. getString(c. getColum nIndex(” ID ”)),
} } retu rn counter; } catch (IOException e){
c. getString(c. getColum nIndex(” TagID ”)),
Log.e(”M ainActivity” , e.getMessage(), c.getString(c.getColum nIndex(” Value”
e); retu rn counter; }
c.getString(c.getColum nIndex(” RawVa
}
lue”)),
21. LocalDB.java package com .audy.droidscada.util;
cv.put(”ID ” , newDevice.ID.toString());
im port java.util.A rrayL ist; im port java.util.D ate; im port java.util.H ashM ap; im port java.util.List; im port java.util.UUID;
cv.put(” Name” newDevice.Name); cv.put(”Detail” newDevice.Detail);
im port com.audy.droidscada.entities.Device; im port com .audy.droidscada.entities.Tag; im port com .audy.droidscada.entities.TagValue; im port android.annotation.SuppressLint; im port android.content.ContentValues; im port android.content.Context; im port android.database.C ursor; im port android.database.sqlite.SQ LiteD atabase; im port android.database.sqlite.SQ LiteO penH elper; im port android.util.Log;
cv.put(” DeviceDriver” , newDevice.DeviceDriver); cv.put(” DeviceProtocol” newDevice.DeviceProtocol); cv.put(” IPA ddress” , newDevice.IPAddress); cv.put(”P o rt” , newDevice.Port); cv.put(” SlaveID” , newDevice.SlaveID); cv.put(” Suspend” newDevice.Suspend);
@ SuppressLint(” Sim pleD ateForm at”) public class LocalDB extends SQLiteO penHelper
//File f = context. getDat abasePath(d bName); //long dbSize = f.length(); public String errL og= ” ” ; //Device section public boolean deleteDevice(UUID ID) { SQLiteDatabase db=this.getW ritableDatabase(); return db.delete(TABLE_NAM E_DEVICE, ” ID ='” + ID.toString()+....., null) > 0;
cv.put(”T im eO ut” , newDevice.TimeOut); cv.put(” R etryTim es” , newDevice.RetryTimes); cv.put(” SyncPeriod” , newDevice. SyncPeriod); cv.put(” Location” , newDevice.Location); cv.put(”P rojectID ” , newDevice.ProjectID); db.insert(TABLE_NAM E_DEVICE, ” ID ” ,cv); db.close(); retu rn true; } catch (Exception e) {
public boolean insertDevice(Device newDevice) try { SQLiteDatabase
errLog=e.getM essage(); retu rn false;
ContentValues
}
db=this.getW ritableDatabase(); cv=new ContentValues();
}
148 public boolean updateDevice(Device newDevice)
device.DeviceDriver= c.getInt(c.getColum nIndex("DeviceDriver"));
try { SQLiteDatabase db=this.getW ritableDatabase();
device.DeviceProtocol= c.getInt(c.getColum nIndex("DeviceProtocol"));
ContentValues cv=new ContentValues(); cv.put("N am e",
device.IPAddress= c.getString(c.getC olum nIndex("IPA ddress"));
newDevice.Name); newDevice.Detail);
device.Port= c.getInt(c.getC olum nIndex("Port"));
cv.put("DeviceDriver", newDevice.DeviceDriver);
device.SlaveID= c.getInt(c.getColum nIndex("SlaveID"));
cv.put("DeviceProtocol", newDevice.DeviceProtocol);
device.TimeOut= c.getInt(c.getC olum nIndex("Tim eO ut"));
cv.put("IPA ddress", newDevice.IPAddress);
device.Suspend= (c.getInt(c.getColum nIndex("Suspend"))==1);
cv. put("D etail",
cv.put("P ort", newDevice.Port); cv.put("SlaveID ",
device.RetryTimes= c.getInt(c.getC olum nIndex("R etryTim es"));
newDevice.SlaveID); newDevice.Suspend);
device.SyncPeriod= c.getInt(c.getColum nIndex("SyncPeriod"));
cv.put("Tim eO ut", newDevice.TimeOut);
device.Location= c.getString(c.getColum nIndex("Location"));
cv.put("Suspend",
cv.put("R etryTim es", newDevice.RetryTimes);
devices.add(device); }while (c.moveToNext());
cv.put("SyncPeriod", newDevice.SyncPeriod); droidDB.close(); retu rn devices;
cv.put("Location", newDevice.Location); db.update(TABLE_NAM E_DEVICE,c v, "ID ='"+new D evice.ID .toString()+"'",null); db.close(); retu rn true; } catch (Exception e) { retu rn false; } } public A rrayList getDevices() { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery("SELEC T ID,Name,Detail,DeviceDriver,DeviceProtocol,IPA ddress,Port,SlaveID,Tim eOut,Suspend,Location,S yncPeriod,RetryTim es from device", null); ArrayList devices=new ArrayList(); if (c != null ) { if (c.moveToFirst()) { do {
public Device getDevicebyID(UUID ID) { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery("SELEC T ID,Name,Detail,DeviceDriver,DeviceProtocol,IPA ddress,Port,SlaveID,Tim eOut,Suspend,Location,S yncPeriod,RetryTim es from device where ID = '"+ID .toString()+"'", null); Device device=new Device(); if (c != null ) { if (c.moveToFirst()) {
device.ID=UUID.fromString( c.getString(c.getColum nIndex("ID"))); device.Name= c.getString(c.getColum nIndex("Nam e")); device.Detail= c.getString(c.getColumnIndex("Detail"));
Device device=new Device(); device.ID=UUID.fromString( c.getString(c.getColum nIndex("ID"))); device.Name= c.getString(c.getColumnIndex("Nam e")); device.Detail= c.getString(c.getColumnIndex("Detail"));
device.DeviceDriver= c.getInt(c.getColum nIndex("DeviceDriver")); device.DeviceProtocol= c.getInt(c.getColum nIndex("DeviceProtocol")); device.IPAddress= c.getString(c.getC olum nIndex("IPA ddress"));
149
device.Port= c.getInt(c.getC olum nIndex("Port"));
cv.put("M inV alue", newTag.MinValue);
device.SlaveID= c.getInt(c.getColum nIndex("SlaveID"));
cv.put("D ecim alN um ber", newTag.DecimalNumber); cv.put("A sset", newTag.Asset); cv.put("Type", newTag.Type);
device.TimeOut= c.getInt(c.getC olum nIndex("Tim eO ut")); device.Suspend= (c.getInt(c.getColum nIndex("Suspend"))==1); device.RetryTimes= c.getInt(c.getC olum nIndex("R etryTim es")); device.SyncPeriod= c.getInt(c.getColum nIndex("SyncPeriod")); device.Location= c.getString(c.getColum nIndex("Location"));
else{device.Name="nothing";}
cv.put("Location", newTag.Location); cv.put("[G roup]" newTag.Group); cv.put("EnableStorage", newTag.EnableStorage); cv.put("StoragePeriod", newTag.StoragePeriod); cv.put("StorageSam pling", newTag.StorageSampling); cv.put("U nit", newTag.Unit); db.insert(TABLE_NAM E_TAG,
else{device.Name="nothing";} droidDB.close(); retu rn device; } //Tag section public boolean deleteTag(UUID ID) { SQLiteDatabase db=this.getW ritableDatabase(); return db.delete(TABLE_NAM E_TAG, "ID = '" + ID .toString()+"'", null) > 0;
"ID",cv); db.close(); retu rn true; } catch (Exception e) { errLog=e.getM essage(); retu rn false; } } public boolean updateTag(Tag newTag) try { SQLiteDatabase
public boolean insertTag(Tag newTag) { try { SQLiteDatabase db=this.getW ritableDatabase();; ContentValues cv=new ContentValues();
db=this.getW ritableDatabase();; ContentValues cv=new ContentValues(); cv.put("ID ", newTag.ID.toString()); cv.put("DeviceID", newTag.DeviceID.toString());
cv.put("ID ",
cv.put("N am e",
newTag.ID.toString());
newTag.Name);
cv.put("DeviceID", newTag.DeviceID.toString());
newTag.Detail);
cv.put("D etail",
cv.put("N am e", newTag.Name);
cv.put("R egisterForm at", newTag.RegisterForm at);
cv. put("D etail", newTag.Detail); cv.put("R egisterForm at", newTag.RegisterForm at); cv.put("RegisterType", newTag.RegisterType); cv.put("RegisterA ddress", newTag.RegisterAddress); cv.put("EnableScaling", newTag.EnableScaling); cv.put("M axV alue", newTag.MaxValue);
cv.put("RegisterType", newTag.RegisterType); cv.put("RegisterA ddress", newTag.RegisterAddress); cv.put("EnableScaling", newTag.EnableScaling); cv.put("M axV alue", newTag.MaxValue); cv.put("M inV alue", newTag.MinValue); cv.put("D ecim alN um ber", newTag.DecimalNumber);
150 cv.put(” Asset”, newTag.Asset);
(c.getInt(c.getColum nIndex(” EnableScaling”))== 1);
cv.put(”T ype” , newTag.Type);
tag.M axValue= c.getInt(c.getColum nIndex(” M axV alue”));
cv.put(”L ocation”, newTag.Location); cv. put(” [G roup]” , newT ag. Group);
tag.M inValue= c.getInt(c.getColum nIndex(” M inValue”));
cv.put(”E nableStorage” , newTag.EnableStorage);
tag.Decim alNumber= c.getInt(c.getColum nIndex(” Decim alNum ber”));;
cv.put(” S toragePeriod” , newTag.StoragePeriod);
tag.Asset= c.getString(c.getColumnIndex(” Asset”));
cv.put(” StorageSam pling” , newTag.StorageSampling); cv.put(” U nit” , newTag.Unit); db.update(TABLE_NAM E_TAG,cv, ” ID = '”+newTag.ID .toString()+.....,null); db.close(); retu rn true; } catch (Exception e) { retu rn false; } }
tag.Type= c.getString(c.getColumnIndex(”T ype”));
public A rrayL ist getTags() { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery(” SELECT ID,DeviceID,Name,Detail,RegisterFormat,Registe rT ype,” +
tag.Location= c.getString(c.getColumnIndex(” Location”)); tag.G roup= c.getString(c.getColumnIndex(” G roup”)); tag.EnableStorage=(c.getInt(c.getColu m nIndex(” E nableStorage”))==0); tag.StoragePeriod= (short) c. getInt(c. getColum nIndex(” StoragePeriod”)); tag.StorageSam pling= (short) c.getInt(c.getColum nIndex(” StorageSam pling”)); tag.Unit= c.getString(c.getColumnIndex(” U nit”)); tags.add(tag);
” RegisterAddress,EnableScaling,M axV alue,M inValue,DecimalNumber,Asset,Type,Locat
” [G roup],EnableStorage,StoragePeriod ,StorageSam pling,Unit from ta g ” , null); A rrayL ist tags=new A rrayList(); if (c != null ) { if (c.moveToFirst()) { do { Tag tag=new Tag(); tag.ID=UUID.from String( c.getString(c.getColumnIndex(” ID ”))); tag.DeviceID=UUID.fromString( c.getString(c.getColumnIndex(” DeviceID”))); tag.Name= c.getString(c.getColumnIndex(” Nam e”)); tag.Detail= c.getString(c.getColumnIndex(” D etail”)); tag.RegisterForm at= c.getInt(c.getColum nIndex(”R egisterForm at”)); tag.RegisterType= c.getInt(c.getColum nIndex(”RegisterType”)); tag.RegisterAddress= c.getInt(c.getColum nIndex(”RegisterA ddress”)); tag.EnableScaling=
}while (c.moveToNext());
droidDB.close(); retu rn tags; } public A rrayL ist getTagsByDevice(UUID DeviceID) { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery(” SELECT ID,DeviceID,Name,Detail,RegisterFormat,Registe rT ype,” + ”RegisterAddress,EnableScaling,M axV alue,M inValue,DecimalNumber,Asset,Type,Locat
” [G roup],EnableStorage,StoragePeriod ,StorageSam pling,Unit from tag where DeviceID='”+DeviceID.toString()+....., null); A rrayL ist tags=new A rrayList(); if (c != null ) { if (c.moveToFirst()) { do { Tag tag=new Tag(); tag.ID=UUID.from String( c.getString(c.getColumnIndex(” ID ”))); tag.DeviceID=UUID.fromString( c.getString(c.getColumnIndex(” DeviceID”)));
151
tag.Name= c.getString(c.getColumnIndex("Nam e")); tag.Detail= c.getString(c.getColumnIndex("Detail")); tag.RegisterForm at= c.getInt(c.getC olum nIndex("R egisterForm at"));
"[G roup],EnableStorage,StoragePeriod ,StorageSam pling,Unit from tag where ID ='"+ID .toString(), null); Tag tag=new Tag(); if (c != null ) { if (c.moveToFirst()) {
tag.RegisterType= c.getInt(c.getColum nIndex("RegisterType"));
tag.ID=UUID.from String( c.getString(c.getColum nIndex("ID")));
tag.RegisterAddress= c.getInt(c.getC olum nIndex("R egisterA ddress"));
tag.DeviceID=UUID.fromString( c.getString(c.getColumnIndex("DeviceID")));
tag.EnableScaling= (c.getInt(c.getColum nIndex("EnableScaling"))== 1);
tag.Name= c.getString(c.getColum nIndex("Nam e"));
tag.M axValue= c.getInt(c.getColum nIndex("M axValue"));
tag.Detail= c.getString(c.getColumnIndex("Detail")); tag.R egisterForm at= c.getInt(c.getC olum nIndex("R egisterForm at"));
tag.M inValue= c.getInt(c.getColum nIndex("M inValue")); tag.Decim alNumber= c.getInt(c.getC olum nIndex("D ecim alN um ber"));;
tag.RegisterType= c.getInt(c.getColum nIndex("RegisterType")); tag.RegisterAddress= c.getInt(c.getC olum nIndex("R egisterA ddress"));
tag.Asset= c.getString(c.getColumnIndex("Asset")); tag.Type= c.getString(c.getColum nIndex("Type"));
tag.EnableScaling= (c.getInt(c.getColum nIndex("EnableScaling"))== 1);
tag.Location= c.getString(c.getColum nIndex("Location"));
tag.M axValue= c.getInt(c.getColum nIndex("M axValue"));
tag.G roup= c.getString(c.getC olum nIndex("G roup"));
tag.M inValue= c.getInt(c.getColum nIndex("M inValue"));
tag.EnableStorage=(c.getInt(c.getColu m nIndex("EnableStorage"))==0);
tag.Decim alNumber= c.getInt(c.getC olum nIndex("D ecim alN um ber"));;
tag.StoragePeriod= (short) c.getInt(c.getC olum nIndex("StoragePeriod"));
tag.Asset= c.getString(c.getColumnIndex("Asset"));
tag.StorageSam pling= (short) c.getInt(c.getColum nIndex("StorageSam pling"));
tag.Type= c.getString(c.getColum nIndex("Type"));
tag.Unit= c.getString(c.getColum nIndex("Unit"));
tag.Location= c.getString(c.getColum nIndex("Location"));
tags.add(tag); }while
tag.G roup= c.getString(c.getC olum nIndex("G roup"));
(c.moveToNext()); } } droidDB.close(); retu rn tags; } public Tag getTagbyID(UUID ID) { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery("SELEC T ID,DeviceID,Name,Detail,RegisterFormat,Registe rType," + "RegisterAddress,EnableScaling,M axV alue,M inValue,DecimalNumber,Asset,Type,Locat ion," +
tag.EnableStorage=(c.getInt(c.getColu m nIndex("EnableStorage"))==0); tag.StoragePeriod= (short) c.getInt(c.getC olum nIndex("StoragePeriod")); tag.StorageSam pling= (short) c.getInt(c.getColum nIndex("StorageSam pling")); tag.Unit= c.getString(c.getColumnIndex("Unit")); } else{tag.Name="nothing";} } else{tag.Name="nothing";} droidDB.close(); retu rn tag; }
152 SQLiteDatabase db=this.getW ritableDatabase(); //TagValue Section public boolean deleteTagValue(UUID
ContentValues cv=new ContentValues();
ID) cv.put("ID ",
{ SQLiteDatabase db=this.getW ritableDatabase(); return db.delete(TABLE_NAM E_TAGVALUE, "ID ='" + ID .toString()+"'", null) > 0;
newTagValue.ID.toString()); cv.put("TagID ", newTagValue.TagID.toString()); cv.put("V alue", newTagValue.value); cv.put("Raw V alue", newTagValue.rawvalue);
public boolean bulkInsertTagValue(HashM ap> tagValues) { SQLiteDatabase db=this.getW ritableDatabase(); try
long data=newTagValue.RecordDate.getTime(); cv.put("R ecordD ate",data );
db.insert(TABLE_NAM E_TAGVALU E, "ID",cv); db.close(); retu rn true; } catch (Exception e) {
db.beginTransaction(); for(List tgv : tagValues.values()){ for(TagValue tv : tgv) { ContentValues cv=new ContentValues();
errLog=e.getM essage(); retu rn false; } } public boolean updateTagValue(TagValue newTagValue)
cv.put("ID ", tv.ID.toString()); try { cv.put("TagID ", tv.TagID.toString());
SQLiteDatabase db=this.getW ritableDatabase();
cv.put("V alue", tv.value);
ContentValues cv=new ContentValues();
cv.put("Raw V alue", tv.rawvalue); cv.put("ID ", newTagValue.ID.toString()); long data=tv.RecordDate.getTim e(); cv.put("R ecordD ate",data ); if(db.insert(TABLE_NAM E_TAGVAL UE, "ID",cv)<0){
cv.put("TagID ", newTagValue.TagID.toString()); cv.put("V alue", newTagValue.value); cv.put("Raw V alue", newTagValue.rawvalue);
throw new E xception("gagal");
cv.put("R ecordD ate", newTagValue.RecordDate.getTime());
} db.setTransactionSuccessful(); retu rn true; } catch (Exception e) { errLog=e.getM essage(); retu rn false; } finally { db.endTransaction(); } } public boolean insertTagValue(TagValue newTagValue) { try {
db.update(TABLE_NAM E_TAG,cv, "ID ='"+new T agV alue.ID .toString()+"'",null); db.close(); retu rn true; } catch (Exception e) { retu rn false; } }
public C ursor getRawTagValues() { SQ LiteD atabase droidDB = this.getReadableDatabase(); return droidD B .raw Q uery("SELEC T ID,TagID,Value,RawValue,RecordDate from tagvalue", null); }
153 public A rrayList getTagValues() { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery(” SELECT ID,TagID,Value,RawValue,RecordDate from tagvalue” , null); A rrayList tagvalues=new ArrayList(); if (c != null ) { if (c.moveToFirst()) { do {
tag.Detail= c.getString(c.getColumnIndex(” D etail”)); tag.R egisterForm at= c.getInt(c.getColum nIndex(” R egisterForm at”)); tag.RegisterType= c.getInt(c.getColum nIndex(” RegisterType”)); tag.RegisterAddress= c.getInt(c.getColum nIndex(” RegisterA ddress”)); tag.EnableScaling= (c.getInt(c.getColum nIndex(” EnableScaling”))== 0);
TagValue tagvalue=new TagValue(); tag.M axValue= c.getInt(c.getColum nIndex(” M axV alue”));
tagvalue.ID=UUID.from String( c.getString(c.getColumnIndex(” ID ”))); tagvalue.TagID =UUID.from String( c.getString(c.getColumnIndex(”T agID ”)));
tag.M inValue= c.getInt(c.getColum nIndex(” M inValue”)); tag.Decim alNumber= c.getInt(c.getColum nIndex(” Decim alNum ber”));;
tagvalue.value= c.getFloat(c.getColum nIndex(” Value”)); tagvalue.rawvalue= c.getLong(c.getColumnIndex(” Raw V alue”)); tagvalue.RecordD ate= new D ate(c.getLong(c.getColumnIndex(” R ecordD ate” )));
tag.Asset= c.getString(c.getColumnIndex(” Asset”)); tag.Type= c.getString(c.getColumnIndex(”T ype”)); tag.Location= c.getString(c.getColumnIndex(” Location”));
tagvalues.add(tagvalue); }while (c. moveT oNext()); } } droidDB.close(); retu rn tagvalues; }
tag.G roup= c.getString(c.getColumnIndex(” G roup”)); tag.EnableStorage=(c.getInt(c.getColu m nIndex(” E nableStorage”))==0); tag.StoragePeriod= (short) c. getInt(c. getColum nIndex(” StoragePeriod”));
public Tag getTagValuebyID(UUID ID) { SQ LiteD atabase droidDB = this.getReadableDatabase(); C ursor c = droidD B .raw Q uery(” SELECT ID,DeviceID,Name,Detail,RegisterFormat,Registe rT ype,” + ” RegisterAddress,EnableScaling,M axV alue,M inValue,DecimalNumber,Asset,Type,Locat ion,” + ” [G roup],EnableStorage,StoragePeriod ,StorageSam pling from tag where ID ='”+ID.toString(), null); Tag tag=new Tag(); if (c != null ) { if (c.moveToFirst()) {
tag.ID=UUID.from String( c.getString(c.getColumnIndex(” ID ”))); tag.DeviceID=UUID.fromString( c.getString(c.getColumnIndex(” DeviceID”))); tag.Name= c.getString(c.getColumnIndex(” Nam e”));
tag.StorageSam pling= (short) c.getInt(c.getColum nIndex(” StorageSam pling”)); } else{tag.Name=” nothing” ;} } else{tag.Name=” nothing” ;} droidDB.close(); retu rn tag; } private static LocalDB instance=null; private static final String DATABASE_NAME = ” DroidScadaLocalDB.db” ; private static final int DATABASE_VERSION = 1; private LocalDB(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } public static LocalDB getInstance(Context ctx) { if(instance==null) { instance=new LocalDB(ctx);
154 } retu rn instance; }
@ Override public void onCreate(SQ LiteD atabase database) { addDB(database); } @ Override public void onUpgrade(SQ LiteD atabase db, int oldVersion, int newVersion) { Log.w(LocalDB.class.getName(), "U pgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); if (oldVersion == 1 && newVersion == 2) { //use this when need to upgrade database } } public void removeDB(SQLiteDatabase db) { db.execSQL("DROP TABLE IF EXISTS tag"); db.execSQL("DROP TABLE IF EXISTS device"); db.execSQL("DROP TABLE IF EXISTS tagvalue"); } public void addDB(SQLiteDatabase db) { db.execSQL(TABLE_DEVICE_CREA TE); db.execSQL(TABLE_TAG_CREATE);
db.execSQL(TABLE_TAGVALUE_C REATE); } private static final String T ABLE_NAME_T AG= "tag"; private static final String TABLE_NAM E_TAGVALUE="tagvalue"; private static final String TABLE_NAM E_DEVICE="device"; private static final String TABLE_TAG_CREATE = "create table tag" + "( ID text prim ary key not null , " + "DeviceID text not null," + "Name text not null," + "Detail text not null," + "R egisterForm at integer not null,"
+ "R egisterType integer not null," + "R egisterA ddress integer not null," + "EnableScaling integer not null," + "M axValue float not null," + "M inValue float not null," + "D ecim alN um ber integer not null," + "StoragePeriod integer not null," + "StorageSam pling integer not null," + "E nableStorage integer not null," + "Asset text not null," + "Type text not null," + "Location text not null," + "[G roup] text not null," + "Unit text not null" + " );"; private static final String TABLE_DEVICE_CREATE = "create table device" + "( ID text prim ary key not null , " + "ProjectID integer not null," + "IPA ddress text not null," + "Name text not null," + "Detail text not null," + "Suspend integer not null," + "P ort integer not null," + "SlaveID integer not null," + "Location text not null," + "DeviceDriver integer not null," + "DeviceProtocol integer not null," + "TimeOut integer not null," + "RetryTimes integer not null," + "SyncPeriod integer not null" + " );"; private static final String TABLE_TAGVALUE_CREATE = "create table tagvalue" + "( ID text prim ary key not null , " + "TagID text not null," + "Value float not null," + "RawValue integer not null,"
155 + "RecordD ate
+ " );";
integer not null"
22. SwipeDetector.java upX = event.getX(); upY = event.getY();
package com .audy.droidscada.util; im port im port im port im port
android.annotation.SuppressLint; android.util.Log; android.view.M otionEvent; android.view.View;
@ SuppressLint("ClickableViewAccessibility") public class SwipeDetector implem ents View.OnTouchListener { public static enum Action { LR, // Left to Right RL, // Right to Left TB, // Top to bottom BT, // Bottom to Top None // when no action was detected } private static final String logTag = " Swi peD etector"; private static final int H ORIZONTAL_M IN_DISTANCE = 100; private static final int VERTICAL_M IN_DISTANCE = 100; private float downX, downY, upX, upY; private Action mSwipeDetected = Action.None; public boolean swipeDetected() { return mSwipeDetected != Action.None;
public Action getAction() { return mSwipeDetected; } @ Override public boolean onTouch(View v, M otionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOW N: { downX = event.getX(); downY = event.getY(); mSwipeDetected = Action.None; retu rn false; // allow other events like Click to be processed } case MotionEvent.ACTION_M OVE: {
float deltaX = downX - upX; float deltaY = downY - upY; // horizontal swipe detection if (M ath.abs(deltaX) > H ORIZONTAL_M IN_DISTANCE) { // left or right if (deltaX < 0) { Log.i(logTag, "Swipe Left to R ight"); mSwipeDetected = Action. LR; return true; } if (deltaX > 0) { Log.i(logTag, "Swipe Right to Left"); mSwipeDetected = Action.RL; return true; } else // vertical swipe detection if (M ath.abs(deltaY) > VERTICAL_M IN_DISTANCE) { // top or down if (deltaY < 0) { Log.i(logTag, "Swipe Top to B ottom "); mSwipeDetected = Action. TB; return false; } if (deltaY > 0) { Log.i(logTag, "Swipe Bottom to Top"); mSwipeDetected = Action. BT; return false;
23. animslideinleft.xml <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator= "false ">
return true;
return false;
156 24. anim slideinright.xm l <set xmlns:android= "http://schemas.android.com/apk/res/android" android:shareInterpolator= "false ">
25. animslideoutleft.xm l <set xmlns:android= "http://schemas.android.com/apk/res/android" android:shareInterpolator= "false ">
26. anim slideoutright.xm l <set xmlns:android= "http://schemas.android.com/apk/res/android" android:shareInterpolator= "false ">
27. act_device_form.xml <ScrollView android :id= "@+id/df_scrlData " android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:layout_above= "@+id/df_btnSave " android:layout_alignParentLeft= "true " android:layout_alignParentRight= "true " android:layout_alignParentT op= "true " >
157 android:layout_height= "wrapcontent" android:text= "@string/df_lblDeviceName " android:textAppearance= "?android:attr/textAppearanceLarge" android:textColor= "@android:color/white " /> <EditText android:id="@+id/df_txtDeviceName" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/df_lblDeviceName" android:maxLength= "30" android:inputType= "text" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/df_txtDeviceIP " android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:digits="0123456789." android:maxLength= "15" android:ems= "10" android:hint= "@string/df_lblDeviceIPAddress " android:inputType= "phone " android:text= "10.0.2.2 " android:textColor= "@android:color/white " > <EditText android :id= "@+id/df_txtDevicePort" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/df_lblDevicePort" android:maxLength= "5" android:inputType= "number" android:text= "502" android:textColor= "@android:color/white " >
158 android:layout_height= "wrapcontent" android:text= "@string/df_lblDeviceSlaveID " android:textAppearance= "?android:attr/textAppearanceLarge" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/dftxtDeviceSlaveID " android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "Slave ID" android:inputType= "num ber^ne " android :text="1" android:textColor= "@android:color/white " > <Switch android :id= "@+id/df_switchSuspend " android:layout_width="fill_parent" android:layout_height= "wrapcontent" android:text="@string/df_lblDeviceSuspend" android:textAppearance= "?android:attr/textAppearanceLarge" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/df_txtDeviceDriver " android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/df_lblDeviceDriver " android:inputType= "text" android:text= "Modbus " android:textColor= "@android:color/white " /> <EditText android :id= "@+id/df_txtDeviceProtocol" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/df_lblDeviceProtocol" android:inputT ype= "textCapCharacters " android:text= "TCPIP " android:textColor= "@android:color/white " />
159 <EditText android:id="@+id/df_txtDeviceLocation" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/df_lblDeviceLocation " android:inputType= "text" android:text= "Local" android:textColor= "@android:color/white " > <EditText android:id= "@+id/df_txtDeviceRetryTimes " android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "Device Retry times" android:inputT ype= "numberSigned " android :text= "10 " android:textColor= "@android:color/white " > <EditText android:id="@+id/df_txtDeviceSyncPeriod" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "Device Sync Period" android:inputT ype= "numberSigned " android:text= "1000" android:textColor= "@android:color/white " >
160 android:layout_height= "wrapcontent" android:text="@string/df_lblDeviceTimeout" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/df_txtDevice TimeOut" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "Device Time Out" android:inputType= "text" android:text= "2000" android:textColor= "@android:color/white " > <Button android :id= "@+id/df_btnSave " android:layout_width= "wrapcontent" android:layout_height= "wrapcontent" android:layout_alignParentB ottom= "true " android:layout_alignParentLeft= "true " android:layout_alignParentRight= "true " android:layout_centerHorizontal= "true " android:onClick= "Save " android:text= "@string/df_btnDeviceSave " android:textC olor= "@android: color/white " />
28. act_device_list.xml
<Button android:id= "@+id/dl_btnAddDevice " android:layout_alignParentLeft= "true " android:layout_alignParentRight= "true " android:layout_alignParentBottom= "true " android:layout_width= "wrapcontent"
161 android:layout_height="wrap_content" android:onClick= "adddevice " android:text= "@string/button_adddevice " />
29. act ta g form.xml <ScrollView android :id= "@+id/dfscrlData " android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:layout_above= "@+id/tfbtnSave " android:layout_alignParentLeft= "true " android:layout_alignParentRight= "true " android:layout_alignParentT op= "true " > <Spinner android:id="@+id/tf_spDeviceName" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/tftxtTagName " android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_lblTagName "
162 android:maxLength= "30" android:inputType="text" android:textColor= "@android:color/white " > <EditText android:id="@+id/tf_txtTagRegisterAddress" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_lblTagRegisterAddress " android:maxLength= "5" android:inputType= "number\none " android:text= "2" android:textColor= "@android:color/white " > <EditText android:id="@+id/tf_txtTagRegisterFormat" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_l blTagRegisterFormat" android:inputType= "number" android:text="Two_Bytes_Unsigned_Integer" android:textColor= "@android:color/white " > <EditText android:id="@+id/tf_txtTagRegisterType" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_lblTagRegisterType " android:inputType= "number" android:text= "OutputHoldings "
163 android:textColor= "@android:color/white " > <EditText android :id= "@+id/tf_txtTagDecimaNum ber" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_l blTagDecimaNumber " android:inputType= "num ber^ne " android:text= "2" android:textColor= "@android:color/white " > <Switch android :id= "@+id/tf_l blTagEnableScaling " android:layout_width="fill_parent" android:layout_height= "wrapcontent" android:text="@string/tf_lblTagEnableScaling" android:textAppearance= "?android:attr/textAppearanceLarge" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/tf_txtTagMinValue" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_lblTagMin Value " android:maxLength= "10" android:inputType= "number" android :text="0" android:textColor= "@android:color/white " > <EditText android:id="@+id/tf_txtTagMaxValue"
164 android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint= "@string/tf_lblTagMaxValue " android:maxLength= "10" android:inputType= "number" android:text= "100" android:textColor= "@android:color/white " > <Switch android:id="@+id/tf_lblTagEnableStorage" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text= "@string/tf_lblTagEnableStorage " android:textAppearance= "?android:attr/textAppearanceLarge" android:textColor= "@android:color/white " /> <EditText android :id= "@+id/tftxtTagStorageSampling " android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:hint="@string/tf_lblTagStorageSampling" android:inputType= "text" android:text= "5000" android:textColor= "@android:color/white " > <EditText android :id= "@+id/tf_txtTagUnit" android:layout_width= "match_parent" android:layout_height= "wrapcontent" android:ems= "10" android:maxLength= "15" android:hint= "@string/tf_l blTagUnit" android:inputType= "text" android:text= "Unit" android:textColor= "@android:color/white " >
165 <Button android :id= "@+id/tf_btnSave " android:layout_width= "wrapcontent" android:layout_height= "wrapcontent" android:layout_alignParentB ottom= "true " android:layout_alignParentLeft= "true " android:layout_alignParentRight= "true " android:layout_centerHorizontal= "true " android:onClick= "Save " android:text= "@string/tf_btnTagSave " android:textColor= "@android:color/white " />
30. basicadapter.xm l
166 31. dialpopup.xm l
32. scada_dashboard.xm l <Button android:id="@+id/db_btnToggleCore" android:layout_alignParentLeft= "true " android:layout_alignParentRight= "true " android:layout_alignParentBottom= "true " android:layout_width= "wrapcontent" android:layout_height= "wrapcontent" android:onClick= "ToggleCore " android:text= "@string/button_startservice " />
33. color.xml #66000000 #8EC9CC #FFFFFF
167 34. dimens.xml \6dp 16dp 240dp 5dp 5dp
35. option.xml <string-array name= "listitem option "> - Edit
- Delete
36. strings.xml <string name= "app_name ">DroidSCADA <string name="title_activiiy_scadadashboard">SCADADashboard <string name="bg_name">Droid SCADA <string name="df_lblDeviceName">Device Name <string name="df_lblDeviceIPAddress">lP Address <string name="df_lblDevicePort">Port <string name="df_lblDeviceRetryTimes">Retry Times <string name="df_lblDeviceTimeout">Time Out(ms) <string name="df_lblDeviceSyncPeriod">Sync Period(ms) <string name="df_lblDeviceSlaveID">Slave ID <string name= "df_lblDeviceSuspend"> Suspend <string name= "dflblDeviceDriver ">Driver <string name= "dflblDeviceProtocol ">Protocol <string name= "dflblDeviceLocation ">Location <string name="df_btnDeviceSave">Save Device <string name="tf_btnTagSave">Save Tag <string name="tf_lblTagDevice ">Device <string name="tf_lblTagName">Tag Name <string name="tf_lblTagRegisterAddress">Register Address <string name="tf_lblTagRegisterFormat">Register Format <string name="tf_lblTagRegisterType">Register Type <string name="tf_lblTagEnableScaling">Enable Scaling <string name="tf_lblTagMinValue">Scale Min Value <string name="tf_lblTagMaxValue">Scale Max Value <string name="tf_lblTagEnableStorage">Enable Storage <string name="tf_lblTagStorageSampling">Storage Sampling <string name="tf_lblTagDecimaNumber">Decimal Number <string name= "tflblTagUnit ">Unit
168
<string name= "imageref’>Image <string name="title_section1 ">DroidSCADA <string name="title_section2">DroidSCADA <string name= "title_section3 ">DroidSCADA <string name="navigation_drawer_open">Open navigation drawer <string name="navigation_drawer_close">Close navigation drawer <string name= "action_adddevice">Add Device <string name= "action_addtag">Add Tag <string name="action_exportdata">Export Data <string name= "actionsettings ">Settings <string name="action_devicelist">Device list <string name="title_activity_device_form">Device Editor <string name="title_activity_tag_form">Tag Editor <string name="notification__please_wait">Please Wait <string name="w_confirm_delete">Confirm Delete <string name= "w_confirm_tag_delete">Delete Tag? <string name="w_confirm_device_delete">Delete Device? <string name="w_tag_delete">Tag Delete <string name="w_device_delete">Device Delete <string name= "wsuccess ">Success <string name="w_/ailed">Failed <string name="w_select_device_here">Select Device <string name= "notification_answer_yes ">Yes <string name= "notificationansw erno ">No <string name= "button_startservice">Start Service <string name= "button_stopservice">Stop Service <string name= "button_addtag">add Tag <string name= "button_adddevice">add Device <string name= "buttonclose ^'>Close <string name="title_activity_device_list">Device List
37. A ndroidM anifest.xm l <manifest xmlns:android= "http://schemas.android.com/apk/res/android" package= "com. audy. droidscada " android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion= "16" android:targetSdkVersion= "21" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission. WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
169 <service android:name=".services.Core" />