Перейти до вмісту

Python CLI — cscli

cscli — невеликий Python-CLI, який спілкується з CarStream-сервером по HTTPS + WebSocket. Живі ASCII-датчики, спарклайни, графік RPM/Speed, гігантські одно-польні показники, сирий JSON-стрім та health-check за один виклик — все з терміналу.

cscli dashboard
┌──── CarStream — Audi Q8 ──────────────────────────────────────────────┐
│ RPM ████████████████░░░░░░░░░░░░░░ 3420 rpm ▁▂▄▆█▆▄▃▂▁▂▃▅▇█│
│ Speed ██████████░░░░░░░░░░░░░░░░░░░░ 72 km/h ▁▁▂▃▄▆▇█▇▆▅▄▃▂▁│
│ Throttle ███████░░░░░░░░░░░░░░░░░░░░░░░░ 23 % ▁▁▂▂▃▃▄▅▆▆▆▅▄▃▁│
│ Load ████░░░░░░░░░░░░░░░░░░░░░░░░░░ 14 % ▁▁▁▂▂▃▃▄▄▄▃▃▂▁▁│
│ Coolant ███████████████████░░░░░░░░░░░ 91 °C ▆▆▆▇▇▇▇█████▇▇▆│
│ Oil ███████████████████░░░░░░░░░░░ 97 °C ▅▅▆▆▆▇▇▇▇█████▇│
│ Fuel ████████████████░░░░░░░░░░░░░░ 56 % █████▇▇▇▇▆▆▆▅▅▅│
└────────────────────────────────────────────────────────────────────────┘
Terminal window
pipx install carstream-cli

Потрібен Python ≥ 3.10.

Terminal window
cscli login
cscli login --email you@example.com # пропустити промпт email
cscli logout

JWT кешується у ~/.config/carstream/credentials.json з правами 0600. Токени мають час життя (зазвичай 24 год); на 401 CLI підкаже виконати cscli login ще раз.

КомандаЩо робить
cscli loginПромпт email + пароль. JWT у ~/.config/carstream/credentials.json.
cscli logoutЗабути збережені креди.
cscli devicesТаблиця авто з пілюлею ONLINE / STALE / OFFLINE та зрозумілим last-seen.
cscli statusEnd-to-end health-check — сервер, авторизація, WebSocket, життя кожного Pi. Дружній до cron.
cscli dashboardЖиві ASCII-датчики + спарклайни + графік RPM/Speed + статус-панель.
cscli watch <field>Гігантський одно-польний ASCII-показник через pyfiglet, зі спарклайном і віком кадру.
cscli tailСтрім сирих кадрів як JSON-per-line у stdout.

Кокпіт на другому моніторі

Постав cscli dashboard на запасний монітор або Pi Zero на кухні. Завжди на видноті — RPM, швидкість, охолоджуюча, оливна, паливо. Плюс живий спарклайн на кожен показник і клікабельне посилання на Google Maps до поточної точки.

Пайп телеметрії куди завгодно

cscli tail пише по одному JSON-обʼєкту на рядок. Збирай ланцюжки з jq, awk, datamash чи своїх скриптів. Гарячий шлях не парсить JSON взагалі — пропускна здатність майже на рівні мережі.

Моніторинг через cron

cscli status повертає не-нуль на будь-яку червону лінію — ідеально для */5 * * * * пінгів у Slack, Discord чи Healthchecks.io.

Великий показник на одну метрику

cscli watch speed дає тобі повноекранне pyfiglet-число. Постав на Pi Zero з дешевим HDMI-екраном — і ось у тебе head-up display у гаражі чи на верстаку.

Terminal window
cscli dashboard # автоматично, якщо в тебе одне авто
cscli dashboard --car "Audi Q8" # або --car <car_id>, для конкретного авто

Що ти бачиш:

  • Кластер датчиків зі смужкою + кольоровим значенням + 60-семпловий спарклайн на кожну метрику.
  • Графік RPM/Speed за тим самим вікном (дві осі Y через plotext).
  • Статус-панель: назва авто, пілюля ONLINE / STALE / OFFLINE (пороги 5 с / 30 с — як на вебі), GPS-координати, вік кадру та OSC-8 посилання Open in Google Maps ↗.

Статус-панель на старті заздалегідь смикає /api/telemetry/<id>/last_position, тож рядок GPS і посилання на Maps зʼявляються одразу — ще до першого WebSocket-кадру. Поки показуємо припарковану позицію, у GPS-рядку додається (last known), а нижче зʼявляється Parked: <ISO timestamp>. Обидва зникають, як тільки приходить живий кадр з координатами.

OSC-8 посилання клікабельні в iTerm2, сучасному xterm, gnome-terminal, wezterm, kitty; у решті терміналів — просто текст. Ctrl-C виходить чисто.

Стеження за одним показником

Section titled “Стеження за одним показником”
Terminal window
cscli watch speed # гігантська ASCII-цифра, спарклайн нижче
cscli watch rpm --font slant
cscli watch fuel_level --font doom

Зручно для другого монітора, Pi Zero на кухні чи head-up екрану в майстерні.

Terminal window
cscli tail # один JSON-обʼєкт на рядок
cscli tail --pretty # форматований JSON
cscli tail --field rpm # лише кадри з цим полем; вивід — {field, ts}

Пайпай у власні інструменти:

Terminal window
cscli tail | jq 'select(.speed > 100)'
cscli tail --field rpm | jq -r .rpm | datamash mean 1
cscli tail --field fuel_level | awk -F: '{print $2}'

Гарячий шлях взагалі не парсить JSON — сирий WebSocket-кадр одразу летить у stdout. Якщо твоєму споживачу потрібно — він сам розпарсить.

Terminal window
cscli status
Terminal window
Server health · https://carstream.live
✓ Credentials present (you@example.com)
✓ Server reachable (200 in 84 ms)
✓ Auth valid (3 cars)
✓ WebSocket upgrades successfully
Devices:
✓ Audi Q8 ONLINE 1s ago
⚠ BMW F36 STALE 18s ago
✗ VW Polo OFFLINE never
All systems healthy.

Виходить з кодом 0, якщо все зелене, і 1 на будь-яке червоне. Підключаємо до cron:

Terminal window
*/5 * * * * cscli status >/dev/null 2>&1 || \
curl -X POST <slack-webhook> -d '{"text":"CarStream unhealthy"}'
Terminal window
cscli devices
Terminal window
┌─────────┬──────────┬──────────────────────────────────┬──────────────────┬───────────┐
│ Status │ Name │ Car ID │ Device │ Last seen │
├─────────┼──────────┼──────────────────────────────────┼──────────────────┼───────────┤
│ ONLINE │ Audi Q8 │ a1491b52-0db3-4649-acba-... │ 89de0a7570734f07 │ 2s ago │
│ STALE │ BMW F36 │ 4db27641-09a5-4fc3-bc03-... │ ed12bab94fccf357 │ 18s ago │
│ OFFLINE │ VW Polo │ — │ (unassigned) │ never │
└─────────┴──────────┴──────────────────────────────────┴──────────────────┴───────────┘

Якщо до акаунта привʼязано більше одного авто, стрімінгові підкоманди (dashboard, watch, tail) не вгадують і виводять список авто для вибору (за назвою або id):

Terminal window
cscli dashboard --car "Audi Q8"

З одним авто --car опційний.