Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wln

wln is a small, deterministic CLI for exporting telemetry from Wialon Hosting or Wialon Local to analysis-ready CSV. It provides profile management, unit discovery, authenticated access to arbitrary Remote API services, unit creation, connectivity identity editing, and the server/port data needed to connect a tracker.

The implementation is written in Go and talks to Wialon only through the documented Remote API. It never prints access tokens or session IDs.

Install

macOS or Linux:

curl -fsSL https://raw.githubusercontent.com/Shooa/wln/main/install.sh | sh

Windows PowerShell:

irm https://raw.githubusercontent.com/Shooa/wln/main/install.ps1 | iex

Both installers detect the operating system and architecture, download the latest GitHub release, verify its SHA-256 checksum, and install wln and wlna in a per-user directory. The Unix installer uses ~/.local/bin; override the target on either platform with WLN_INSTALL_DIR.

Download the archive for your platform from the latest GitHub release:

Platform Intel/AMD 64-bit ARM 64-bit
Linux linux_amd64.tar.gz linux_arm64.tar.gz
macOS darwin_amd64.tar.gz darwin_arm64.tar.gz
Windows windows_amd64.zip windows_arm64.zip

Each release includes SHA256SUMS and both executable names. Extract the archive and put wln/wlna (or their .exe variants) somewhere on PATH.

Alternatively, with Go 1.23 or newer:

go install github.com/Shooa/wln/cmd/wln@latest

go install installs only the canonical wln name. Use the release installer or copy that executable to wlna to activate agent defaults by invocation name.

For a repository-local binary:

make build
./bin/wln --version
./bin/wlna --version

Built-in help

The help is hierarchical and does not require a configured profile or network access. Open a command group, a specific command, or one self-contained manual:

wln help
wln help messages
wln help messages get
wln messages get --help
wln help --all

Running a command group without a subcommand shows that level directly, so wln profile, wln units, wln messages, and wln api are also valid help entry points. A leaf command that cannot run without a positional argument also shows its complete help when invoked bare; for example, wln messages get includes every interval shortcut instead of returning a shortened usage line.

wln help --all is intended for shell agents and LLMs that have only the binary: it includes every command, argument, default, constraint, and example in one output.

Agent mode

wlna is the same executable under an agent-oriented name. It selects compact JSON by default for command results, version output, help, and errors, disables the automatic update prompt, and sends message downloads to stdout unless an output file is explicitly requested. Human-friendly wln behavior is unchanged. Explicit --format and --compact=false options override defaults.

wlna units get 1001
wlna units get 1001 --fields unit_id,unique_id,device_type,tcp_port
wlna units list --fields id,name,unique_id

Native messages export --output - is the intentional exception: it writes the requested binary export bytes to stdout.

Updates

wln checks GitHub Releases at startup at most once every 24 hours. When a new version is available in an interactive terminal, it offers to install the update before running the requested command. In non-interactive sessions it prints a notice and continues without prompting.

Check or update explicitly:

wln update --check
wln update

Release archives are always verified against SHA256SUMS before the executable is replaced. On Windows, a background helper finishes replacement immediately after the running process exits. Explicit wln update also creates or synchronizes the adjacent wlna command; invoking the update as wlna does the same for wln. Disable startup checks in automation when needed:

WLN_NO_UPDATE_CHECK=1 wln units list

Log in and create a profile

The normal login flow opens Wialon's authorization page in the system browser, listens on a one-time loopback callback, verifies the issued token with token/login, and then saves the profile:

wln profile login hosting \
  --server https://hosting.wialon.com \
  --default

--server is the base address of the Wialon installation containing login.html, not necessarily its Remote API address. Wialon Hosting returns wialon_sdk_url in the callback, so a login through hosting.wialon.com automatically stores hst-api.wialon.com. Wialon Local falls back to the same installation base address.

The default access value is 768 (0x100 + 0x200): online/message access plus viewing connectivity properties such as the unit unique ID. Wialon groups editing connectivity settings into the broad 0x1000 critical-data scope, which also includes destructive rights, so wln does not request it by default. Explicitly authorize a write-capable profile when needed:

wln profile login editor \
  --server https://hosting.wialon.com \
  --access 4864

The authenticated user must also have the Edit connectivity settings right to the unit. The default token duration is unlimited (0), though Wialon removes tokens after 100 days of inactivity. Useful options:

wln profile login local \
  --server https://wialon.example.test \
  --user operator \
  --lang ru \
  --duration 720h \
  --callback-timeout 10m

Use --no-open when the URL should be opened manually. The callback still must reach the same machine where wln is running.

Manual token fallback

If browser login is unavailable, do not put the token directly in a shell argument. Supply it through a temporary environment variable:

read -s WLN_TOKEN
export WLN_TOKEN
wln profile add hosting --server https://hst-api.wialon.com --default
unset WLN_TOKEN

Or pipe it on standard input:

security find-generic-password -w -s wialon-token |
  wln profile add hosting --token-stdin --default

Profiles are stored in the OS user configuration directory. The directory is created with mode 0700 and the JSON file with mode 0600. profile list never shows tokens:

wln profile list
wln profile use hosting
wln profile check hosting
wln profile remove old-profile

Use --profile NAME before the command to override the default profile:

wln --profile staging units list

Find a unit

wln units list
wln units list --search 'Truck*'
wln units list --format json
wln units list --format json --fields id,name,unique_id
wlna units get 1001

--search is a Wialon unit-name mask, not an IMEI search. JSON output uses stable CLI field names. Human-readable table output resolves Wialon hardware IDs through core/get_hw_types and uses Unicode borders:

┌──────┬──────────┬─────────────────┬───────────┐
│ ID   │ NAME     │ UNIQUE ID       │ HARDWARE  │
├──────┼──────────┼─────────────────┼───────────┤
│ 1001 │ Truck 01 │ 123456789012345 │ Tracker X │
└──────┴──────────┴─────────────────┴───────────┘

JSON retains both the readable name and raw Wialon ID:

[
  {
    "id": 1001,
    "name": "Truck 01",
    "unique_id": "123456789012345",
    "hardware": "Tracker X",
    "hardware_id": 42
  }
]

Device types and connection settings

Find the exact device type and its numeric Wialon ID:

wln units device-types --search Teltonika
wln units device-types --search Teltonika --format json

Show everything needed to point an existing tracker to Wialon: primary unique ID, device type, hardware gateway address, and the type's TCP/UDP ports:

wln units connection 1001
wln units connection 123456789012345 --format json

The gateway address comes from hw_gw_ip in the authenticated token/login response. Ports come from core/get_hw_types. An empty TCP or UDP port means that the device type does not advertise that transport through the API.

Create or update a unit

The device type accepts either the numeric ID printed by device-types or its exact name. --imei is an alias for Wialon's primary --unique-id field:

wln units create "Truck 02" \
  --device-type "Teltonika FMB920" \
  --imei 123456789012345

wln units update 1001 --imei 987654321098765
wln units update 1001 --device-type "Teltonika FMB920"
wln units update 1001 --device-type 123 --unique-id 987654321098765

For updates, an omitted value is preserved. Wialon applies the device type and primary unique ID together through unit/update_device_type. Creation requires two documented API calls: core/create_unit, followed by unit/update_device_type to assign the unique ID. If the second call fails, wln reports the ID of the unit that was already created instead of hiding the partial result.

Unit status and stale positions

Show connection state, the last coordinate, its age, the last message, and the last known position:

wln units status
wln units status 1001
wln units status --offline --stale 30d --sort age --limit 20
wln units status --offline --inactive 30d --sort age

The default age order puts units with no known position first, followed by the oldest positions. --stale is based on the coordinate timestamp, not the last arbitrary message timestamp, so the two are shown separately. For reuse candidates, --inactive is safer: it requires both the last position and the last message to be older than the threshold.

Tables detect the current terminal width and fit before printing: optional columns are removed by command-specific priority and long values receive an ellipsis instead of being wrapped by the terminal. units status always keeps the name, unique ID, connection state, point age, and message age. A compact notice lists hidden columns. Use global --wide to disable fitting or --width N to reproduce a specific layout:

wln --width 106 units status
wln --wide units status

CSV, JSON, NDJSON, and redirected table output remain unabridged.

The table also includes the current unique ID, making the selected unit
unambiguous before its connectivity settings are changed.

Export messages

The unit argument accepts an exact Wialon ID, exact name, or exact unique ID/IMEI. Timestamps must be ISO 8601/RFC 3339 values with explicit offsets.

With no interval or output options, wln exports from local midnight through the current time and creates wialon-UNIQUE_ID-YYYY-MM-DD.csv in the current directory:

wln messages get 1001

Before loading messages, wln reports the resolved unit and interval. Use the explicit form to set either boundary:

wln messages get 1001 \
  --from 2026-07-19T11:00:00+05:00 \
  --to 2026-07-19T12:00:00+05:00 \
  --batch-size 10000 \
  --output /tmp/wialon-123456789012345.csv

Relative and calendar intervals are also supported:

wln messages get 1001 --last 2h
wln messages get 1001 --last 7d
wln messages get 1001 --today
wln messages get 1001 --yesterday
wln messages get 1001 --since 08:30

Write structured data to stdout for pipelines, or retain only selected message parameters:

wln messages get 1001 --last 30m --format ndjson --output -
wln messages get 1001 --today --format json --params temperature,voltage

By default, only telemetry/data messages are selected. Pass --all-types to include events, commands, logs, and other Wialon message types. Existing output is not replaced unless --force is specified.

The exporter:

  1. resolves the unit without guessing;
  2. logs in with token/login;
  3. loads the complete interval through messages/load_interval;
  4. reads the server-side loader in --batch-size pages;
  5. flattens nested fields without renaming them (pos.x, p.sensor_temp, etc.);
  6. writes CSV atomically and verifies the returned row count;
  7. unloads messages and logs out even after most failures.

Preferred columns are ordered first when present:

t,r,rt,tp,f,i,o,pos.x,pos.y,pos.z,pos.s,pos.c,pos.sc,...sorted dynamic fields

All discovered parameters are retained as p.<name> columns. CSV, JSON, and NDJSON files are built through a private temporary spool so large exports do not have to remain in memory and partially written destination files are not published.

Latest messages

wln messages tail 1001
wln messages tail 1001 -n 100 --format ndjson
wln messages tail 1001 --follow --poll 2s
wln messages tail 1001 --max-params 60
wln messages tail 1001 --full-params

--follow polls for new messages until interrupted. Table output shortens the parameter JSON to 100 characters by default; use --max-params to change the limit or --full-params to disable it. Use --all-types to include events, commands, logs, and other non-telemetry messages.

Native Wialon export

Download formats produced directly by Wialon without converting them:

wln messages export 1001 --today --format wln
wln messages export 1001 --last 24h --format kml
wln messages export 1001 --yesterday --format wlb --compress

Supported formats are kml, plt, wln, and wlb. Although some Wialon API documentation also lists txt, Wialon Hosting currently rejects that value as invalid input, so wln does not advertise an option it cannot reliably export.

Diagnose a profile

wln doctor
wln --profile staging doctor
wln profile check hosting

The diagnostic checks the configuration, selected profile, API login latency, server time, authenticated user, and accessible unit count without displaying the token or session ID.

Raw API fallback

For fields not covered by units or messages, call an authenticated Wialon service while still using the configured profile:

wln api call core/search_items --params @request.json
wln api call user/get_locale --params '{}'

The response is pretty-printed JSON. Use --compact for a compact response. Credential-management services are blocked, and credential-like response fields are redacted. token/login and core/logout are managed internally.

Global options

--profile NAME
--config PATH
--timeout 2m
--width N
--wide
--version

Global options must precede the top-level command. Command-specific options may follow their positional argument, matching the examples above.

API references

Development

go test ./...
go vet ./...

Tests use local httptest servers and never require a real Wialon token.

About

Command-line utility for exporting data from Wialon

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages