Assalamualaikum, jumpa lagi di triyonos.com dengan tutorial-tutorial pemrograman yang menarik dan mudah untuk dipelajari.

Pada tutorial kali ini triyonos.com akan membahas tentang implementasi dari Server Sent Events (SSE), yang merupakan salah satu metode transfer data satu arah dari server ke client. Server Sent Events (SSE) adalah API yang disediakan oleh HTML 5 untuk mem-push data dari server ke client. Dengan menggunakan SSE kita dapat mendapatkan update dari server tanpa harus mengirimkan data tertentu terlebih dahulu.

Di tutorial ini saya akan membuat suatu project controller warna nyala lampu LED Strip WS2812, yang warna nyala LED strip-nya berdasarkan nilai RGB dari warna object yang tertangkap di webcam. Hmmm.. menurut saya cukup keren sih projectnya, mudah-mudahan teman-teman bisa mempraktikkannya walaupun harus keluar biaya untuk membeli Arduino, LED Strip, dll.

Dalam membuat project tersebut saya menggunakan bahasa pemrograman Python dan Javascript. Aplikasi web yang berperan sebagai server saya buat menggunakan framework Flask yang berbahasa pemrograman Python, sedangkan client-nya menggunakan interface EventSource di node.js untuk menerima data Server Sent Events (SSE).

Saya akan membuat aplikasi pendeteksi warna (RGB) dari suatu object atau benda yang di dekatkan ke webcam menggunakan library Python OpenCV. Aplikasi ini berjalan di web browser, data RGB yang terdeteksi akan di-push ke client tiap 0.3 detik melalui metode Server Sent Events (SSE). Data RGB ini kemudian dibaca oleh node.js untuk kemudian diteruskan ke Arduino Uno untuk mengontrol nyala lampu LED strip WS2812.

python flask opencv sse

Tahapan Pembuatan Project

1. Pembuatan Color Detection Web Application

Seperti pada tutorial-tutorial sebelumnya, dalam pembuatan web application ini saya menggunakan framework Flask yang di-install melalui Pycharm IDE. Berikut tahapan pembuatan aplikasinya:

  1. Buka Pycharm IDE kemudian Create Project
  2. pycharm ide create new project

    Beri nama project Flask_OpenCV_SSE pada text box Location. Kemudian klik tombol Create

    pycharm ide create new project

    Tampilan awal project Flask_OpenCV_SSE di Pycharm IDE

    pycharm ide create new project
  3. Install Flask & OpenCV
  4. Pilih menu File Setting, kemudian pilih menu Python Interpreter, kemudian klik icon + untuk menampilkan jendela Available Packages

    project setting
    project setting

    Install Flask melalui jendela Available Packages

    install flask from pycharm ide

    Install OpenCV melalui jendela Available Packages

    install opencv from pycharm ide

    Flask & OpenCV berhasil terinstall.

    flask opencv successfull install from pycharm ide
  5. Copy Paste Folder templates & static
  6. Silakan klik link templates_static_folder.zip ini untuk mendownload folder templates dan static untuk di copy paste ke dalam root folder project Flask_OpenCV_SSE.

    Extract file .zip yang sudah didownload

    .zip download file

    Drag and drop folder templates dan static dari folder download ke root folder project Flask_OpenCV_SSE

    copy paste template static folder

    Jika proses copy paste folder templates dan static berhasil, maka struktur file-nya akan seperti gambar berikut:

    copy paste template static folder
  7. Create New Python File app.py
  8. Klik kanan pada root folder, arahkan mouse ke New Pyhton File, kemudian isikan dengan nama file app

    copy paste template static folder

    File app.py berhasil dibuat

    project setting

    Selanjutnya copy paste script kode di bawah ini:

    from flask import Flask, Response, render_template
    import time
    import cv2
    import json
    
    r = 0
    g = 0
    b = 0
    
    app = Flask(__name__)
    
    @app.route('/')
    def home():
        return render_template('index.html')
    
    def rgb_detection():
        wCam, hCam = 400, 400
    
        cap = cv2.VideoCapture(0)
        cap.set(3, wCam)
        cap.set(4, hCam)
    
        while True:
            _, img = cap.read()
            hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
            height, width, _ = img.shape
    
            cx = int(width / 2)
            cy = int(height / 2)
    
            # Pick pixel value
            pixel_center = hsv_img[cy, cx]
            hue_value = pixel_center[0]
    
            global b, g, r
    
            pixel_center_bgr = img[cy, cx]
            b, g, r = int(pixel_center_bgr[0]), int(pixel_center_bgr[1]), int(pixel_center_bgr[2])
    
            cv2.rectangle(img, (cx - 260, 10), (cx + 150, 70), (255, 255, 255), -1)
            cv2.putText(img, 'R:'+str(r)+', G:'+str(g)+', B:'+str(b), (cx - 220, 50), 0, 1, (b, g, r), 4)
            cv2.circle(img, (cx, cy), 5, (25, 25, 25), 3)
    
            frame = cv2.imencode('.jpg', img)[1].tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
    
            key = cv2.waitKey(1)
            if key == 27:
                break
    
    
    @app.route('/video_feed')
    def video_feed():
        # Video streaming route. Put this in the src attribute of an img tag
        return Response(rgb_detection(), mimetype='multipart/x-mixed-replace; boundary=frame')
    
    # a generator with yield expression
    def rgb_event_data():
        while True:
            time.sleep(0.3)
    
            _data = json.dumps({"red": r, "green": g, "blue": b})
    
            # DO NOT forget the prefix and suffix
            yield f"id: 1\ndata: {_data}\nevent: online\n\n"
    
    @app.route('/sse_rgb')
    def sse_rgb():
        return Response(
            rgb_event_data(), mimetype='text/event-stream'  # mark as a stream response
        )
    
    if __name__ == "__main__":
        app.run(host='127.0.0.1', port=5000, debug=True)
    
                        
  9. Test Running App
  10. Klik icon Play atau icon Debug pada Pycharm IDE untuk menjalankan aplikasi.

    running app

    Setelah icon diklik dan jika tidak ada error, maka pada jendela console akan tampil url untuk menjalankan aplikasi di web browser.

    running app

    Berikut tampilan OpenCV Color Detection Web Application:

    running app

2. Upload node-pixel Firmata ke Arudino Uno

Untuk cara upload node-pixel Firmata bisa dilihat di laman github-nya ajfisher yaitu https://github.com/ajfisher/node-pixel

3. Membuat Runtime Environment EventSource Client Menggunakan node.js

Langkah-langkahnya adalah sebagai berikut:

  1. Buat folder project di direktori yang anda inginkan.
  2. Di tutorial ini saya membuat folder j5_sse_client di dalam folder E:\triyonos\

  3. Install Johnny-Five, node-pixel dan eventSource Melalui Node Package Manager (npm)
  4. npm install Johnny-Five
  5. Edit File Javascript index.js
  6. Klik kanan file index.js kemudian Edit with Notepad++. Copy paste kode javascript di bawah ini:

    const pixel = require("node-pixel");
    var EventSource = require('eventsource')
    
    var eventSource = new EventSource("http://127.0.0.1:5000/sse_rgb")
    
    const {Board} = require("johnny-five");
    const board = new Board({ port: "COM11" });
    
    var strip = null;
    
    board.on("ready", function() {
        strip = new pixel.Strip({
            board: this,
            controller: "FIRMATA",
            strips: [ {pin: 7, length: 12}, ],
            gamma: 2.8,
        });
        
        eventSource.addEventListener("online", function(e) {
            console.log(e.data)
    
            var jsonObject = JSON.parse(e.data.toString());
    
            var red = jsonObject.red;
            var green = jsonObject.green;
            var blue = jsonObject.blue;
            
            for (var i = 0; i < strip.length; i++) {
                strip.pixel( i ).color( [red, green, blue] );
            }
                
            strip.show();
          
        }, true)
    });
    
                        

4. Rangkaian Arduino Uno & LED Strip WS2812

Setelah Arduino Uno diupload program Firmata seperti pada tahapan nomor 2, hubungkan pin-pin LED strip ke pin-pin Arduino Uno seperti pada wiring diagram berikut ini:

running app

5. Running app.py dan index.js bersama-sama



Untuk lebih jelasnya silakan tonton video dari channel youtube Kode Erik di bawah ini. Kalau ada pertanyaan silakan komen di youtube dan jangan lupa subscribe: