Kami mengontrol pencahayaan di apartemen (NooLite, Raspberry Pi, dan WebIOPi)

Saya ingin berbagi pengalaman menggunakan sistem rumah pintar NooLite bersama dengan Raspberry Pi Model B (selanjutnya disebut RPI ) di apartemen dua kamar.
Tentang sistem NooLite berulang kali ditulis pada hub:

Dalam artikel ini saya akan memberi tahu:



  • ( ): RPI + WebIOPi (UART+REST) + NooLite
  • : NooLite —
  • ( , ): Android, WEB-, bash shell (python script)

Mungkin seseorang akan berpikir: "Saya tidak akan repot-repot dengan RPI demi fungsi sederhana seperti itu - untuk mengontrol pencahayaan di apartemen dari ponsel, tetapi akan menyadari semuanya menggunakan cangkir plastik, kerikil dan benang pada Arduino dengan perisai Wi-Fi atau perisai yang lebih sederhana implementasi ringkas pada mikrokontroler AVR. "
Tapi, karena saya sudah mengumpulkan debu di rak RPI dan diatasi oleh keinginan untuk membuat pencahayaan "pintar" menggunakan platform RPI, saya memutuskan untuk menjadikannya sebagai dasar. Juga, kemungkinan menggunakan RPI memberikan margin yang baik untuk memperluas fungsionalitas "rumah pintar".

Memasukan data


  • Apartemen 2 kamar P44T tanpa perbaikan di gedung baru
  • RPI (diakuisisi dua tahun lalu untuk kepentingan)
  • keinginan untuk mewujudkan pencahayaan yang cerdas

Untuk beberapa waktu saya melihat berbagai platform dan teknologi rumah pintar, sebagai hasilnya, pilihan jatuh pada sistem NooLite, berdasarkan pada hal-hal berikut:
  • harga yang memadai dibandingkan dengan sistem serupa (Z-Wave, EnOcean, ZigBee)
  • Saya percaya barang-barang buatan Belarus
  • protokol terbuka
  • banyak contoh penggunaan di Internet
  • 433 MHz tersebar luas dan disahkan oleh SCRF

Saya juga menarik perhatian pada platform Wiren Board berbasis ARM9 untuk otomatisasi rumah dengan fungsionalitas yang kaya untuk semua kebutuhan yang dapat dibayangkan dan tidak terbayangkan. Saya sangat senang dengan fitur mematikan - modul radio 433 MHz, yang dalam kasus saya cocok untuk mengendalikan unit daya NooLite. Tapi karena saya sudah memiliki RPI, kami akan membangun ini.
Untuk menerapkan pencahayaan "pintar" di apartemen, saya harus menyelesaikan tugas-tugas berikut:
  1. menentukan skenario pencahayaan optimal di apartemen dua kamar
  2. mendefinisikan metode untuk berintegrasi dengan RPI dan menempatkan arus rendah
  3. pilih pembungkus untuk dikontrol
  4. buat daftar belanja
  5. mengoordinasikan hal di atas dengan istrinya
  6. beli komponen yang diperlukan
  7. bind remote dan debug integrasi RPI> NooLite
  8. temukan dan beli sakelar yang cocok untuk kendali jarak jauh
  9. tempatkan blok daya dan sakelar
  10. mengembangkan aplikasi seluler untuk Android

Item 1 dan 4-6 dapat diulang dalam satu siklus.
Harga Masalah:
  • RPI [1 pc]
  • Modul NooLite MT1132 [1 140 ₽ X 1 pc] 1 140 ₽
  • Blok daya NL [1 240 ₽ X 11 pcs] 13 640 ₽
  • Panel kontrol stasioner NL [1 340 ₽ X 7 pcs] 9 380 ₽
  • Gantungan kunci kendali jarak jauh NL [1 550 ₽ X 1 pc] 1 550 ₽
  • Sensor gerak NL [1 550 ₽ X 1 pc] 1 550 ₽
  • Kotak pemasangan, dukungan, modul keyboard / tombol (sakelar), bingkai (dibeli terpisah)
  • berteman dengan printer 3D - gratis

Total: ~ 27 000 ₽ + pengontrol dari 3 000 ₽.

Skenario pencahayaan apartemen


Tata letak rompi dua kamar sudut P44T dengan jendela rongga diberikan di bawah ini.

Direncanakan untuk mengontrol pencahayaan dengan NooLite di semua kamar kecuali loggia, kamar mandi dan toilet.
Koridor

2 titik pencahayaan dengan mode relai (on / off).
Satu titik cahaya yang tidak terlalu terang harus dikendalikan oleh sensor gerak PM111 . Ini akan memungkinkan dalam gelap untuk menerangi jalan pengembara malam mencari cahaya malam kelaparan.

Kedua titik pencahayaan harus dikontrol oleh saklar tetap yang terletak di sebelah pintu depan. Switch harus mencakup skenario "matikan lampu di seluruh apartemen."
Sensor gerak termal beralih ke mode siaga (mulai merespons pergerakan benda-benda termal) ketika Anda mengatur tingkat pencahayaan dan sensitivitas ruangan yang diperlukan. Biasanya di siang hari tidak perlu berkedip cahaya di koridor untuk lulus.
Dari instruksi untuk sensor:
Jika iluminasi dekat sensor PM111 lebih tinggi dari yang ditetapkan oleh regulator Illuminance, maka sensor berada dalam mode siaga. Pada saat yang sama, konsumsi saat ini minimal (kurang dari 1 μA), dan sensor gerak termal dinonaktifkan. Ketika iluminasi jatuh di bawah level yang telah ditentukan, sensor memasuki mode siaga.

Lampu di toilet dan kamar mandi dikendalikan oleh saklar stasioner klasik. Lampu dan kipas di toilet terhubung melalui relay waktu F&F PO-415 (juga Belarusia) pada rel DIN.

Sebagai akibat dari penutupan kontak kontrol 6, kontak relai 11, 12 ditutup. Membuka kontak kontrol 6 menyebabkan hitungan mundur dari waktu yang ditetapkan, setelah itu operasi PO-415 berhenti.

Saklar koridor stasioner harus dari jenis tombol-tekan, karena menjalankan skrip melibatkan menekan tombol (skrip tidak memiliki status ON / OFF).
Juga, tombol ini diperlukan jika kita perlu mematikan lampu yang sudah dinyalakan oleh sensor gerak, ketika timer sensor dikonfigurasikan untuk tidak mematikan lampu selama beberapa menit setelah dipicu. Kuncinya tidak cocok dalam kasus ini.
Total menyusuri lorong:
  • dua unit daya tipe relai 200 W ( SU111-200 dalam mode relai)
  • satu saklar 3 tombol stasioner (Remote PK313 ):
    • Tombol 1 - lampu titik nyala / mati 1
    • tombol 2 - menyalakan / mematikan lampu titik 2
    • tombol 3 - mematikan lampu di seluruh apartemen (skrip)



Dapur

Tiga titik pencahayaan:
  • lampu di atas meja ( mode relai SU111-200 )
  • pencahayaan spot di plafon peregangan ( mode relai SU111-200 )
  • Strip LED untuk menerangi permukaan kerja dapur ( SU111-200 mode relai)

Titik pencahayaan dikendalikan oleh sakelar 3 tombol (remote PK311 ) yang terletak di pintu masuk dapur.

Ruang tamu dan balkon

Dua titik pencahayaan dalam mode relai ( SU111-200 ):
  • pencahayaan utama di ruang tamu
  • cahaya di balkon

Setiap titik pencahayaan dikendalikan oleh 2 sakelar:
  • Sakelar stasioner 2 tombol di balkon (Remote PK313 ):
    • Tombol 1 - lampu on / off di balkon
    • tombol 2 - menghidupkan / mematikan lampu di ruang tamu

  • Sakelar stasioner 2-kunci di ruang tamu (Remote PK314 ):
    • kunci 1 - menghidupkan / mematikan lampu di ruang tamu
    • tombol 2 - lampu on / off di balkon



Mungkin seseorang akan bertanya "mengapa tidak meletakkan saklar 2 tombol di balkon seperti di ruang tamu?" atau "mengapa tidak meletakkan tombol di seluruh apartemen?".
Kebetulan, mula-mula ia seharusnya memasang sakelar 3 tombol dengan satu tombol skenario di balkon, tetapi kemudian berubah pikiran ketika memilih desain sakelar itu sendiri. Juga diasumsikan bahwa akan ada tombol di koridor dan di dapur, dan tombol kunci di ruang tamu, kamar tidur dan balkon untuk melestarikan desain.
Kemudian saya ingin meredupkan lampu dengan saklar di tempat tidur, jadi semuanya serba salah. Untuk melestarikan desain pemutus sirkuit, saya harus berkeliling di banyak pasar konstruksi, mengunjungi selusin situs Internet, lebih lanjut tentang ini nanti di bagian " Temukan dan beli pemutus sirkuit yang cocok untuk kontrol jarak jauh ".
Kamar tidur

Bagian 1 (tempat tidur)
Biasanya blok daya terletak di setiap titik pencahayaan. Satu titik pencahayaan - satu unit daya. Dalam skenario pencahayaan saya, ada satu penyimpangan dari logika tradisional. Di kamar tidur "bagian 1" itu seharusnya memasang lampu dengan dua unit daya, salah satunya akan diredupkan.
Bagian 2 (jendela rongga)
Selain sakelar stasioner, semua titik pencahayaan harus dikontrol dari sakelar kendali jarak jauh sebagai konsol cadangan dan RPI. Untuk gantungan kunci:
  • tombol A (menyalakan / mematikan lampu di lorong dan di dapur)
  • tombol B (menyalakan / mematikan lampu di ruang tamu dan di balkon)
  • tombol C (nyalakan / matikan lampu di kamar tidur)


Menentukan Metode Integrasi Penempatan Rendah dan NooLite C untuk RPI


Saya akan katakan segera, integrasi itu sederhana. NooLite memiliki modul MT1132 . Modul menerima paket kontrol melalui UART dari beberapa pengontrol, dalam kasus saya ini adalah RPI, mentransmisikan perintah melalui udara ke perangkat eksekutif (blok daya) dan merespons dengan konstruksi OK / r \ n, semuanya dijelaskan dalam instruksi modul .
Tegangan pasokan modul (VCC Upit)2.7-5.5 V
rentang tegangan input pada Rx0 - Atas
TTL LVL TINGGI (unit logis) pada Upit = 5 V2 - Upit (5 V)
TTL RENDAH LVL (nol logis) pada Upit = 5 V0-0.8 V
TTL LVL TINGGI (unit logis) pada Upit = 3,3 V2-3.3 V
TTL RENDAH LVL (nol logis) pada Upit = 3,3 V0-0.8 V
Kecepatan UART9600 baud


Karena garis RPART UART beroperasi dengan level TTL 3,3 V, maka kita akan menggunakan 3,3 V sebagai daya modul U.

Anda dapat menggunakan tiga baris pada MT1132: VCC, GND, dan RX, untuk mengirimkan paket kontrol. Saya melakukan ini ketika debugging - Saya tidak membaca jawaban "OK \ r \ n" dari MT1132, itu sudah cukup bagi saya untuk mengamati indikator unit daya yang terpasang. Setelah berhasil menerima perintah "mengikat", sering berkedip LED internal dimulai pada unit daya.
Poin lain, kekuatan pemancar radio dengan daya U dari 3,3 V hingga 3,3 mW, dengan daya U dari 5 V hingga 5 mW. Jarak maksimum ke unit daya adalah 70 m.

Tentang paket kontrol


Paket kontrol terdiri dari 12 byte:
ST, B0, B1, B2, B3, B4, B5, B6, B7, B8, CS, SP
ST - byte awal, selalu 85
B0..B8 - payload (perintah kontrol)
CS - periksa jumlah. Byte paling tidak signifikan dari jumlah 10 byte pertama (ST ke B8)
SP - stop byte
Menurut instruksi, saya menuliskan byte kontrol yang saya butuhkan:
B1 - perintah kontrol dengan nilai:
  • 0 - matikan beban
  • 2 - hidupkan beban
  • 4 - aktifkan atau matikan beban
  • 9 - decoupling (mulai proses menghapus alamat dari memori unit daya)
  • 15 - binding (catat alamat modul di unit daya)

B4 - alamat saluran (dari 0 hingga 31). Hanya 32 saluran.
byte lain secara default kecuali untuk checksum.
B0 - mengatur mode transmisi modul.
Jika nilai 80 (0x50) diteruskan ke B0, maka:
  • jumlah pengulangan - 2
  • bitrate 2-1000 bps
  • mode 0 - mengirim perintah


Akibatnya, saya mengkompilasi tabel seperti itu dengan paket kontrol yang diperlukan untuk saya.
Penempatan pada panel listrik

Diputuskan untuk menginstal arus lemah di switchboard internal:
  • RPI dipasang pada rel DIN dengan melampirkan teman yang dicetak pada printer 3D
  • Modul MT1132 untuk mengontrol unit daya melalui udara
  • dua ~ 220 soket pada DIN untuk koneksi unit catu daya router dan RPI


Debugging integrasi dan pemilihan pembungkus untuk manajemen


Prasyarat:
  • RPI
  • Modul MT1132
  • kabel dari ibu ke ibu untuk menghubungkan pin MT1132 dan RPI GPIO
  • Kartu SD dengan gambar RPI yang sudah diinstal sebelumnya
  • akses ke SHELL (bash, csh, korn, dll.) RPI konsol (keyboard langsung atau jarak jauh melalui SSH)
  • paket kontrol yang disiapkan
  • perpustakaan untuk bekerja dengan UART melalui header GPIO di RPI

Saat menyiapkan gambar, saya menangkap bug bawaan yang keren di Macbook Air sambil merekam gambar Raspbian-wheezy di bawah root (meskipun bagi saya ini adalah fitur - perlindungan penulisan tambahan, pikirkan kembali sebelum menimpa data):
dd bs=1m if=2015-02-16-raspbian-wheezy.img of=/dev/disk2

Konsol kembali:
dd: /dev/disk2: Permission denied 

Dengan kunci yang dilepaskan pada kartu SD, di bawah root dan mod yang benar di / dev / disk2 ....
Lalu saya menemukan pertukaran pada topik ini , seseorang membantu meniup ke slot SD pada poppy, seseorang mendapat mesin slot. Mengalahkan macbook adalah pemborosan hari ini, dan sebagai hasilnya, sedikit celah membantu saya: jika kartu SD tidak sepenuhnya dimasukkan, semuanya akan berfungsi.
Selama debugging, saya harus ke pertanian kolektif, karena tidak ada konektor ibu-ibu yang cocok.

Menimbang bahwa saya memerlukan pembungkus untuk mengontrol unit daya melalui WEB, kemampuan untuk membuat permintaan REST di masa depan dan pustaka UART dari satu kotak - pilihan ada di WebIOPi .

Walaupun saya ingin membangun OpenHAB karena arsitekturnya yang keren. Platform otomatisasi dijelaskan pada Habré .
Saya pasti akan menggunakan platform ini di masa depan, tetapi untuk sekarang, untuk "Daftar Keinginan" saya, platform yang dipilih sudah cukup.
Arsitektur interaksi umum


Menyiapkan WebIOPi minimum
Menggunakan instruksi yang disediakan di situs web proyek:
  1. instal kerangka kerja WebIOPi dengan mengikuti langkah-langkah ini
    • Instalasi
    • Menjalankan WebIOPi (Daemon)
    • Mulai otomatis saat boot

  2. konfigurasikan UART dengan mengubah 3 file: / etc / inittab, /boot/cmdline.txt, / etc / webiopi / config. Langkah:
    • Uart on-board
    • Konfigurasi WebIOPi

  3. kami mereproduksi tindakan yang dijelaskan dalam bagian ini
    • Trik Serial Loopback (mengirim "string" ke diri kita sendiri melalui UART dan membaca antarmuka WEBIOPi di bagian Serial Monitor)
    • video di bagian Serial Monitor menampilkan proses



Instal jumper untuk menguji loop UART.
Menggunakan tabel yang sebelumnya dikompilasi dengan paket kontrol, kita akan menulis skrip Python sederhana untuk mengelola modul dari RPI SHELL.
Skrip RPI Shell untuk modul MT1132
#!/usr/bin/python
import sys, getopt
def main(argv):
   ch = ''
   cmd = ''
   try:
      opts, args = getopt.getopt(argv,"h:",["ch=","cmd="])
   except getopt.GetoptError:
      print 'mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>'
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         print 'mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>'
         sys.exit()
      elif opt in ("--ch"):
         ch = arg
      elif opt in ("--cmd"):
         cmd = arg
   print 'Channel: ', ch
   print 'Command: ', cmd
   if cmd=='ON' and ch!='':
        if ch=='0':
                print 'Switch ON channel 0'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
        elif ch=='1':
                print 'Switch ON channel 1'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00a8, 0x00aa])
        elif ch=='2':
                print 'Switch ON channel 2'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00a9, 0x00aa])
        elif ch=='3':
                print 'Switch ON channel 3'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00aa, 0x00aa])
        elif ch=='4':
                print 'Switch ON channel 4'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00ab, 0x00aa])
        elif ch=='5':
                print 'Switch ON channel 5'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00ac, 0x00aa])
        elif ch=='6':
                print 'Switch ON channel 6'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ad, 0x00aa])
        elif ch=='7':
                print 'Switch ON channel 7'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='8':
                print 'Switch ON channel 8'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00af, 0x00aa])
        elif ch=='9':
                print 'Switch ON channel 9'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00b0, 0x00aa])
        elif ch=='10':
                print 'Switch ON channel 10'
                serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00b1, 0x00aa])
   if cmd=='OFF' and ch!='':
        if ch=='0':
                print 'Switch OFF channel 0'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a5, 0x00aa])
        elif ch=='1':
                print 'Switch OFF channel 1'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00a6, 0x00aa])
        elif ch=='2':
                print 'Switch OFF channel 2'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
        elif ch=='3':
                print 'Switch OFF channel 3'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00a8, 0x00aa])
        elif ch=='4':
                print 'Switch OFF channel 4'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00a9, 0x00aa])
        elif ch=='5':
                print 'Switch OFF channel 5'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00aa, 0x00aa])
        elif ch=='6':
                print 'Switch OFF channel 6'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ab, 0x00aa])
        elif ch=='7':
                print 'Switch OFF channel 7'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00ac, 0x00aa])
        elif ch=='8':
                print 'Switch OFF channel 8'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00ad, 0x00aa])
        elif ch=='9':
                print 'Switch OFF channel 9'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='10':
                print 'Switch OFF channel 10'
                serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
   if cmd=='BIND' and ch!='':
        if ch=='0':
                print 'BIND channel 0'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
        elif ch=='1':
                print 'BIND channel 1'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00b5, 0x00aa])
        elif ch=='2':
                print 'BIND channel 2'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00b6, 0x00aa])
        elif ch=='3':
                print 'BIND channel 3'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00b7, 0x00aa])
        elif ch=='4':
                print 'BIND channel 4'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00b8, 0x00aa])
        elif ch=='5':
                print 'BIND channel 5'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00b9, 0x00aa])
        elif ch=='6':
                print 'BIND channel 6'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00ba, 0x00aa])
        elif ch=='7':
                print 'BIND channel 7'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00bb, 0x00aa])
        elif ch=='8':
                print 'BIND channel 8'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00bc, 0x00aa])
        elif ch=='9':
                print 'BIND channel 9'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00bd, 0x00aa])
        elif ch=='10':
                print 'BIND channel 10'
                serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00be, 0x00aa])
   if cmd=='UNBIND' and ch!='':
        if ch=='0':
                print 'UNBIND channel 0'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
        elif ch=='1':
                print 'UNBIND channel 1'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00af, 0x00aa])
        elif ch=='2':
                print 'UNBIND channel 2'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00b0, 0x00aa])
        elif ch=='3':
                print 'UNBIND channel 3'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00b1, 0x00aa])
        elif ch=='4':
                print 'UNBIND channel 4'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00b2, 0x00aa])
        elif ch=='5':
                print 'UNBIND channel 5'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00b3, 0x00aa])
        elif ch=='6':
                print 'UNBIND channel 6'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
        elif ch=='7':
                print 'UNBIND channel 7'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00b5, 0x00aa])
        elif ch=='8':
                print 'UNBIND channel 8'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00b6, 0x00aa])
        elif ch=='9':
                print 'UNBIND channel 9'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00b7, 0x00aa])
        elif ch=='10':
                print 'UNBIND channel 10'
                serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00b8, 0x00aa])
if __name__ == "__main__":
   main(sys.argv[1:])


Untuk mengontrol MT1132 dari konsol shell, jalankan perintah berikut

mt1132.py --ch <channel_number> --cmd <ON/OFF/BIND/UNBIND>

Kami kencangkan API REST
Kerangka kerja WebIOPi menyediakan kontrol melalui permintaan HTTP dengan gaya REST , yang memfasilitasi pengikatan klien seluler dan menyederhanakan interaksi klien-server.
Salin tempel kerangka REST API menggunakan tautan di atas:
  • Dapatkan fungsi GPIO
  • Atur fungsi GPIO
  • Dapatkan nilai GPIO
  • Tetapkan nilai GPIO
  • Keluarkan satu pulsa
  • Urutan bit output
  • Output PWM dengan rasio siklus kerja
  • Output PWM dengan sudut untuk servos
  • Panggil makro di server
  • Dapatkan status / konfigurasi GPIO lengkap

Kasus kami adalah "Panggil makro di server". Uraiannya tidak berminyak, tetapi cukup untuk percobaan:
HTTP POST / macro / (macro) / (args)
  • Mengembalikan nilai yang dikembalikan oleh makro

Karena (makro) belum disiapkan, kami akan memeriksa REST "Dapatkan status GPIO penuh / konfigurasi", dan untuk ini kita perlu membuat permintaan HTTP GET / *.
Kami membuka Klien REST API, saya menggunakan klien DHC untuk browser Chrome. Kami mencoba melakukan permintaan REST untuk mendapatkan waktu saat ini.

Konfigurasi WebIOPi (/ etc / webiopi / config)

Di bagian [PERANGKAT] :
Tambahkan perangkat serial (UART GPIO) - ini adalah modul MT1132 kami, di mana
ttyAMA0 adalah perangkat (port) yang dilihat oleh kernel Raspbian,
baudrate adalah kecepatan dalam Baud pertukaran informasi melalui antarmuka UART ini.
9600 baud / (8 + 1 bit awal + 1 stop bit) = 960 byte / s.
Di bagian [SCRIPTS] (skrip khusus):
Tambahkan string myscrypt = /home/pi/smarthome/python/mt1132.py - untuk menghubungkan skrip kami ke framework.
Di bagian [REST] (pengaturan kontrol GPIO melalui API REST. Opsional):
gpio-post-value = false - melarang mengubah level RENDAH / TINGGI logis pada pin GPIO melalui permintaan REST;
gpio-post-function = false - melarang mengubah pengaturan IN / OUT pada pin GPIO melalui permintaan REST.
Pengaturan yang tersisa dibiarkan tidak berubah.
[COAP] :
Saya tidak menyentuh, memutuskan koneksi . Sementara saya tidak tahu apa yang dimakan dan di mana itu digunakan. Saya mencatat hanya baris ini di kepala saya: oAP - adalah protokol transfer web khusus untuk digunakan dengan node terbatas dan jaringan terbatas diInternet of Things , dirancang untuk aplikasi mesin-ke-mesin (M2M) seperti energi pintar dan otomatisasi bangunan. "
Mungkin di Habr seseorang membuka kasus penggunaan yang bermanfaat.
Tambahkan makro untuk permintaan REST ke skrip yang disiapkan sebelumnya.
# Channel 0	
@webiopi.macro	
def ch0(cmd):
	if cmd=='on':
		serial.writeBytes([0x55, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a7, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='off':
		serial.writeBytes([0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00a5, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='unbind':
		serial.writeBytes([0x55, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00ae, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	if cmd=='bind':
		serial.writeBytes([0x55, 0x50, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00b4, 0x00aa])
		webiopi.sleep(1)
		resp = 'Channel: 0, Cmd: ' + cmd + ', Status: ' + serial.readString()
	return resp 


Menguji permintaan REST dengan makro

Kami mengirim permintaan REST untuk "mengikat alamat saluran ke-3 NooLite MT1132 ke blok daya tempat pengikatan dimulai" melalui DHC.
Jika paket kontrol berhasil dikirim, modul MT1132 akan merespons melalui UART TX ke GPIO UART RX “OK”. Jika berhasil, unit daya akan mengingat alamat saluran dan berkedip intens dengan LED hijau bawaan.

Klien sederhana untuk Android


Awalnya, saya tidak berencana untuk menulis aplikasi untuk Android, karena fakta bahwa saya tidak tahu, saya bermaksud membatasi diri ke browser. Kemudian dia secara tidak sengaja berkeliaran di saluran Mulai Android . Penulis, Dmitry, menceritakan secara terperinci dengan Andryukha cara memulai proyek pertamanya dengan cepat di bawah platform Androyd. Terima kasih banyak kepada penulis untuk proyek dan kerja kerasnya!
Setelah menonton dan menyelesaikan tidak lebih dari dua puluh pelajaran, saya mulai membuat aplikasi kontrol pencahayaan sederhana saya. Untuk pengembangan saya menggunakan IDE Android Studio, seperti yang diminta Google - berdasarkan IntelliJ IDEA.
Antarmuka
Hasilnya adalah antarmuka yang sangat asketis:

main.xml SEBAGAIMANA ADANYA
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/hl7"
    android:padding="2dp"
    android:clickable="false">

    <!-- -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/r1c1"
            android:textSize="18sp"
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:layout_margin="1dp"
            android:text=""
            android:background="@color/hl4"
            android:layout_weight="1"
            android:gravity="center"
            android:textColor="@color/white" />
        <TextView
            android:textColor="@color/white"
            android:textSize="18sp"
            android:id="@+id/r1c2"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text=" "
            android:layout_margin="1dp"
            android:background="@color/hl4"
            android:layout_weight="2"
            android:gravity="center"/>
        <TextView
            android:textColor="@color/white"
            android:textSize="18sp"
            android:id="@+id/r1c3"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:padding="4dp"
            android:text=""
            android:layout_margin="1dp"
            android:background="@color/hl4"
            android:layout_weight="3"
            android:gravity="center"/>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textColor="@color/black"
            android:textSize="16sp"
            android:text="@string/room1txt"
            android:id="@+id/room1"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center|top">
            <TextView
                android:layout_width="match_parent"
                android:textColor="@color/hl9"
                android:layout_height="36dp"
                android:text="@string/place1txt"
                android:id="@+id/r1switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:textColor="@color/hl9"
                android:text="@string/place5txt"
                android:id="@+id/r1switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:textColor="@color/hl9"
                android:text="@string/place2txt"
                android:id="@+id/r1switch3"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r1b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_weight="1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b2off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r1b3on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r1b3off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room2txt"
            android:id="@+id/room2"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textColor="@color/black"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:textSize="13sp"
            android:text="@string/place1txt"
            android:textColor="@color/hl9"
            android:id="@+id/r2switch1"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center|left"
            android:background="@color/hl8"/>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="horizontal"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r2b1on" />
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_weight="1"
                android:layout_height="36dp"
                android:text=""
                android:id="@+id/r2b1off" />
        </LinearLayout>
    </LinearLayout>

    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room3txt"
            android:id="@+id/room3"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:textColor="@color/black"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:textSize="13sp"
            android:textColor="@color/hl9"
            android:text="@string/place1txt"
            android:id="@+id/r3switch1"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center|left"
            android:background="@color/hl8"
            android:clickable="true"/>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="horizontal"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r3b1on" />
            <Button
                style="?android:attr/buttonStyleSmall"
                android:layout_width="wrap_content"
                android:layout_height="36dp"
                android:layout_weight="1"
                android:text=""
                android:id="@+id/r3b1off" />
        </LinearLayout>
    </LinearLayout>

    <!--    -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room4txt"
            android:id="@+id/room4"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:background="@color/holotheme_color"
            android:textColor="@color/black"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:text="@string/place6txt"
                android:textColor="@color/hl9"
                android:id="@+id/r4switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:text="@string/place8txt"
                android:textColor="@color/hl9"
                android:id="@+id/r4switch3"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:textColor="@color/hl9"
                android:layout_height="37dp"
                android:text="@string/place7txt"
                android:id="@+id/r4switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="37dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b3on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b3off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r4b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r4b2off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>


    <!--  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="110dp"
            android:layout_height="match_parent"
            android:textSize="16sp"
            android:text="@string/room5txt"
            android:id="@+id/room5"
            android:layout_weight="1"
            android:layout_margin="1dp"
            android:padding="4dp"
            android:gravity="center"
            android:textColor="@color/black"
            android:background="@color/holotheme_color"
            android:textStyle="bold" />
        <LinearLayout
            android:orientation="vertical"
            android:background="@color/hl8"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:layout_margin="1dp"
            android:gravity="center">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:text="@string/place3txt"
                android:textColor="@color/hl9"
                android:id="@+id/r5switch1"
                android:textSize="13sp"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
            <TextView
                android:textSize="13sp"
                android:layout_width="match_parent"
                android:layout_height="37dp"
                android:textColor="@color/hl9"
                android:text="@string/place4txt"
                android:id="@+id/r5switch2"
                android:padding="4dp"
                android:gravity="center_vertical|left"
                android:background="@drawable/hover1"
                android:clickable="true"/>
        </LinearLayout>
        <LinearLayout
            android:background="@color/hl8"
            android:orientation="vertical"
            android:layout_width="150dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:gravity="center"
            android:layout_margin="1dp">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="36dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r5b1on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r5b1off" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="37dp">
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text=""
                    android:id="@+id/r5b2on" />
                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_weight="1"
                    android:layout_height="match_parent"
                    android:text=""
                    android:id="@+id/r5b2off" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


Metode OnClick terikat ke tombol.
@Override
    public void onClick(View v) {
        // define the button switch that invoked the listener by id
        switch (v.getId()) {
            // Buttons room1 
            case R.id.r1b1on: // 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "on";
                new ParseTask().execute();
                break;

Switch mendefinisikan tampilan ID dari elemen tombol, menampilkan pesan TOAST di layar, dan membuat permintaan HTTP ke RPI melalui HttpURLConnection di dalam AsyncTask (panggil ParseTask (). Execute (); Execute ();
Interaksi dengan backend
HttpURLConnection - kelas untuk interaksi melalui protokol HTTP.
Kelas AsyncTask metode doInBackground - melakukan tugas berat dalam aliran latar belakang yang terpisah dan mengembalikan hasilnya ke aliran UI.
HttpURLConnection dieksekusi dalam metode doInBackground.
Teknik ini sering ditemukan di Internet untuk mengimplementasikan pertukaran data melalui protokol HTTP.
webiopiurl = getString(R.string.ch4url) + "on";

Mengganti konstanta dari file strings.xml dalam sumber daya proyek
<string name="ch4url">http://192.168.1.154:8000/macros/ch4/</string>

Jadi URL lengkap untuk mengaktifkan saluran 4 terlihat seperti ini
http://192.168.1.154:8000/macros/ch4/on

// HTTP Query to backend in REST style
    private class ParseTask extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String result = "";
        String BASIC_AUTH = "Basic "
                + Base64.encodeToString((getString(R.string.login) + ":" + getString(R.string.pwd)).getBytes(), Base64.NO_WRAP);

        @Override
        protected String doInBackground(Void... params) {
            //    REST 
            try {
                URL url = new URL(webiopiurl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Authorization", BASIC_AUTH);
                urlConnection.connect();
                //    backend webiopi
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

kode MainActivity.java SEBAGAIMANA ADANYA
package ru.bbq.smarthome_App;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends ActionBarActivity implements View.OnClickListener {
    // Add logger
    public static String LOG_TAG = "my_log";
    public static String webiopiurl = "";
    // switch buttons
    TextView r1sw1;
    TextView r1sw2;
    TextView r1sw3;
    TextView r2sw1;
    TextView r3sw1;
    TextView r4sw1;
    TextView r4sw2;
    TextView r4sw3;
    TextView r5sw1;
    TextView r5sw2;
    // ON OFF buttons
    Button r1b1on;
    Button r1b1off;
    Button r1b2on;
    Button r1b2off;
    Button r1b3on;
    Button r1b3off;
    Button r2b1on;
    Button r2b1off;
    Button r3b1on;
    Button r3b1off;
    Button r4b1on;
    Button r4b1off;
    Button r4b2on;
    Button r4b2off;
    Button r4b3on;
    Button r4b3off;
    Button r5b1on;
    Button r5b1off;
    Button r5b2on;
    Button r5b2off;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // find View-elements and buttons
        r1sw1 = (TextView) findViewById(R.id.r1switch1); // room1switch1
        r1sw2 = (TextView) findViewById(R.id.r1switch2); // room1switch2
        r1sw3 = (TextView) findViewById(R.id.r1switch3); // room1switch3
        r2sw1 = (TextView) findViewById(R.id.r2switch1); // room2switch1
        r3sw1 = (TextView) findViewById(R.id.r3switch1); // room3switch1
        r4sw1 = (TextView) findViewById(R.id.r4switch1); // room4switch1
        r4sw2 = (TextView) findViewById(R.id.r4switch2); // room4switch2
        r4sw3 = (TextView) findViewById(R.id.r4switch3); // room4switch3
        r5sw1 = (TextView) findViewById(R.id.r5switch1); // room5switch1
        r5sw2 = (TextView) findViewById(R.id.r5switch2); // room5switch2
        r1b1on = (Button) findViewById(R.id.r1b1on);    // room1 button1 ON
        r1b1off = (Button) findViewById(R.id.r1b1off);  // room1 button1 OFF
        r1b2on = (Button) findViewById(R.id.r1b2on);    // room1 button2 ON
        r1b2off = (Button) findViewById(R.id.r1b2off);  // room1 button2 OFF
        r1b3on = (Button) findViewById(R.id.r1b3on);    // room1 button3 ON
        r1b3off = (Button) findViewById(R.id.r1b3off);  // room1 button3 OFF
        r2b1on = (Button) findViewById(R.id.r2b1on);    // room2 button1 ON
        r2b1off = (Button) findViewById(R.id.r2b1off);  // room2 button1 OFF
        r3b1on = (Button) findViewById(R.id.r3b1on);    // room3 button1 ON
        r3b1off = (Button) findViewById(R.id.r3b1off);  // room3 button1 OFF
        r4b1on = (Button) findViewById(R.id.r4b1on);    // room4 button1 ON
        r4b1off = (Button) findViewById(R.id.r4b1off);  // room4 button1 OFF
        r4b2on = (Button) findViewById(R.id.r4b2on);    // room4 button2 ON
        r4b2off = (Button) findViewById(R.id.r4b2off);  // room4 button2 OFF
        r4b3on = (Button) findViewById(R.id.r4b3on);    // room4 button3 ON
        r4b3off = (Button) findViewById(R.id.r4b3off);  // room4 button3 OFF
        r5b1on = (Button) findViewById(R.id.r5b1on);    // room5 button1 ON
        r5b1off = (Button) findViewById(R.id.r5b1off);  // room5 button1 OFF
        r5b2on = (Button) findViewById(R.id.r5b2on);    // room5 button2 ON
        r5b2off = (Button) findViewById(R.id.r5b2off);  // room5 button2 OFF

        //assign listeners to buttons
        r1b1on.setOnClickListener(this);
        r1b1off.setOnClickListener(this);
        r1b2on.setOnClickListener(this);
        r1b2off.setOnClickListener(this);
        r1b3on.setOnClickListener(this);
        r1b3off.setOnClickListener(this);
        r2b1on.setOnClickListener(this);
        r2b1off.setOnClickListener(this);
        r3b1on.setOnClickListener(this);
        r3b1off.setOnClickListener(this);
        r4b1on.setOnClickListener(this);
        r4b1off.setOnClickListener(this);
        r4b2on.setOnClickListener(this);
        r4b2off.setOnClickListener(this);
        r4b3on.setOnClickListener(this);
        r4b3off.setOnClickListener(this);
        r5b1on.setOnClickListener(this);
        r5b1off.setOnClickListener(this);
        r5b2on.setOnClickListener(this);
        r5b2off.setOnClickListener(this);
    }

    // Define On ClickView method
    @Override
    public void onClick(View v) {
        // define the button switch that invoked the listener by id
        switch (v.getId()) {
            // Buttons room1 
            case R.id.r1b1on: // 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b1off: // 
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch4url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r1b2on: //  
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch3url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b2off: //  
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch3url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r1b3on: // LED 
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room1txt)+" > "+r1sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch2url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r1b3off: // LED 
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room1txt)+" > "+r1sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch2url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room2 
            case R.id.r2b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room2txt)+" > "+r2sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch6url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r2b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room2txt)+" > "+r2sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch6url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room3 
            case R.id.r3b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room3txt)+" > "+r3sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch5url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r3b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room3txt)+" > "+r3sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch5url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room4 bedroom
            case R.id.r4b1on: //    
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch8url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b1off: //    
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch8url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r4b2on: //    
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch7url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b2off: //    
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch7url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r4b3on: //   dimmer
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room4txt)+" > "+r4sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch9url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r4b3off: //   dimmer
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room4txt)+" > "+r4sw3.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch9url) + "off";
                new ParseTask().execute();
                break;
            // Buttons room5 corridor
            case R.id.r5b1on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room5txt)+" > "+r5sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch1url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r5b1off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room5txt)+" > "+r5sw1.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch1url) + "off";
                new ParseTask().execute();
                break;
            case R.id.r5b2on:
                Toast.makeText(this, getString(R.string.bon)+" '"+getString(R.string.room5txt)+" > "+r5sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch0url) + "on";
                new ParseTask().execute();
                break;
            case R.id.r5b2off:
                Toast.makeText(this, getString(R.string.boff)+" '"+getString(R.string.room5txt)+" > "+r5sw2.getText()+"'", Toast.LENGTH_SHORT).show();
                webiopiurl = getString(R.string.ch0url) + "off";
                new ParseTask().execute();
                break;
        }
    }

    // HTTP Query to backend in REST style
    private class ParseTask extends AsyncTask<Void, Void, String> {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String result = "";
        String BASIC_AUTH = "Basic "
                + Base64.encodeToString((getString(R.string.login) + ":" + getString(R.string.pwd)).getBytes(), Base64.NO_WRAP);
        @Override
        protected String doInBackground(Void... params) {
            //    REST 
            try {
                URL url = new URL(webiopiurl);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Authorization", BASIC_AUTH);
                urlConnection.connect();
                //    backend webiopi
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                result = buffer.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String str) {
            super.onPostExecute(str);
            //  ,    plain text ( JSON)
            //    log
            Log.d(LOG_TAG, str);
            //  TOAST -   webiopi     MT1132
            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
        }
    }

}



Temukan dan beli sakelar yang cocok untuk kendali jarak jauh


Berdasarkan skenario pencahayaan, proyek ini menggunakan keyboard NooLite dan tombol / built-in yang stasioner, perlu untuk menyediakan kemampuan untuk menginstal switch dengan tiga modul (tombol / tombol), menjaga desain switch (semua switch harus terlihat sama).
Saat memilih sakelar, pertimbangkan kemungkinan:
  • pemasangan dua hingga tiga modul untuk mendukung sakelar
  • pemasangan modul tombol dan keyboard

Saklar lampu hidup bticino cocok untuk kondisi ini. Pada foto di bawah ini, modul yang dirakit dengan remote control NooLite.


Unit daya di langit-langit selama debugging, debugging

di tempat,

panel listrik dengan arus lemah terletak di dalam,

terima kasih atas perhatian Anda. Semoga harimu menyenangkan!

Source: https://habr.com/ru/post/id382689/


All Articles