How to monitor a JK BMS online with just an old phone and Chrome

18 minute read

Published:

🌐 อ่านหน้านี้เป็นภาษาไทย →

TL;DR: take an old Android phone you no longer use, plug it in next to the battery, open clearevo.com/batray in Chrome, press Connect, pick your JK BMS, press Share live. Scan the QR with the phone in your pocket and watch voltage, battery %, current, power, every cell and the history from anywhere. Nothing to install, no account; the readings leave the old phone encrypted with a key that exists only in the link.

Live demo: the author’s own two battery banks, watch them live. It opens with the last reading and how old it is; when the reader phone is online, readings follow every few seconds. This is the viewer side of Share live below - what anyone you send a link to would see.

Connect

  1. Bluetooth on. Android: Chrome. PC: Chrome or Edge. Not iPhone, not Firefox.
  2. Open https://www.clearevo.com/batray/, press Connect, pick your BMS. It shows under the name set in the JK app (mine is n11).
  3. Close the JK app first: a JK BMS takes one Bluetooth connection at a time.

No BMS nearby? The start screen has a link to the author’s own banks, live (the same link as above). There is no simulated demo any more.

The Bluetooth button in the toolbar is the link itself: Connect when idle, Connecting while it tries (tap to cancel), Disconnect sunk while connected.

Leave an old phone next to the battery

Plug in any old Android phone or notebook with Chrome, connect once, leave the tab in front. The screen stays awake, and a dropped link reconnects every 10 s until you press Cancel. Keep Bluetooth on: on this Chrome version a reconnect with Bluetooth off can close the tab. A phone asleep for an hour freezes the tab; on your return BatRay throws away what the Bluetooth stack queued and reconnects for fresh readings, never an old number dressed up as live.

Turn off auto-update for Chrome on that phone (Play Store, find Chrome, the ⋮ menu, untick Enable auto update): an update closes Chrome and the BatRay tab with it, and nothing reopens it until someone opens Chrome and presses Connect. Update Chrome by hand when you are next to the phone, and keep it at 108 or newer.

When the reader page opens again (Chrome restored it, or someone opened BatRay), it counts down 30 s with Now and Cancel, then shares again on the last link and reconnects the BMS it was connected to. Reconnecting without a tap needs Chrome to remember the Bluetooth permission: open chrome://flags, set “Use the new permissions backend for Web Bluetooth” to Enabled, tap Relaunch, and connect once. Without it the share still resumes and BatRay says which BMS needs a tap on Connect. The Reader setup checklist in Notes lists what a phone left next to the battery needs (that flag, notifications, charging, Chrome auto-update off, Chrome’s battery use set to Unrestricted, and more), checking what the page can check; the two Chrome settings it cannot see have a Done for you to tap. Connect shows the list when something is missing, with Continue anyway, and while the reader runs a ⚠ next to “updated” opens it. Keep the reader phone plugged in: Chrome and Edge tell the page its battery level and whether a charger is connected, so the reader phone shows a warning when it is unplugged, and your viewers see a line while it is not charging and get an alert (when alerts are on) when it is unplugged, falls to 20 % without charging, or charges again.

Some phones let go of the screen lock after hours (an old Sony did). BatRay asks for it again. If that is not enough, Notes can add a tiny silent video that Chrome treats as media keeping the screen on (off by default; only when the lock keeps dropping, or always; Android may lower other apps’ sound while it plays). A viewer never plays it. Low power in Notes stops every moving thing on screen. Last resort: Android Developer options → Stay awake.

Watch from anywhere

Press Share live, give it a name (prefilled with the BMS’s name or a cat’s), keep use the last share link ticked so the same link and QR survive a restart. A QR code appears and the link is copied: scan it, or paste it into Chrome on any phone or PC. Readings are encrypted on your phone with a key that exists only inside the link; nobody in between can read them, clearevo.com included. Anyone with the link can watch, so treat it like a password; pressing the sunk Share button, or stop sharing, makes it dead.

Both ends show the viewer count. The readings travel through a small relay server, encrypted, which the author pays for; the app says so next to the live chip. A viewer that opens the link sees the last picture at once, with how old it is, and the live readings follow. Under updated in the picture’s corner, the reading’s own time to the millisecond; a viewer gets a second line with the time it arrived there. When the reader is away, the viewer says since when (date, time, how long ago), how it ended (page closed, screen off and then quiet, or the connection just dropped) and what it last read; tap that box, or Reader phone under More, for the reader phone’s last status: its battery and charging, Chrome version, history storage, memory and network. If BatRay is useful to you: GitHub Sponsors. With notifications on, the reader is told when a viewer joins or leaves, a viewer when the reader goes offline or comes back, and either side when its own internet or the server drops. The live view has three tabs at the bottom: Now, History, More.

More than one BMS

+ Add BMS. Every pack is read at once; tap a chip to switch. A shared link carries all of them.

Show on TV

Press Show on TV, pick 720p or 1080p, start. BatRay draws its picture into a small video and puts the last seconds on clearevo.com for a TV to pull, a few seconds behind. The preview in the card is the picture drawn on your phone; it switches to the stream itself only while the phone can actually play it, so it never goes dark when the connection has a gap. The cast icon (Chromecast, Google TV or Android TV on the same Wi-Fi; one under the preview, one on it) loads Google’s cast library at that moment and shows a small progress panel: looking for TVs (20 s limit), your pick in Google’s list, then the TV’s own player state - buffering, playing - for up to a minute, with a Cancel button throughout and a Close once it plays or gives up; the same state stays under the icon afterwards. The TV takes about 20 s to show the first picture. Or open the link or QR in the TV’s browser or a player such as VLC.

Two honest limits. This path is not encrypted: the picture sits on clearevo.com and anyone with the link can watch, so stop it when done (it stops by itself two minutes after the phone goes quiet). And it needs Chrome 94 or newer to encode video; the app says so if it cannot.

Alerts

Alerts under the readings, tick Chrome notifications (asks once; send a test shows one). Six rules are on: below 40 %, below 25 %, no charging in daylight, cells drifting apart, no data from the BMS, any alarm the BMS reports. Change or switch off any. On Android keep the tab in front. On the reader phone, sharing live with notifications allowed also sets up a “reader stopped” message: if that page stays offline for 3 minutes (Chrome closed, the phone killed it, the network went), the relay sends one push and the phone shows “BatRay: NAME stopped - tap to reopen”; the tap opens the reader page, which shares again after its 30 s countdown. Android hands the push to Chrome even when Chrome is closed, but not after Chrome was force-stopped. Stopping the share yourself cancels it.

What you see

  • Picture: an upright battery whose level is the state of charge, 20 % ticks, your inverter cut-off as a red dashed line; pack voltage and SOH under it; the flow to the load (amber) or from the charger (green) with power and current; time to go to the cut-off (Notes, default 10 %) while discharging, to full while charging, from the current averaged over a minute.
  • Tap anything: the battery, the flow, the status chips, the cell line. A sheet slides up with one plain sentence and the exact values; drag it down, tap outside or press Back to close.
  • Status chips: charge and discharge switches (green allowed, red blocked), balancing, temperatures, the BMS alarm line.
  • Cells: the spread in mV with lowest and highest named, then one bar each. The bars exaggerate the spread on purpose; read the mV.
  • History: up to four lines of your choice over 1 h, 6 h, 24 h, 7 d or all. Tap the chips to choose among battery %, voltage, current, power, the MOSFET and the two sensor temperatures and remaining Ah; the default is battery % and current, which keeps a 7-day window quick to draw. The first chosen line owns the left axis, the second the right, and each chip shows the value under the cursor. The cut-off line appears with battery %; the energy charged and discharged in the window is under the chips. Two fingers zoom, a mouse drags a window. Readings are stored on the device in the browser’s private storage as one SQLite database per UTC day, today’s included (the chart shows your local time), one row per pack every 3 s, kept as long as the browser has room: the Storage box shows the days stored, the space used of what the browser allows and the estimated days left, and the oldest days are deleted automatically when less than 100 MB stay free. The chart is drawn from small queries on those files, so the page keeps no table of readings in memory. Every read and write has a time limit and the results, failures and read/write statistics go to the debug log; a storage worker that stops answering is restarted. A day file that turns out damaged is deleted and a message says so; if it is today’s, a new file starts from that moment. A viewer asks the reader for the rows it lacks, by row number, so it keeps the same rows. Each browser tab keeps its own history and debug log, so several BatRay tabs (a reader and viewers of different shares) store at the same time; a viewer tab fetches its history from its reader, and a reader opened again in a new tab after its tab was closed continues the closed tab’s history. Only the settings are shared by every tab. Only one tab can be the reader (the tab that talks to the BMS) in a browser at a time: a second one opened without a share link does not start, says to close the other BatRay tabs, and starts by itself once they are closed. Browse lists the day files and every other tab’s store (one that is open in another tab is deleted from that tab; a closed viewer tab’s copy is freed by itself after 30 days unused, or sooner when space runs low), Download saves one .tar holding a .sqlite file per day (7-Zip or Windows 11 opens the .tar; DB Browser for SQLite or Python opens a day; up to 512 MB), Restore merges the rows each day lacks, Clear removes it all. A bar counts the first 30 s on a new device. When this browser cannot store the files (Chrome older than 108, or storage that did not start), nothing is kept, not even in memory, so the history cannot fill the phone’s memory on a long run: the History card is greyed out and says why and what to do.
  • More and BMS settings: every figure the BMS reports and its protection limits. Read-only: BatRay never writes to the BMS.
  • Notes: cut-off, keep-awake, low power, and the check line. ✔ means the pack voltage agrees with the sum of the cells. ⚠ layout uncertain means do not trust the numbers: turn on Debug log (the bug button at the top) and Upload log (a warning first, then an id to quote), or Copy log in the Debug card and send it to me.
  • ⛶ fills the screen with the picture.

  • Connect to NAME: once a BMS has been picked on a device, a green button above Connect reconnects to it without the chooser, as long as Chrome still lists it as permitted for this site (Chrome gives the page no Bluetooth address, only a per-site id and the name).

Limits

  • The phone next to the battery: Chrome or Edge 108 or newer, Android or desktop. Firefox, Safari and every iPhone browser have no Web Bluetooth, so they cannot be that phone.
  • Watching a share link: Chrome or Edge 108+, or Firefox 114+; Safari / iPhone 16.4+ is let through but untested.
  • An older browser gets a warning on Connect (or on opening the link) saying why and where to update, with Connect anyway (or Open anyway) to try it regardless. A browser without Web Bluetooth gets the reason only.
  • Read-only. History lives in the browser’s private storage on that device only: clearing site data or uninstalling Chrome deletes it, and it is not backed up anywhere.
  • Upload log sends the log to clearevo.com only after you confirm (Browse in the History card can upload any stored log file, not only this session’s), with a progress bar and a Cancel. It holds device details, raw BMS frames and the BMS name and serial, never the share-link key, and is kept 90 days. Keeping the debug log is off until you press Debug log, the bug button at the top; it works before any BMS is connected. Pressed in, the log is kept on the device itself (one file per session, 10 MB each, the newest ten) so it survives a refresh, Upload log shows next to the button, and the History card shows the log’s size and can download it as a .tar or delete it; pressed again, nothing more is kept and Upload log goes away. The card also shows the tab’s memory use against the limit Chrome allows, and after a crash the next start writes what the app last reported at the top of the new log; while Debug log is on, Chrome may also send its own crash report (reason only, no data) to clearevo.com.
  • Time to go comes from the BMS’s own remaining-capacity figure; a wrong capacity setting in the BMS makes it wrong too.
  • Tested on my own unit and on captured frames from four JK firmware generations; a new firmware may show ⚠. Send the log.
  • Notifications need the tab open and, on Android, in front.
  • Share live and Show on TV go through a small relay server that the author pays for. Direct viewing of your own BMS over Bluetooth needs no server at all. If BatRay is useful to you: GitHub Sponsors.

Privacy

Battery data stays on your device unless you turn on Share live, and then it reaches your viewers encrypted, unreadable to anyone in between, clearevo.com included. Share live also sends the reader phone’s own status (its battery and charging, Chrome version, memory, storage and network) to your viewers, encrypted the same way; the relay keeps only when the reader’s connection ended and how it closed. For the “reader stopped” message the relay keeps the reader phone’s push address and sends it one push with no content through the browser’s push service (for Chrome, Google’s Firebase Cloud Messaging): a wake-up, no battery data. Show on TV is the one exception: the picture (not the raw data) sits on clearevo.com unencrypted for the seconds a TV needs to fetch it. Alerts are judged and shown on the device. BatRay never reads your location, and the page tells Chrome so: it is served with Permissions-Policy: geolocation=(), which makes the browser refuse location to it. Google Analytics counts visits only - verify it yourself.

Licence

© 2026 Kasidit Yusuf. Free software under the GNU GPL v2, like every ClearEvo tool. Provided as is, with no warranty and no support. Not a safety device: BatRay cannot be relied on to prevent damage or danger.

This tool is free software and open source: ykasidit/clearevo_online_tools (public/batray) - issues and pull requests welcome, especially captured frames from JK firmware I do not own.

Full disclosure: this post - and any code or tool it describes - was co-authored with Claude (Anthropic’s AI, via Claude Code). I directed, guided and reviewed. I don’t want to pretend otherwise.