Part of the Librescoot open-source platform.
lsc is the Librescoot control and diagnostics command-line client. It talks to
vehicle services through the Redis-compatible datastore used by a Librescoot
system; it is not a standalone vehicle controller.
- Show consolidated vehicle, motor, battery, connectivity, GPS, map, update, and fault information.
- Control vehicle state, the seatbox and handlebar locks, alarm, LEDs, USB mode, modem, power state, and selected dashboard and engine functions.
- Manage keycards, saved locations, settings, systemd services, update operations, logs, and diagnostic recordings.
- Watch datastore pub/sub channels and emit machine-readable JSON for automation.
- Generate shell completion for Bash, Zsh, Fish, and PowerShell.
Run lsc --help and lsc <command> --help for the authoritative command and
argument reference. The primary command groups are vehicle, alarm, led,
diag, gps, modem, nav, ota, power, service, settings, usb,
keycard, locations, logs, monitor, ext, and watch. Common shortcuts include
status, lock, unlock, open, battery, faults, and maps.
keycard changes go to keycard-service over scooter:keycard, so it stays
authoritative for the duplicate, role and anti-lockout rules and publishes the
matching keycard:events. With the service stopped, lsc edits the UID files
under /data/keycard/ itself and says so on stderr.
Most commands read hashes and publish events or push commands through the
Redis-compatible datastore. State-changing vehicle and alarm operations wait
for their expected state change by default; their --no-block option sends the
request without that confirmation. Use it only when asynchronous behaviour is
intentional.
Examples:
lsc status
lsc vehicle lock
lsc settings get dashboard.theme
lsc --json gps status
lsc watch vehicle battery:0lsc ext manages rules through the event-service RPC API on the selected Redis
endpoint. Management requires a running, compatible event-service; there is no
local rule-file fallback, SSH invocation, or automatic service restart. status
requests a live reply rather than treating cached Redis hashes as proof of life.
RPC expiry uses the datastore clock; the CLI host and MDB need not have
synchronized wall clocks.
lsc ext list
lsc --json ext list
lsc ext add seatbox-notice --on 'vehicle.seatbox.*' --do redis --list extensions:notifications --push seatbox-changed
lsc ext show seatbox-notice
lsc ext add input-notice --on button.horn.tap,button.horn.hold --on 'button.brake.*' --do exec --command /data/extensions/input-notice.sh --timeout 2s
lsc ext disable seatbox-notice
lsc ext enable seatbox-notice
lsc ext test seatbox-notice --event '{"topic":"vehicle.seatbox.opened","src":"example","from":"closed","to":"open"}'
lsc ext status
lsc ext tail
lsc ext tail 'button.*'
lsc --json ext tail vehicle.seatbox.openedAdd, enable and disable persist desired configuration only. Their response
reports pending restart; current running rules remain unchanged until an
explicit event-service restart. A disabled rule can therefore still fire in the
current process. Arrange that restart separately on the intended target when it
is safe; these commands never perform it. Updates use revision checks and do not
retry mutations after errors or timeouts. Inspect list/show before deciding
whether to issue a fresh mutation. After restart, disabled rules stop accepting
new triggers, but valid saved delayed tails can finish without cancel-on
cancellation; replay expiry and fingerprint checks still apply.
exec --command names an executable on the service host, not shell text or a
command with arguments. Install the script before activating its rule. Add
writes a dedicated TOML file; enable/disable preferences are persisted separately
and take precedence over the file's enabled field.
list includes enabled/loaded state, last-fire timestamps, error counts and load
diagnostics, fetching all pages while checking revision consistency. show
includes the TOML definition. test is strictly a dry run: it does not publish
the supplied event or execute actions. Delayed conditions are evaluated against
the current snapshot, not predicted future state. status reports workers,
queue occupancy and service counters, including CAN counters when supplied by
the service.
tail subscribes only to ev: channels. Accepted patterns are an exact topic,
*, or a dotted prefix such as button.*; other globs are rejected. Quote stars
against shell expansion. Human output includes timestamp, source, topic, from
and to; JSON mode emits one event envelope per line. Malformed payloads produce
warnings on stderr; payloads over 64 KiB are skipped with a warning. Press Ctrl-C to stop. Tail watches live pub/sub, not history;
slow consumers can miss events.
CAN rules can directly affect vehicle hardware after the next service restart. Only configure frames whose effects you understand, and verify the target and service CAN policy first. Adding or dry-running a rule does not transmit a CAN frame. These examples illustrate syntax, not safe vehicle commands:
lsc ext add example-can --on example.request --do can --iface can0 --id 0x123 --data '01 02'
lsc ext add example-rtr --on example.query --do can --iface can0 --id 0x123 --rtr --dlc 2IDs are hexadecimal (standard or extended); classic CAN data is limited to
eight bytes. RTR frames carry no data and optionally specify --dlc 0..8.
Runtime CAN availability and permission remain the service's responsibility.
lsc has no configuration file. Its persistent options are:
| Option | Default | Purpose |
|---|---|---|
--redis-addr <host:port> |
192.168.7.1:6379 |
Datastore endpoint |
--json |
disabled | Emit JSON where supported |
--verbose, -v |
disabled | Report client connection activity on stderr |
Settings commands operate on the settings hash. When the deployed system
provides settings:schema, lsc settings list uses it to describe known
settings and lsc settings set validates values unless --force is supplied.
It also publishes changed setting keys on the settings channel so services can
react.
Use Go 1.25.7 (GOTOOLCHAIN=go1.25.7). Build a host binary or the ARMv7 target binary
with the supplied Makefile:
make build-host # bin/lsc for the build host
make build # statically linked Linux ARMv7 binary in bin/lsc
make test # go test -v ./...
make lint # requires golangci-lintmake build sets CGO_ENABLED=0, GOOS=linux, GOARCH=arm, and GOARM=7.
Use go build directly when a different target is required.
The binary needs network access to a Redis-compatible datastore and the
Librescoot services that define the hashes, queues, and pub/sub channels it
uses. The Yocto layer packages it as lsc and installs shell completion under
/etc/profile.d/; it can otherwise be installed anywhere on PATH.
Service and power-management commands invoke local systemctl, journalctl,
and related platform facilities. Run them on the intended target with the
privileges those operations require.
Commands can lock a vehicle, change its power state, control hardware, modify
settings, and manage OTA operations. Confirm the target endpoint before
executing state-changing commands, especially when overriding --redis-addr.
A successful send is not necessarily a successful vehicle action; keep the
default confirmation behaviour when possible and inspect status after critical
operations.
Use lsc motion calibrate start|status|finish|cancel|reset to manage motion-service's in-process magnetometer calibration. Perform clockwise and counter-clockwise circles upright in an open area away from vehicles and steel structures. A failed finish preserves the previous model; reset deletes it and disables magnetic heading.
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Made with ❤️ by the Librescoot community