Lệnh location (nodes)

TL;DR

  • location.get là lệnh của node (thông qua node.invoke).
  • Mặc định tắt.
  • Cài đặt dùng selector: Off / While Using / Always.
  • Toggle riêng: Precise Location.

Tại sao dùng selector (không chỉ là switch)

Quyền của hệ điều hành có nhiều cấp độ. Mình có thể hiển thị selector trong app, nhưng hệ điều hành vẫn là người quyết định cấp quyền thực sự.

  • iOS/macOS: người dùng có thể chọn While Using hoặc Always trong system prompts/Settings. App có thể yêu cầu nâng cấp, nhưng hệ điều hành có thể yêu cầu vào Settings.
  • Android: quyền location chạy nền là quyền riêng biệt; trên Android 10+ thường yêu cầu phải vào Settings.
  • Precise location là quyền riêng (iOS 14+ “Precise”, Android “fine” vs “coarse”).

Selector trong giao diện điều khiển chế độ mình yêu cầu; quyền thực sự nằm trong cài đặt hệ điều hành.

Mô hình cài đặt

Cho mỗi node device:

  • location.enabledMode: off | whileUsing | always
  • location.preciseEnabled: bool

Hành vi giao diện:

  • Chọn whileUsing sẽ yêu cầu quyền foreground.
  • Chọn always trước tiên đảm bảo whileUsing, sau đó yêu cầu quyền background (hoặc đưa người dùng vào Settings nếu cần).
  • Nếu hệ điều hành từ chối cấp độ yêu cầu, quay về cấp độ cao nhất được cấp và hiển thị trạng thái.

Ánh xạ permissions (node.permissions)

Tùy chọn. macOS node báo cáo location qua permissions map; iOS/Android có thể bỏ qua.

Lệnh: location.get

Gọi thông qua node.invoke.

Params (gợi ý):

{
  "timeoutMs": 10000,
  "maxAgeMs": 15000,
  "desiredAccuracy": "coarse|balanced|precise"
}

Response payload:

{
  "lat": 48.20849,
  "lon": 16.37208,
  "accuracyMeters": 12.5,
  "altitudeMeters": 182.0,
  "speedMps": 0.0,
  "headingDeg": 270.0,
  "timestamp": "2026-01-03T12:34:56.000Z",
  "isPrecise": true,
  "source": "gps|wifi|cell|unknown"
}

Errors (mã ổn định):

  • LOCATION_DISABLED: selector đang tắt.
  • LOCATION_PERMISSION_REQUIRED: thiếu quyền cho chế độ yêu cầu.
  • LOCATION_BACKGROUND_UNAVAILABLE: app đang chạy nền nhưng chỉ được phép While Using.
  • LOCATION_TIMEOUT: không lấy được vị trí kịp thời gian.
  • LOCATION_UNAVAILABLE: lỗi hệ thống / không có providers.

Hành vi chạy nền (tương lai)

Mục tiêu: model có thể yêu cầu location ngay cả khi node đang chạy nền, nhưng chỉ khi:

  • Người dùng chọn Always.
  • Hệ điều hành cấp quyền background location.
  • App được phép chạy nền cho location (iOS background mode / Android foreground service hoặc quyền đặc biệt).

Luồng kích hoạt bằng push (tương lai):

  1. Gateway gửi push đến node (silent push hoặc FCM data).
  2. Node thức dậy trong thời gian ngắn và yêu cầu location từ thiết bị.
  3. Node chuyển tiếp payload đến Gateway.

Lưu ý:

  • iOS: Cần quyền Always + background location mode. Silent push có thể bị throttle; có thể gặp lỗi không liên tục.
  • Android: background location có thể yêu cầu foreground service; nếu không, có thể bị từ chối.

Tích hợp Model/tooling

  • Tool surface: nodes tool thêm action location_get (cần node).
  • CLI: openclaw nodes location get --node <id>.
  • Agent guidelines: chỉ gọi khi người dùng đã bật location và hiểu rõ phạm vi.

UX copy (gợi ý)

  • Off: “Location sharing is disabled.”
  • While Using: “Only when OpenClaw is open.”
  • Always: “Allow background location. Requires system permission.”
  • Precise: “Use precise GPS location. Toggle off to share approximate location.”