HƯỚNG DẪN SỬ DỤNG INUT CẢM BIẾN VÀ NODE RED IDE ĐỂ HIỆN THỊ BIỂU ĐỒ THỜI TIẾT

Mô Tả Dự án

Chào các bạn, hôm nay mình sẽ cùng các bạn làm một ví dụ điển hình về thế mạnh của iNut Node - RED IDE. Đặt vấn đề đơn giản thế này, nếu bây giờ các bạn muốn làm một giao diện về biểu đồ ( biểu đồ gió, mưa, lưu lượng nước v.v..) thì sao nhỉ, với những bạn không phải chuyên về làm phần mềm hay làm web mà chỉ quen làm phần cứng (như mình) thì ôi thôi, vấn đề làm front-end, back-end cho web nó quá xa vời với mình, chưa kể còn đồng bộ dữ liệu theo thời gian thực, v.v.. Suy nghĩ mới tới đó là thấy có quá nhiều rào cản để một hardware-er như tụi mình muốn làm một dự án IOT nhỏ để giám sát bằng biểu đồ. 

Nhưng, với iNut Node - RED IDE, bạn sẽ không phải lo lắng vấn đề giao diện nữa, chỉ cần những khối lệnh kéo thả đơn giản là bạn đã có thể làm ra một giao diện đơn giản để giám sát rồi. Thần kì phải không nào, trong bài viết lần này, mình sẽ hướng dẫn bạn cách sử dụng iNut cảm biến và iNut Node RED - IDE để làm việc này. Bắt tay vào làm nhé.

I. Bạn Cần Chuẩn Bị Những Gì?

Phần Cứng

Phần cứng như vậy là đủ ,tất cả các thông số mình sẽ random, chủ yếu là mình sẽ hướng dẫn cách xài iNut Node - RED IDE tạo biểu đồ, các bạn làm project có thể gán các biến hoặc thông số của các bạn vào phần mình random là được, chi tiết mình sẽ comment ở Code cho các bạn.

Phần Mềm

  • Trên điện thoại di động:
    • iNut - Công tắc wifi (các bạn search trong apple store hoặc google play từ khóa inut là ra). Tải về trên Apple Store, tải về ở Google Play.
  • Trên máy tính:

Nếu bạn chưa biết,tham khảo bài biết này để cài đặt môi trường cho iNut Node RED IDE nhé: http://arduino.vn/i...

Thư Viện: thư viện cho iNut cảm biến cho Arduino các bạn có thể tải về ở đây https://github.com/ngohuynhngockhanh... (tải nhanh)

II. Các Cài Đặt Khác

III. Lập Trình

Code Arduino

#include <iNut.h> //thư viện iNut Cảm Biến
iNut sensor;
void setup() {
  Serial.begin(9600); //bật baudrate ở mức 9600

  Serial.println("San sang nhan lenh");
  
  //Khai báo số lượng luồn cảm biến
  sensor.setup(3); //Sẽ có 03 luồn cảm biến (tối đa 8 luồng cảm biến, tùy vào cách bạn sử dụng)
}

void loop() {
  unsigned long value_gio = random() % 1000; //random tốc độ gió từ 0 m/s đến 1000m/s
  // tùy vào tình hình thực tế các bạn đưa vào đúng đơn vị và vận tốc gió nhé.
  unsigned long value_huonggio = random() % 16;
  //random 16 hướng cho chính xác luôn để làm hình la bàn cho dễ.
//  0:Bắc             4:Đông            8:Nam             12:Tây
//  1:Bắc Đông Bắc    5:Đông Đông Nam   9:Nam Tây Nam    13:Tây Tây Bắc
//  2:Đông Bắc        6:Đông Nam        10:Tây Nam        14:Tây Bắc
//  3:Đông Đông Bắc   7:Nam Đông Nam    11:Tây Tây Nam    15:Bắc Tây Bắc
  unsigned long value_luongmua = random() % 1000; //đơn vị là mm nha các bạn.
  //nhiều nơi ngập lụt thì mưa lượng mưa cao lắm, mình lấy đại diện từ 0->1000mm
  // để các bạn xem biểu đồ hoạt động như thế nào thôi nha.
  sensor.setValue(0,value_gio); // luồng cảm biến "thứ 0" hiện thị thông số gió mà iNut Cảm biến gửi lên
  sensor.setValue(1,value_huonggio);// luồng cảm biến "thứ 1" hiển thị thông số hướng gió.....
  sensor.setValue(2,value_luongmua);// luồng cảm biến "thứ 2" hiển thị thông số lưu lượng mưa.
  sensor.loop();
}

Code iNut Node - RED IDE

https://ideone.com/vHiMTO (các bạn copy đoạn code này về rồi import vào iNut Node RED IDE theo hướng dẫn phía dưới)

[
    {
        "id": "beb272e1.718f2",
        "type": "subflow",
        "name": "Lấy dữ từ iNut",
        "info": "",
        "in": [
            {
                "x": 50,
                "y": 30,
                "wires": [
                    {
                        "id": "a1b88fc4.64d4b"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 1000,
                "y": 180,
                "wires": [
                    {
                        "id": "88c2dcd2.643f1",
                        "port": 0
                    }
                ]
            },
            {
                "x": 1000,
                "y": 260,
                "wires": [
                    {
                        "id": "88c2dcd2.643f1",
                        "port": 1
                    }
                ]
            },
            {
                "x": 980,
                "y": 320,
                "wires": [
                    {
                        "id": "88c2dcd2.643f1",
                        "port": 2
                    }
                ]
            }
        ],
        "inputLabels": [
            "Nhận đầu vào MQTT IN từ iNut cảm biến"
        ],
        "outputLabels": [
            "Luồng cảm biến 1",
            "Luồng cảm biến 2",
            "Luồng cảm biến 3",
            "Luồng cảm biến 4",
            "Luồng cảm biến 5",
            "Luồng cảm biến 6",
            "Luồng cảm biến 7",
            "Luồng cảm biến 8"
        ]
    },
    {
        "id": "a1b88fc4.64d4b",
        "type": "json",
        "z": "beb272e1.718f2",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 165,
        "y": 84,
        "wires": [
            [
                "539af8f6.6de3f8"
            ]
        ]
    },
    {
        "id": "88c2dcd2.643f1",
        "type": "switch",
        "z": "beb272e1.718f2",
        "name": "Phân luồn",
        "property": "relayId",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "0",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "1",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "2",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 825.9869575500488,
        "y": 288.1562738418579,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "539af8f6.6de3f8",
        "type": "function",
        "z": "beb272e1.718f2",
        "name": "Lặp",
        "func": "if (!msg.states) {\n    msg.states = msg.payload\n    msg.i = 0\n    return msg;\n} else {\n    msg.i++\n    if (msg.states[msg.i])\n        return msg;\n}\n",
        "outputs": 1,
        "noerr": 0,
        "x": 327.89060974121094,
        "y": 83.33600330352783,
        "wires": [
            [
                "c5938e3d.d1fbb"
            ]
        ]
    },
    {
        "id": "c5938e3d.d1fbb",
        "type": "function",
        "z": "beb272e1.718f2",
        "name": "Lấy trạng thái thiết bị",
        "func": "msg.relayId = msg.i\nmsg.payload = msg.states[msg.i].state\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 477.89060974121094,
        "y": 183.33600330352783,
        "wires": [
            [
                "539af8f6.6de3f8",
                "88c2dcd2.643f1"
            ]
        ]
    },
    {
        "id": "689bf8e4.989f18",
        "type": "ui_gauge",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "group": "352403e1.779a5c",
        "order": 1,
        "width": "6",
        "height": "3",
        "gtype": "gage",
        "title": "Hướng Gió",
        "label": "",
        "format": "{{value}}",
        "min": 0,
        "max": "15",
        "colors": [
            "#1f964f",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 790,
        "y": 660,
        "wires": []
    },
    {
        "id": "960a236b.cc49c",
        "type": "ui_gauge",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "group": "156c2391.cc456c",
        "order": 1,
        "width": "6",
        "height": "3",
        "gtype": "gage",
        "title": "Gió",
        "label": "m/s",
        "format": "{{value}}",
        "min": 0,
        "max": "1000",
        "colors": [
            "#1f964f",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 730,
        "y": 480,
        "wires": []
    },
    {
        "id": "a0b0981d.3c98b8",
        "type": "subflow:beb272e1.718f2",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "x": 380,
        "y": 600,
        "wires": [
            [
                "79c342d6.f2cabc"
            ],
            [
                "482febe8.68e5a4"
            ],
            [
                "62ab0033.45abf"
            ]
        ]
    },
    {
        "id": "62ca446c.63776c",
        "type": "ui_gauge",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "group": "add3a25d.5ad48",
        "order": 1,
        "width": "6",
        "height": "3",
        "gtype": "gage",
        "title": "Lưu Lượng Mưa",
        "label": "mm",
        "format": "{{value}}",
        "min": 0,
        "max": "1000",
        "colors": [
            "#1f964f",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 760,
        "y": 720,
        "wires": []
    },
    {
        "id": "79c342d6.f2cabc",
        "type": "change",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "Gió",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 550,
        "y": 480,
        "wires": [
            [
                "5806ccec.5559b4",
                "960a236b.cc49c"
            ]
        ]
    },
    {
        "id": "5806ccec.5559b4",
        "type": "ui_chart",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "group": "156c2391.cc456c",
        "order": 2,
        "width": "6",
        "height": "6",
        "label": "Biểu Đồ Gió",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "Biểu Đồ Gió",
        "dot": false,
        "ymin": "-5",
        "ymax": "1000",
        "removeOlder": "2",
        "removeOlderPoints": "2000",
        "removeOlderUnit": "60",
        "cutout": 0,
        "useOneColor": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "useOldStyle": false,
        "outputs": 1,
        "x": 730,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "62ab0033.45abf",
        "type": "change",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "Lưu Lượng Mưa",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 550,
        "y": 720,
        "wires": [
            [
                "f69684ef.eef1f8",
                "62ca446c.63776c"
            ]
        ]
    },
    {
        "id": "f69684ef.eef1f8",
        "type": "ui_chart",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "group": "add3a25d.5ad48",
        "order": 2,
        "width": "6",
        "height": "6",
        "label": "Biểu Đồ Lưu Lượng Mưa",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "Biểu Đồ Lưu Lượng Mưa",
        "dot": false,
        "ymin": "-5",
        "ymax": "1000",
        "removeOlder": "2",
        "removeOlderPoints": "2000",
        "removeOlderUnit": "60",
        "cutout": 0,
        "useOneColor": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "useOldStyle": false,
        "outputs": 1,
        "x": 770,
        "y": 780,
        "wires": [
            []
        ]
    },
    {
        "id": "482febe8.68e5a4",
        "type": "change",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "Hướng Gió",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 570,
        "y": 600,
        "wires": [
            [
                "689bf8e4.989f18",
                "845ebb19.3c9908",
                "a5c752c0.0f0dd"
            ]
        ]
    },
    {
        "id": "845ebb19.3c9908",
        "type": "ui_gauge",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "group": "352403e1.779a5c",
        "order": 2,
        "width": "6",
        "height": "5",
        "gtype": "compass",
        "title": "La Bàn",
        "label": "NEWS",
        "format": "{{value}}",
        "min": "0",
        "max": "16",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 780,
        "y": 540,
        "wires": []
    },
    {
        "id": "a5c752c0.0f0dd",
        "type": "function",
        "z": "78f7e2bb.3b2d9c",
        "name": "Set Hướng Theo Yêu Cầu",
        "func": "var huong;\nif (msg.payload == 0) {\n    huong = \"Bắc\";\n}\nelse if (msg.payload == 1) {\n    huong = \"Bắc Đông Bắc\";\n}\nelse if (msg.payload == 2) {\n    huong = \"Đông Bắc\";\n}\nelse if (msg.payload == 3) {\n    huong = \"Đông Đông Bắc\";\n}\nelse if (msg.payload == 4) {\n    huong = \"Đông\";\n}\nelse if (msg.payload == 5) {\n    huong = \"Đông Đông Nam\";\n}\nelse if (msg.payload == 6) {\n    huong = \"Đông Nam\";\n}\nelse if (msg.payload == 7) {\n    huong = \"Nam Đông Nam\";\n}\nelse if (msg.payload == 8) {\n    huong = \"Nam\";\n}\nelse if (msg.payload == 9) {\n    huong = \"Nam Tây Nam\";\n}\nelse if (msg.payload == 10) {\n    huong = \"Tây Nam\";\n}\nelse if (msg.payload == 11) {\n    huong = \"Tây Tây Nam\";\n}\nelse if (msg.payload == 12) {\n    huong = \"Tây\";\n}\nelse if (msg.payload == 13) {\n    huong = \"Tây Tây Bắc\";\n}\nelse if (msg.payload == 14) {\n    huong = \"Tây Bắc\";\n}\nelse if (msg.payload == 15) {\n    huong = \"Bắc Tây Bắc\";\n}\nmsg.payload = huong;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 810,
        "y": 600,
        "wires": [
            [
                "554fc50e.66f75c"
            ]
        ]
    },
    {
        "id": "554fc50e.66f75c",
        "type": "ui_text",
        "z": "78f7e2bb.3b2d9c",
        "group": "352403e1.779a5c",
        "order": 2,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Hướng:",
        "format": "{{msg.payload}}",
        "layout": "row-center",
        "x": 1020,
        "y": 600,
        "wires": []
    },
    {
        "id": "1880698b.af4b96",
        "type": "mqtt in",
        "z": "78f7e2bb.3b2d9c",
        "name": "[MQTT-IN]LaCrosse",
        "topic": "request/5Wl5TpkHs7Sy2Zxav1W4GWlv6Yl1/H1Mlh33UN/4b9f9dc914442ac7bc3be38377832957717354287137",
        "qos": "2",
        "broker": "869a4e98.9ec2",
        "x": 150,
        "y": 560,
        "wires": [
            [
                "a0b0981d.3c98b8"
            ]
        ]
    },
    {
        "id": "235eeb7b.65a7d4",
        "type": "http request",
        "z": "78f7e2bb.3b2d9c",
        "name": "[REST][GET]LaCrosse",
        "method": "GET",
        "ret": "txt",
        "url": "https://c...content-available-to-author-only...e.vn/api/1.0/request/5Wl5TpkHs7Sy2Zxav1W4GWlv6Yl1/H1Mlh33UN/4b9f9dc914442ac7bc3be38377832957717354287137/req_device",
        "tls": "",
        "x": 380,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "4df422ed.0787cc",
        "type": "http request",
        "z": "78f7e2bb.3b2d9c",
        "name": "[REST][POST]LaCrosse",
        "method": "POST",
        "ret": "txt",
        "url": "https://c...content-available-to-author-only...e.vn/api/1.0/request/5Wl5TpkHs7Sy2Zxav1W4GWlv6Yl1/H1Mlh33UN/4b9f9dc914442ac7bc3be38377832957717354287137/req_device_toggle",
        "tls": "",
        "x": 120,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "145fa4ea.902d0b",
        "type": "mqtt in",
        "z": "78f7e2bb.3b2d9c",
        "name": "[MQTT-IN]iNut cảm biến - iNut S1",
        "topic": "request/5Wl5TpkHs7Sy2Zxav1W4GWlv6Yl1/By7KqT8pm/3083ebabca806130bb0f7a9eb703fa7d858976875246",
        "qos": "2",
        "broker": "c180542c.84e2d8",
        "x": 130,
        "y": 620,
        "wires": [
            []
        ]
    },
    {
        "id": "74454c1e.8ab6e4",
        "type": "inject",
        "z": "78f7e2bb.3b2d9c",
        "name": "",
        "topic": "",
        "payload": "3",
        "payloadType": "num",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 350,
        "y": 700,
        "wires": [
            [
                "482febe8.68e5a4"
            ]
        ]
    },
    {
        "id": "352403e1.779a5c",
        "type": "ui_group",
        "z": "",
        "name": "DATA 3",
        "tab": "418ca3dd.8ead5c",
        "order": 3,
        "disp": true,
        "width": "6",
        "collapse": true
    },
    {
        "id": "156c2391.cc456c",
        "type": "ui_group",
        "z": "",
        "name": "DATA 1",
        "tab": "418ca3dd.8ead5c",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": true
    },
    {
        "id": "add3a25d.5ad48",
        "type": "ui_group",
        "z": "",
        "name": "DATA 2",
        "tab": "418ca3dd.8ead5c",
        "order": 2,
        "disp": true,
        "width": "6",
        "collapse": true
    },
    {
        "id": "869a4e98.9ec2",
        "type": "mqtt-broker",
        "name": "",
        "broker": "mqtt.mysmarthome.vn",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": ""
    },
    {
        "id": "c180542c.84e2d8",
        "type": "mqtt-broker",
        "name": "",
        "broker": "mqtt.mysmarthome.vn",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": ""
    },
    {
        "id": "418ca3dd.8ead5c",
        "type": "ui_tab",
        "z": "",
        "name": "Thời Tiết",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

Giao Diện Làm Việc

 

Giao Diện iNut Node - RED IDE

IV. Cách Import Code Vào iNut Node RED IDE

Bước 1: bạn click vào 3 gạch ngang góc phải trên

Bước 2: Bạn vào Import -> Clipboard

Bước 3: vào link ideone phía trên mục Code iNut Node - RED IDE copy đoạn code và paste vào clipboard ở vị trí này

Bước 4: sau khi paste vào clipboard rồi thì bạn click vào Import

Bước 5: khi đã import xong, bạn sắp xếp các block lại cho đẹp bắt rồi bấm deploy là xong.

 

 

Bài viết này chủ yếu hướng dẫn cho bạn các thao tác cơ bản trên IDE của iNut. Dựa vào bài viết này và hãy sáng tạo thêm nhé. Liên hệ mình nếu cần hỗ trợ qua sđt: 037 3998 468

Như vậy là xong rồi, mở máy lên để tận hưởng kết quả của ngày hôm này nào, à đừng quên tự thưởng cho bản thân 1 lon bò húc mát lạnh nhé, chúc các bạn thành công.

lên
3 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Select any filter and click on Apply to see results

Các bài viết cùng tác giả

Tài Liệu Kỹ Thuật Bỏ Túi Để Xây Dựng – Vận Hành – Quản Lý Một Dự Án Internet Of Things Với iNut Platform

Kính chào quý vị và các bạn!

Lập trình Internet of Things được biết đến là một thứ vô cùng khó khăn và phức tạp. Nơi này, trước đây không phải dành cho tất cả mọi người. Nhưng, để đưa Việt Nam trở thành một cường quốc về công nghệ cao và đi tắt đón đầu nhờ cuộc cách mạng công nghệ 4.0 thì bài toán Internet of Things phải được giải quyết bằng chính trí tuệ của tất cả mọi người. Cuối cùng, để giải quyết được đồ thị Đa dụng và Dễ sử dụng, iNut Node-red IDE đã ra đời, giải pháp cung cấp một phương pháp sáng tạo, cho phép người dùng lập trình ứng dụng IoT bằng những khối lệnh kéo thả với những ví dụ ngay trong app. Ngay cả một học sinh tiểu học học STEM cũng có thể làm được. Hãy cùng khám phá nhé!

Mặc dù trên http://arduino.vn/ đã có rất nhiều bài viết về iNut nhưng chưa có một bài viết nào cụ thể dành cho các bạn newbie khi mới mua một bộ iNut cảm biến về thì phải làm như thế nào, bắt đầu từ đâu, các bước thực hiện như thế nào….? Bài viết này sẽ tổng hợp lại và hướng dẫn các bạn thực hiện setup từng bước một và demo 1 ví dụ cụ thể để các bạn có thể biết các iNut cảm biến vận hành thế nào nha. Ở mỗi mục mình sẽ trích dẫn link bài viết liên quan để các bạn tham khảo thêm, từ đó có cái nhìn tổng quát nhất khi mới bắt đầu sử dụng iNut cảm biến.

lên
7 thành viên đã đánh giá bài viết này hữu ích.

Nạp firmware cho Arduino bằng Xloader - Nạp chương trình cho Arduino bằng Xloader

Bài viết hôm nay sẽ hướng dẫn các bạn nạp file hex xuống Kit Arduino

Trong một số trường hợp bạn chỉ có File hex không có file chương trình hay muốn nạp cho nhiều mạch ứng dụng, dùng phần mềm Arduino IDE sẽ hơi bất tiện và mất nhiều thời gian hơn.

lên
11 thành viên đã đánh giá bài viết này hữu ích.