Kết nối với thiết bị

IoT Driver cho phép bất kỳ module Odoo nào giao tiếp theo thời gian thực với bất kỳ thiết bị nào được kết nối với IoT Box. Việc giao tiếp với IoT Box diễn ra theo cả hai chiều, vì vậy Odoo client có thể gửi lệnh đến và nhận thông tin từ bất kỳ thiết bị nào được hỗ trợ.

Để thêm hỗ trợ cho một thiết bị, tất cả những gì chúng ta cần là:

  • một Interface, để phát hiện các thiết bị đã kết nối thuộc một loại cụ thể

  • một Driver, để giao tiếp với từng thiết bị riêng lẻ

Ở mỗi lần khởi động, IoT Box sẽ tải tất cả các Interface và Driver có thể tìm thấy trên instance Odoo đang kết nối. Mỗi module có thể chứa một thư mục iot_handlers sẽ được sao chép sang IoT Box. Cấu trúc của thư mục này như sau

your_module
├── ...
└── iot_handlers
    ├── drivers
    │   ├── DriverName.py
    │   └── ...
    │
    └── interfaces
        ├── InterfaceName.py
        └── ...

Phát hiện thiết bị

Các thiết bị kết nối với IoT Box được phát hiện thông qua Interface. Có một Interface cho mỗi loại kết nối được hỗ trợ (USB, Bluetooth, Video, máy in, Serial, v.v.). Interface duy trì một danh sách các thiết bị đã phát hiện và liên kết chúng với Driver phù hợp.

Các thiết bị được hỗ trợ sẽ xuất hiện cả trên trang chủ của IoT Box mà bạn có thể truy cập qua địa chỉ IP của nó, lẫn trong module IoT của instance Odoo đang kết nối.

Interface

Vai trò của Interface là duy trì một danh sách các thiết bị được kết nối qua một loại kết nối xác định. Việc tạo một interface mới đòi hỏi

  • Kế thừa (mở rộng) class Interface

  • Thiết lập thuộc tính class connection_type

  • Triển khai phương thức get_devices, phương thức này phải trả về một dictionary chứa dữ liệu về từng thiết bị đã phát hiện. Dữ liệu này sẽ được truyền làm argument cho các constructor và phương thức supported của các Driver.

Ghi chú

Thiết lập thuộc tính _loop_delay sẽ thay đổi khoảng thời gian giữa các lần gọi get_devices. Theo mặc định, khoảng thời gian này được đặt là 3 giây.

from odoo.addons.hw_drivers.interface import Interface

class InterfaceName(Interface):
    connection_type = 'ConnectionType'

    def get_devices(self):
        return {
            'device_identifier_1': {...},
            ...
        }

Driver

Sau khi interface đã lấy được danh sách các thiết bị đã phát hiện, nó sẽ lặp qua tất cả các Driver có cùng thuộc tính connection_type và kiểm tra phương thức supported tương ứng của chúng trên tất cả các thiết bị đã phát hiện. Nếu phương thức supported của một Driver trả về True, một instance của Driver này sẽ được tạo cho thiết bị tương ứng.

Ghi chú

Các phương thức supported của driver được sắp xếp theo một thứ tự ưu tiên. Phương thức supported của class con luôn được kiểm tra trước class cha của nó. Thứ tự ưu tiên này có thể được điều chỉnh bằng cách thay đổi thuộc tính priority của Driver.

Việc tạo một Driver mới đòi hỏi:

  • Kế thừa (mở rộng) Driver

  • Thiết lập thuộc tính class connection_type.

  • Thiết lập các thuộc tính device_type, device_connection và device_name.

  • Định nghĩa phương thức supported

from odoo.addons.hw_drivers.driver import Driver

class DriverName(Driver):
    connection_type = 'ConnectionType'

    def __init__(self, identifier, device):
        super(NewDriver, self).__init__(identifier, device)
        self.device_type = 'DeviceType'
        self.device_connection = 'DeviceConnection'
        self.device_name = 'DeviceName'

    @classmethod
    def supported(cls, device):
        ...

Giao tiếp với thiết bị

Sau khi thiết bị mới của bạn được phát hiện và xuất hiện trong module IoT, bước tiếp theo là giao tiếp với nó. Vì box chỉ có địa chỉ IP cục bộ, nó chỉ có thể được truy cập từ cùng một mạng cục bộ. Do đó, việc giao tiếp cần diễn ra ở phía trình duyệt, bằng JavaScript.

Quy trình phụ thuộc vào chiều giao tiếp: - Từ trình duyệt đến box, thông qua Actions - Từ box đến trình duyệt, thông qua Longpolling

Cả hai kênh này đều được truy cập từ cùng một đối tượng JS là DeviceProxy, đối tượng này được khởi tạo bằng địa chỉ IP của IoT Box và định danh của thiết bị.

var DeviceProxy = require('iot.DeviceProxy');

var iot_device = new DeviceProxy({
    iot_ip: iot_ip,
    identifier: device_identifier
});

Actions

Actions được dùng để yêu cầu một thiết bị đã chọn thực hiện một hành động cụ thể, chẳng hạn như chụp ảnh, in hóa đơn, v.v.

Ghi chú

Cần lưu ý rằng box sẽ không gửi bất kỳ “câu trả lời” nào qua tuyến này, chỉ có trạng thái của yêu cầu. Câu trả lời cho action, nếu có, phải được lấy thông qua longpolling.

Một action có thể được thực hiện trên đối tượng DeviceProxy.

iot_device.action(data);

Trong driver của bạn, hãy định nghĩa một phương thức action sẽ được thực thi khi được gọi từ một module Odoo. Phương thức này nhận dữ liệu được truyền trong lúc gọi làm argument.

def action(self, data):
    ...

Longpolling

Khi bất kỳ module nào trong Odoo muốn đọc dữ liệu từ một thiết bị cụ thể, nó sẽ tạo một listener được định danh bởi IP/domain của box và định danh của thiết bị, đồng thời truyền cho listener đó một hàm callback để gọi mỗi khi trạng thái thiết bị thay đổi. Callback được gọi với dữ liệu mới làm argument.

iot_device.add_listener(this._onValueChange.bind(this));

_onValueChange: function (result) {
    ...
}

Trong Driver, một sự kiện được phát ra bằng cách gọi hàm device_changed từ event_manager. Tất cả các callback được thiết lập trên listener khi đó sẽ được gọi với self.data làm argument.

from odoo.addons.hw_drivers.event_manager import event_manager

class DriverName(Driver):
    connection_type = 'ConnectionType'

    def methodName(self):
        self.data = {
            'value': 0.5,
            ...
        }
        event_manager.device_changed(self)