A command-line interface for controlling and monitoring Librescoot electric scooters via Redis.
Part of the Librescoot open-source platform.
- Vehicle Control: Lock, unlock, hibernate, and force-lock vehicle states
- LED Control: Trigger LED cues and fade animations
- Power Management: Control power states (run, suspend, hibernate, reboot)
- Service Management: Start, stop, restart, enable, disable systemd services and view logs
- OTA Updates: View update status and install updates
- GPS: Monitor GPS status and track location
- Battery Diagnostics: View detailed battery information and health
- Alarm System: Arm, disarm, and trigger the vehicle alarm
- Keycard Management: Authorize/revoke keycards for vehicle access
- Location Management: Save and manage frequently visited locations
- Hardware Control: Manage dashboard, engine, handlebar, and seatbox
- Settings: Get and set vehicle configuration
- Diagnostics: Monitor faults, view firmware versions, and stream events
- Metrics Recording: Capture detailed system metrics over time for debugging
- Log Extraction: Extract service logs and Redis snapshots for analysis
- JSON Output: All commands support
--jsonflag for automation
Build for ARM (e.g., Raspberry Pi):
GOOS=linux GOARCH=arm GOARM=7 go build -o lsc .Build for your local system:
go build -o lsc .# Show overall status
lsc status
# Lock the scooter
lsc lock
# Unlock the scooter
lsc unlock
# View all settings
lsc settings
# Get a specific setting
lsc get alarm.enabled
# Set a setting
lsc set alarm.duration 15
# View battery status
lsc battery
# Show active faults
lsc faults
# Watch GPS location
lsc gps watch
# View OTA update status
lsc ota status
# Manage keycards
lsc keycard list
lsc keycard add ABC123DEF456
# Manage saved locations
lsc locations list
lsc locations add 51.5074 -0.1278 "office"lsc vehicle lock- Lock the scooterlsc vehicle unlock- Unlock the scooterlsc vehicle force-lock- Force standby without waiting for lockslsc vehicle hibernate- Lock and request hibernationlsc vehicle open- Open seatbox
lsc led cue <index>- Trigger LED cue by indexlsc led fade <channel> <index>- Trigger LED fade animation
lsc keycard list- List all authorized keycardslsc keycard add <uid>- Add a keycard UIDlsc keycard remove <uid>- Remove a keycard UIDlsc keycard add-master <uid>...- Add master keycard(s)lsc keycard remove-master <uid>...- Remove master keycard(s)lsc keycard export <file>- Export keycards to filelsc keycard import <file>- Import keycards from file
lsc locations list- List all saved locationslsc locations add <latitude> <longitude> <label>- Add a saved locationlsc locations show <label>- Show location detailslsc locations edit <label>- Edit a saved locationlsc locations delete <label>- Delete a saved locationlsc locations touch <label>- Update last-used timestamp
lsc power status- Show power manager statuslsc power run- Set power state to run (normal operation)lsc power suspend- Set power state to suspend (low power)lsc power hibernate- Set power state to hibernate (power off)lsc power reboot- Reboot the system
lsc service list(orlsc svc list) - List all services with statuslsc service start <service>- Start a servicelsc service stop <service>- Stop a servicelsc service restart <service>- Restart a servicelsc service enable <service>- Enable service to start on bootlsc service disable <service>- Disable service from starting on bootlsc service status <service>- Show detailed service statuslsc service logs <service>- View recent service logs--followor-f- Follow logs in real-time--lines <n>or-n <n>- Number of lines to show (default: 50)
Service Name Shortcuts: Use shorthand names like vehicle, battery, ecu, alarm, modem, settings, bluetooth, pm, etc. instead of full names like librescoot-vehicle.
Examples:
# List all services
lsc svc list
# Restart vehicle service (shorthand)
lsc svc restart vehicle
# Or use full name
lsc svc restart librescoot-vehicle
# Follow logs in real-time (shorthand)
lsc svc logs battery -f
# View last 100 log lines
lsc svc logs redis -n 100lsc ota status- View OTA update status and configurationlsc ota install <file-or-url>- Install update from local file or URLlsc ota check- Check for available updates
lsc gps status- Show GPS status and fix informationlsc gps watch- Monitor GPS location in real-time--compact- One-line format output
lsc watch- Watch Redis pub/sub channels for real-time events
lsc diag battery [id...]- Show detailed battery informationlsc diag version- Display firmware versionslsc diag faults- Show active faultslsc diag events- View fault event stream--follow- Follow events like tail -f--since <duration>- Show events since duration (e.g., 1h, 24h, 7d)--filter <regex>- Filter events by regex pattern
lsc diag blinkers [off|left|right|both]- Control blinkerslsc diag horn [on|off]- Control hornlsc diag handlebar [lock|unlock]- Control handlebar locklsc diag dashboard- Control dashboard poweron/off- Power on/offstatus- Show power statusping- Check connectivityon-wait- Power on and wait until readyoff-wait- Power off and wait until unreachable--force- Force off even during updates
lsc diag engine- Control engine power
Record detailed metrics for debugging and analysis:
lsc monitor <subsystems...>- Record metrics over time- Available subsystems:
gps,battery,vehicle,motor,power,modem,events,all --duration <time>- Recording duration (e.g., 1h, 5m, 24h)--interval <time>- Polling interval (e.g., 1s, 5s, 100ms)--format <format>- Output format (jsonl, csv)--output <dir>- Output directory
- Available subsystems:
Examples:
lsc monitor gps --duration 1h
lsc monitor battery vehicle --duration 10m --interval 5s
lsc monitor all --duration 30m --output /data/debugExtract service logs and Redis snapshots:
lsc logs [services...]- Extract logs for analysis- Available services:
vehicle,battery,ecu,modem,pm,update,settings,keycard,bluetooth,ums,radio-gaga,all --since <time>- Start time (e.g., 24h, 1d, "2025-10-25 10:00")--until <time>- End time--priority <level>- Log level (err, warning, info, debug)--output <dir>- Directory to write the.tar.gzinto (default:/data/log-bundles)
- Available services:
Examples:
lsc logs # Extract all services (last 24h) into /data/log-bundles/
lsc logs vehicle --since 1h
lsc logs battery ecu --since 24h --output /data/debug
lsc logs all --priority err # Show only errorsThe command produces a single logs-<timestamp>.tar.gz archive in the
output directory; the unpacked tree is staged in a temporary subdirectory
and removed when the archive is written.
lsc alarm status- Check alarm statuslsc alarm arm- Enable the alarmlsc alarm disarm- Disable the alarmlsc alarm trigger- Manually trigger the alarm
lsc settings- List all settingslsc settings get <key>- Get a setting valuelsc settings set <key> <value>- Set a setting value
Quick access to common commands:
Vehicle:
lsc lock- Lock the scooterlsc unlock- Unlock the scooterlsc open- Open seatbox
Settings:
lsc get <key>- Get setting valuelsc set <key> <value>- Set setting valuelsc del <key>- Delete setting key
Diagnostics:
lsc batteryorlsc bat- Show battery infolsc versionorlsc ver- Show firmware versionslsc faults- Show active faultslsc events- View fault event streamlsc dashboardorlsc dbcorlsc dash- Control dashboard powerlsc engine- Control engine powerlsc blinkersorlsc blink- Control blinkers
All shortcuts support --json output and vehicle commands support --no-block flag.
Dev only — hidden from lsc --help. lsc boot pokes U-Boot env and raw block devices to swap the Mender A/B rootfs selection, bypassing mender-update and OTA. Worst case you end up in a boot-loop and have to stop at U-Boot over UART to fix mender_boot_part by hand — annoying, not destructive.
Same binary on MDB and DBC; it operates on the local slot.
- pending =
upgrade_available=1. U-Boot incrementsbootcounteach boot and rolls back to the other slot oncebootcount > bootlimit(defaultbootlimit=1— one tentative boot, next reboot falls back). - committed =
upgrade_available=0. Boot is permanent.
Commands:
lsc boot status- current slot, next-boot target, pending/committed state.lsc boot set <a|b|other|current|N>- persistently switch the next-boot slot.lsc boot try-other [-y]- one-shot boot into the other slot; any reboot without commit rolls back.lsc boot armor [-y]- tentative boot of the current slot with fallback to the other. Use before a risky change; reboot-loops auto-fall-back.lsc boot commit [-y]- clear a pending one-shot, making the current slot permanent.lsc boot clone [--arm] [-y]-ddthe running rootfs onto the other slot (live/fuzzy snapshot; fsck cleans up on first mount).--armalso sets next-boot to the clone.
Recipes:
# Safety net: clean copy of A on B, keep hacking in A. Any reboot lands on B.
lsc boot clone --arm -y
# Risky kernel / initramfs change: armor, reboot, commit if it works.
lsc boot armor -y
reboot
# ... if A comes up clean:
lsc boot commit -y
# ... if A reboot-loops, U-Boot falls back to B automatically.
# Just poke at the other slot once; reboot restores sanity.
lsc boot try-other -y
rebootarmor only fires on counted reboots — a kernel that hangs early without a watchdog reboot won't fall back on its own.
--json- Output in JSON format for automation--redis-addr <host:port>- Redis server address (default: 192.168.7.1:6379)--no-block- Don't wait for state change confirmation (vehicle commands)
All commands support JSON output for scripting and automation:
# Get status in JSON format
lsc status --json
# Lock and capture result
lsc lock --json
# Get setting value
lsc get alarm.enabled --jsonExample JSON output:
{
"vehicle": {
"state": "parked",
"kickstand": "up",
"brakes": {
"left": "released",
"right": "released"
}
},
"motor": {
"speed_kph": 0,
"odometer_km": 1234.5,
"temperature_c": 25
},
"batteries": [...]
}Settings can be viewed with lsc settings list and modified with lsc set <key> <value>:
Alarm:
alarm.enabled- Enable/disable alarm (true/false)alarm.honk- Enable horn during alarm (true/false)alarm.duration- Alarm duration in seconds
Updates:
updates.mdb.method- MDB update method (delta/full)updates.mdb.channel- MDB update channel (nightly/stable/etc)updates.dbc.method- Dashboard update methodupdates.dbc.channel- Dashboard update channel
Network:
cellular.apn- Cellular APN string
Dashboard Display:
dashboard.theme- UI theme (dark/light)dashboard.mode- Dashboard mode (navigation/etc)dashboard.show-raw-speed- Show raw speed (true/false)dashboard.show-clock- Clock visibility (always/riding/never)dashboard.show-gps- GPS indicator visibilitydashboard.show-bluetooth- Bluetooth indicator visibilitydashboard.show-cloud- Cloud indicator visibilitydashboard.show-internet- Internet indicator visibilitydashboard.battery-display-mode- Battery display mode (percentage/range)dashboard.map.type- Map source (offline/online) - offline uses local MBTiles, online uses CartoDB tilesdashboard.map.render-mode- Map render mode (raster)dashboard.valhalla-url- Routing service URL
Battery:
scooter.battery-keep-active-on-seatbox-open- Keep a running battery active when the seatbox opensscooter.battery-aux-low-keep-active-enter-mv- Aux voltage (mV) below which keep-active engages automatically (default 11500)scooter.battery-aux-low-keep-active-exit-mv- Aux voltage (mV) at or above which the auto override disengages (default 12000)scooter.dual-battery- Enable dual battery modescooter.max-voltage-delta- Max voltage delta (mV) between batteries for dual-battery activation
Power:
hibernation-timer- Hibernation timer duration
Generate shell completion scripts:
# Bash
lsc completion bash > /etc/bash_completion.d/lsc
# Zsh
lsc completion zsh > "${fpath[1]}/_lsc"
# Fish
lsc completion fish > ~/.config/fish/completions/lsc.fish
# PowerShell
lsc completion powershell > lsc.ps1lsc communicates with Librescoot services via Redis:
- Command Queues: LPUSH to
scooter:*lists for commands - State Hashes: HGET/HSET on
vehicle,battery:*, etc. - Pub/Sub: Subscribe to state change notifications
- Streams: XREAD for event history
# Install dependencies
go mod download
# Build for ARM (target platform)
make build
# Build for your local platform
make build-native
# Or manually:
go build -o lsc .
GOOS=linux GOARCH=arm GOARM=7 go build -o lsc .
# Run tests
go test ./...This project is dual-licensed. The source code is available under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. The maintainers reserve the right to grant separate licenses for commercial distribution; please contact the maintainers to discuss commercial licensing.
