Tham chiếu SDK
Trang này là bản đồ API để mở song song với editor khi viết code: toàn bộ method công khai của Nextwaves SDK 1.0.0, xếp theo việc. Nếu bạn đang đọc tài liệu lần đầu, bắt đầu từ bắt đầu nhanh và đọc thẻ rồi hãy quay lại đây. Cả năm package dùng chung một bộ khái niệm; tên method theo quy ước của từng ngôn ngữ.
Trạng thái đầu đọc
Gần như mọi quy tắc "gọi được lúc nào" trên trang này rút về một sơ đồ:
Đầu đọc chỉ nhận lệnh cấu hình khi đang idle. Muốn đổi cấu hình giữa lúc kiểm kê, dừng trước rồi đổi, chi tiết ở đọc thẻ và chống trùng.
Tạo đối tượng reader
| Ngôn ngữ | Hàm khởi tạo | Ghi chú |
|---|---|---|
| Python | create_reader(port, baudrate=115200, timeout=0.5, log_level=logging.INFO) | Trả về NRNReader đã cấu hình; dạng trực tiếp là NRNReader(port, baudrate, timeout, logger) |
| TypeScript | createNRNReader({ baudrate, timeout, onLog }) | Trả về NRNWebSerial; không có tham số port vì trình duyệt chọn cổng |
| Go | nrn.NewNRNReader(portName, baudrate) | NewNRNReaderWithTransport nhận mọi kiểu triển khai io.ReadWriteCloser có SetReadTimeout và ResetInputBuffer, tiện inject test double |
| Rust | NRNReader::new(port_name, baudrate) | Trả về Result<NRNReader> |
| C++ | nrn::NRNReader(port, baudrate = 115200, timeout_ms = 500) | Gọi open() trước khi dùng |
Kết nối
| Việc cần làm | Python | TypeScript | Go | Rust | C++ |
|---|---|---|---|---|---|
| Mở port | open() | connect() | mở trong constructor | mở trong constructor | open() |
| Handshake | Connect_Reader_And_Initialize() | connect() | ConnectAndInitialize() | connect_and_initialize() | connect_and_initialize() |
| Đóng | close() | disconnect() | Close() | tự đóng khi drop | close() |
| Trạng thái port | uart.is_open() | getReaderInfo().isConnected | báo lỗi ở lần ghi kế tiếp | báo lỗi ở lần ghi kế tiếp | is_open() |
NRNWebSerial.connect() mở port và handshake trong một lần gọi. NRNWebSerial.isSupported() cho biết trình duyệt có Web Serial API không.
Ở bản 1.0.0, năm package không tính checksum của frame giống nhau. Python và TypeScript dùng CRC16 đa thức 0x1021; Go, Rust và C++ dùng 0x8005. Mọi lệnh mà ba package này gửi, và phép kiểm tra hợp lệ trong ParseFrame / parse_frame của chúng, đều dùng 0x8005. Hãy thử package Go, Rust hoặc C++ với đầu đọc của bạn trước khi dựa vào nó, xem CRC16.
Danh tính và năng lực đầu đọc
info = reader.Query_Reader_Information()
ability = reader.query_rfid_ability()info gồm serial_number, power_on_time_sec, baseband_compile_time, app_version, os_version và app_compile_time. ability gồm min_power_dbm, max_power_dbm, antenna_count, frequencies và rfid_protocols.
Method tương đương: queryReaderInformation() (TypeScript, bản này không có lệnh truy vấn năng lực), QueryReaderInformation() và QueryRFIDAbility() (Go), query_reader_information() và query_rfid_ability() (Rust và C++). Truy vấn năng lực trước rồi hãy đặt công suất: đầu đọc tự khai dải hợp lệ của nó, và giá trị bạn đặt nên nằm gọn trong dải đó.
Kiểm kê
reader.start_inventory_with_mode(antenna_mask=[1, 2], callback=on_tag)
reader.stop_inventory()
reader.is_inventory_running()| Ngôn ngữ | Bắt đầu | Tham số ăng-ten | Dừng |
|---|---|---|---|
| Python | start_inventory_with_mode(antenna_mask, callback) | danh sách cổng đánh số từ 1 | stop_inventory() |
| TypeScript | startInventory(antennaMask, callback) | mảng cổng đánh số từ 1 | stopInventory() |
| Go | StartInventory(antennaMask, callback) | mask 32-bit, dựng bằng BuildAntennaMask | StopInventory() |
| Rust | start_inventory(antenna_mask, callback) | mask 32-bit, dựng bằng build_antenna_mask | stop_inventory() |
| C++ | start_inventory(antenna_mask, callback, include_tid) | mask 32-bit, dựng bằng build_antenna_mask | stop_inventory() |
Python và Web Serial giao thẻ qua callback bằng vòng đọc có sẵn. Ở Go, Rust và C++ bản 1.0.0, lệnh start inventory chỉ gửi lệnh bắt đầu: callback được nhận nhưng không bao giờ được gọi. Để nhận thẻ ở ba ngôn ngữ này, ghép thêm receive loop theo phụ lục. Ở Python, chỉ gọi is_inventory_running() sau một lần start hoặc stop, vì cờ mà nó đọc chưa tồn tại trước đó.
Dữ liệu thẻ
interface TagData {
epc: string;
pc: string;
antenna_id: number;
rssi: number | null;
tid?: string;
phase?: number;
frequency?: number;
}epc: nội dung EPC bank dạng chuỗi hex viết hoa.pc: Protocol Control word dạng hex, xem thuật ngữ.antenna_id: cổng ăng-ten đã đọc được thẻ, đánh số từ 1. Giữ trường này xuyên suốt để biết lần đọc đến từ khu vực nào.rssi: cường độ tín hiệu tính bằng dBm, SDK đã quy đổi từ byte thô. Bằngnull(Nonetrong Python) khi đầu đọc không kèm tham số RSSI.tid: nội dung TID bank dạng hex, chỉ có khi yêu cầu đọc TID.phase: phase của thẻ tính bằng radian, quy đổi từ giá trị thô 0 tới 128.frequency: tần số kênh tính bằng MHz.
Go dùng TagData{EPC, PC, AntennaID, RSSI, TID, Phase, Frequency} với trường tùy chọn ở dạng pointer; Rust và C++ dùng Option<T> và std::optional<T>. Python trả về dict với đúng các key như interface TypeScript.
Một thẻ nằm trong vùng đọc sinh notification ở mỗi vòng quét, nên trước khi biến lần đọc thành sự kiện nghiệp vụ, áp cửa sổ chống trùng của bạn theo đọc thẻ và chống trùng.
Công suất
reader.configure_reader_power({1: 30, 2: 25}, persistence=True)
powers = reader.query_reader_power()query_reader_power trả về map cổng sang dBm, ví dụ {1: 30, 2: 25, 3: 30, 4: 30}. persistence=True ghi thiết lập để giữ lại sau khi tắt nguồn. Python từ chối cổng ngoài 1 tới 64 và công suất ngoài 0 tới 33 dBm, rồi trả về False. TypeScript có configureReaderPower(antennaPowers, persistence) / queryReaderPower(). Go, Rust và C++ có cặp tương ứng ConfigurePower(powers, persist) / QueryPower() và configure_power / query_power.
Ăng-ten
mask = reader.build_antenna_mask([1, 4, 7, 32]) # 0x80000049
reader.enable_ant(4, save=True)
reader.disable_ant(2, save=True)
reader.query_enabled_ant_mask()
reader.save_antenna_mask(mask)Mask là bitmask 32-bit, ăng-ten n nằm ở bit n - 1. Hàm tự do BuildAntennaMask (Go) và build_antenna_mask (Rust, C++) làm cùng phép chuyển đổi. Bản Web Serial tự chuyển đổi bên trong: chỉ cần truyền mảng số cổng cho startInventory.
RF band, tần số và baseband
Nhóm method này thuộc bản Python. Mẫu triển khai gọn cho client trình duyệt: cấu hình đầu đọc một lần từ Python hoặc công cụ của hãng, lưu bằng persist, rồi để client Web Serial chỉ chạy kiểm kê.
| Method | Mục đích |
|---|---|
query_rf_band() / set_rf_band(band_code, persist) | Đọc và đặt band theo vùng |
query_working_frequency() | Đọc danh sách kênh đang dùng |
select_profile(profile_id) / get_profile() | Baseband profile, RF_PROFILES chứa id 0, 1, 2 |
configure_baseband(speed, q_value, session, inventory_flag) / query_baseband_profile() | Speed, Q, session và inventory flag, xem thuật ngữ |
get_session() | Session Gen2 hiện tại |
set_filter_settings(repeated_time_ms, rssi_threshold) / query_filter_settings() | Cửa sổ chống trùng phía đầu đọc và ngưỡng RSSI |
SDK phát đúng cấu hình bạn đặt, nên việc chọn band và kênh hợp pháp tại nơi lắp là trách nhiệm của thiết kế; danh sách kiểm cuối nằm ở kiểm tra production.
Ghi EPC
Bản Python có ba đường ghi:
reader.write_epc_tag(epc_hex, antenna_id=1, match_epc_hex=None) # start word tường minh
reader.write_epc_tag_auto(new_epc_hex, match_epc_hex=None) # tự tính PC bits và start word
reader.write_epc_to_target_auto(target_tag_epc, new_epc_hex) # quét tìm thẻ rồi ghiwrite_epc_tag trả về dict gồm success, result_code, result_msg và failed_addr. validate_epc_hex(epc_hex) raise ValueError khi gặp ký tự không phải hex hoặc số chữ số lẻ, và trả về bytes đã đệm cho tròn word.
check_write_epc(epc_hex) chưa xác minh lần ghi ở bản 1.0.0. Hàm này bắt đầu kiểm kê trên ăng-ten 1 với một callback chỉ ghi log việc có thấy EPC mong đợi hay không, trả về True ngay, và để nguyên lần kiểm kê đó đang chạy. Hãy tự đọc lại thẻ bằng inventory callback của bạn, so EPC, rồi dừng kiểm kê. Luôn đọc lại sau khi ghi, và chỉ ghi khi giá trị đã encode cùng món hàng đích được xác minh độc lập; quy trình đầy đủ ở mã hóa EPC.
GPIO
ConfigureGPO(gpoID, state) và QueryGPI(gpiID) có ở bản Go; configure_gpo / query_gpi có ở Rust và C++, dùng cho đầu đọc có cổng GPIO, ví dụ bật đèn hay mở chắn. Bản Python và Web Serial chưa có method GPIO ở bản 1.0.0. Trong lúc chưa có, chạy phần GPIO qua một tiến trình Go, Rust hoặc C++ nhỏ, lưu ý phần checksum ở mục Kết nối.
Còi
reader.set_beeper(BEEPER_MODES["BEEP_AFTER_TAG"])
reader.get_beeper()BEEPER_MODES gồm QUIET (0x00), BEEP_AFTER_INVENTORY (0x01) và BEEP_AFTER_TAG (0x02). Ở bản Python 1.0.0, 0 gửi lệnh tắt còi và 1 cho còi kêu ngay. 2 chỉ ghi chế độ vào SDK và không gửi gì; vòng kiểm kê không đọc giá trị này, nên không có tiếng bíp theo từng thẻ. get_beeper() trả về True khi chế độ đang lưu là 1 hoặc 2.
Lỗi
Python và TypeScript định nghĩa một bộ exception phân cấp:
from nrn import (
NextwavesSDKError, # lớp gốc
ConnectionError, # mở port, mất port
ProtocolError, # dữ liệu truyền nhận không hợp lệ
ConfigurationError, # công suất, mask, band không hợp lệ
TagOperationError, # ghi hoặc lock thất bại
)TypeScript phản chiếu cấu trúc này với lớp gốc NRNWebSerialError và bốn lớp con tương ứng. Rust trả về Result<T, NRNError>, Go trả về error đã wrap, còn C++ báo lỗi qua giá trị bool và struct kết quả rỗng.
Ở bản Python 1.0.0, ConnectionError là lớp duy nhất trong bộ này được raise: khi mở port thất bại, hoặc khi gửi hay nhận trên port đã đóng. Ba lớp còn lại đã được định nghĩa nhưng chưa được raise. Phần lớn method ghi log rồi trả về False, {} hoặc một dict kết quả, nên hãy kiểm tra giá trị trả về. Lỗi bên trong thread kiểm kê, như đầu đọc USB bị rút giữa chừng, chỉ được ghi log và vòng lặp vẫn chạy; lỗi không tới tag callback cũng không tới thread của bạn. Theo dõi tốc độ nhận thẻ để phát hiện mất đầu đọc.
Log
reader.set_log_level(logging.DEBUG)TypeScript nhận callback onLog(level, message) trong tham số khởi tạo, C++ dùng set_log_callback. Go dùng package log chuẩn, Rust dùng facade của crate log. Log mức debug ghi cả dữ liệu thô của từng lần đọc, nên chỉ bật khi gỡ lỗi và tắt trên production, nơi log có thể dính định danh hàng hóa và khách hàng.
Các tiện ích tầng thấp để tự dựng và mổ dữ liệu, cho người viết công cụ riêng hoặc receive loop, nằm ở phụ lục giao thức đầu đọc NRN.
Thông tin SDK
NRNReader.get_sdk_info() (Python) và NRNWebSerial.getSDKInfo() (TypeScript) trả về tên và phiên bản SDK. Ghi log giá trị này lúc mở phiên, để mỗi ticket hỗ trợ có sẵn bản SDK bên cạnh firmware của đầu đọc.
Đọc tiếp
- Đọc thẻ và chống trùng: cách dùng các method này thành một pipeline hoàn chỉnh.
- Phụ lục: giao thức đầu đọc NRN: tầng frame và các tiện ích đi kèm.
- Thuật ngữ RFID cho dev: session, Q, TID và các khái niệm trong bảng trên.

