IPerfect Live Data Plotter
User Guide
Open the Plotter
1

What this tool does

The Live Data Plotter listens to an MQTT topic over a WebSocket and draws numbers from each message onto a live time-series chart. It does not know anything about your payload format — you tell it how to pull the numbers out, using one regular expression and one short line of JavaScript per line on the chart.

Broker ws://iperfect.net:3000
Message raw payload text
Expression 1 splits it into regEx[ ]
Expressions 2…n addPoint() per series
Live chart redrawn each message
2

Before you start

Open the plotter over http://, never https://. The broker on port 3000 has no TLS, so a secure page will silently block the ws:// connection and nothing will ever arrive. The plotter shows a yellow warning bar if you get this wrong.
  • Use a current Chrome, Edge or Firefox.
  • Your device must already be publishing to the broker. The plotter only reads — it never sends data to your device.
  • Know your topic and roughly what your payload looks like. If you do not, connect first and read one off the console (step 2 below).
3

Quick start

  1. Connect. Leave WebSocket URL as ws://iperfect.net:3000, type your topic into Subscribe Topic, and press Connect & Subscribe. The pill top-right turns green and reads Connected.
  2. Look at one real message. The black console fills with timestamped payloads. If it stays empty, your topic is wrong — try a wildcard such as Zone/# to see what is being published. Copy one payload; you need it for step 4.
  3. Name your chart lines. In Axis Configuration set X-Axis data types to plot to how many lines you want and press Apply. Give each one a name. Note the grey highcharts.series[0] tag beside each — that is how you refer to it.
  4. Count your fields. Split the payload you copied on every comma and pipe, then count from zero. That position is the number you put in regEx[…]. See How parsing works.
  5. Set the expression count. In RegEx Configuration set Expressions to plot to 1 + one per line (three lines means four) and press Apply.
  6. Row 1 splits the payload. Enter /([^|,]+)/g and tick Is RegEx.
  7. The remaining rows plot. Leave Is RegEx unticked and enter one line each, pointing at the field you counted in step 4:
    highcharts.series[0].addPoint([dt,(regEx[4])*1],false)
  8. Press Save Configuration. The page reloads with your settings in the address bar. Press Connect & Subscribe again and the chart starts drawing.
Bookmark the address bar once it works. Every setting lives in the URL, so a bookmark restores the whole configuration. That is also how you share a working setup with a colleague.
4

How parsing works

Every row in RegEx Configuration runs once per message, top to bottom. The Is RegEx tick is what decides how it runs:

Is RegEx What the row does
Ticked The text is treated as a regular expression. The plotter matches it against the payload and stores every match in the regEx array. It draws nothing by itself.
Unticked The text is treated as a line of JavaScript and executed as written. This is where you call addPoint().

What you can use inside a row

Name Meaning
data The payload of the message that just arrived.
regEx The array produced by your Is RegEx row. Counts from zero.
dt The time the message arrived, in milliseconds. Use it as the x-value of every point.
highcharts The chart. highcharts.series[0] is your first named line, [1] the second, and so on.

Counting the index

/([^|,]+)/g means “every run of characters that is not a comma or a pipe” — in other words, every field. Suppose a message reads:

Zone,2340,e1:0b:6f:40:82:fb,17,1.42,-0.87,9.61|ok

Splitting it gives these positions:

0Zone
12340
2e1:0b:…
317
41.42
5-0.87
69.61
7ok

So the three numbers you want are regEx[4], regEx[5] and regEx[6]. Do this with a payload copied from your own console — the layout above is only an illustration of the counting.

Four rules worth remembering

  • Put the Is RegEx row first. Rows run in order, so the array has to be filled before anything reads from it.
  • Use only one Is RegEx row on this page. A second one replaces the first one's result. (The dev page lifts this limit.)
  • End each addPoint with ,false. That skips a redraw per point; the chart redraws once after all rows have run, which keeps it smooth at high message rates.
  • Multiply by 1. Matches come out as text. (regEx[4])*1 turns "1.42" into the number 1.42. Without it the point plots as zero or not at all.
5

Worked example — three accelerometer axes

This is a complete, working configuration that plots AccelX, AccelY and AccelZ from a BLE zone sensor. Copy it field for field.

Field Value
WebSocket URL ws://iperfect.net:3000
Username / Password left empty
Subscribe Topic Zone/2340_e1:0b:6f:40:82:fb
X-Axis data types 3 → named AccelX, AccelY, AccelZ
Expressions to plot 4 — one to split, three to plot
Expression 1  Is RegEx ticked /([^|,]+)/g
Expression 2 highcharts.series[0].addPoint([dt,(regEx[4])*1],false)
Expression 3 highcharts.series[1].addPoint([dt,(regEx[5])*1],false)
Expression 4 highcharts.series[2].addPoint([dt,(regEx[6])*1],false)

Read it as: row 1 chops the message into fields; rows 2–4 take fields 5, 6 and 7 and push them onto the first, second and third line of the chart, stamped with the arrival time.

Load this example in the plotter
It loads the settings but does not connect — press Connect & Subscribe. If that sensor is asleep the chart stays empty; the console tells you whether anything is arriving.
6

Field reference

Top bar

Control What it does
Status pill Not Connected · Connecting · Connected · Error. The dot pulses while a connection is live.
Connect & Subscribe Opens the WebSocket and subscribes to your topic.
Disconnect Closes the connection. The chart keeps whatever it has drawn.
Help Opens this guide.

Connection strip

Field What it does
WebSocket URL The broker. ws://iperfect.net:3000 unless you are told otherwise.
Username / Password Only if your broker demands them. Usually blank.
Subscribe Topic The topic to listen on. + matches one level, # matches the rest — Zone/# is a good way to discover what is publishing.

Chart and console

Control What it does
1M / 5M / All Show the last minute, last five minutes, or everything.
Legend Click a name to hide or show that line.
Export menu (☰) Save as PNG, JPEG, PDF or SVG, download CSV or XLS, or choose View data table to read the exact numbers.
Console The last 500 payloads with arrival times. Green lines are status messages, red are errors.
Autoscroll / Clear Untick autoscroll to hold position while reading; Clear empties the console and resets the counter.
Visible Series Coloured chips, one per line. Click to hide or show it.

Configuration

Field What it does
X-Axis data types How many lines the chart has. Press Apply to get that many name boxes.
Expressions to plot How many expression rows. Press Apply to get that many.
Is RegEx Ticked = split the payload. Unticked = run as JavaScript.
Save Configuration Applies everything and puts it in the URL. Edits do nothing until you press this.
Dump Parsed Data to Console Prints the current regEx array to the browser console (F12) so you can check your indices.
7

Expression cookbook

Splitting rows — tick Is RegEx

Payload looks like Use
12.5,13.1,9.8 /([^,]+)/g
a,b,c|1.4,-0.8,9.6 /([^|,]+)/g
X=1.4 Y=-0.8 Z=9.6 /=([-0-9.]+)/g
Any text, numbers only /[-+]?[0-9]*\.?[0-9]+/g
Fields separated by spaces /(\S+)/g

Plotting rows — leave Is RegEx unticked

Goal Write
Plot field 5 on line 1 highcharts.series[0].addPoint([dt,(regEx[4])*1],false)
Plot the last field highcharts.series[0].addPoint([dt,(regEx[regEx.length-1])*1],false)
Scale a value (mg → g) highcharts.series[0].addPoint([dt,(regEx[4])/1000],false)
Plot a difference highcharts.series[0].addPoint([dt,(regEx[4]*1)-(regEx[5]*1)],false)
Payload is JSON highcharts.series[0].addPoint([dt,JSON.parse(data.toString()).temp],false) — no Is RegEx row needed at all
Expression rows are executed as written. On this page a row that throws an error stops the rows below it for that message, so the chart appears to freeze. Check the browser console (F12) if lines stop updating after an edit.
8

Troubleshooting

What you see Why Fix
Yellow bar about HTTPS, nothing connects The page is on https://, which blocks ws:// Reopen the same address with http://
Status goes to Library Missing The MQTT client script did not load Check that iperfect.net:3000 is up; reload
Status sticks on Connecting Broker unreachable, or the URL is wrong Confirm the URL and that port 3000 is open from your network
Connected but the console stays empty Nothing is published on that topic Subscribe to Zone/# to see what exists, then narrow it
Console fills but the chart stays flat Your regEx[…] indices point at the wrong fields Recount from a real payload; use Dump Parsed Data to Console
Lines plot as 0 The field is text, not a number Add *1, and check you are not pointing at a label
Chart shows one point at 05:30 The placeholder point every new line starts with Normal. It disappears from view once real data arrives; use 1M or 5M
Edits appear to do nothing Save Configuration was not pressed Press it — the page reloads with the new settings
Chart area shows a red “library unavailable” box Highcharts could not be downloaded Check internet access to code.highcharts.com or cdn.jsdelivr.net
It slows down after a long run Every point is kept in memory Reload the page to start a fresh capture
9

The dev page

basic_line_dev.php is the same tool with three extras. Use it when the main page is not enough.

  • External MQTT Host. Fill it in and the broker will bridge another broker's traffic onto your topic, so you can plot data from a machine the browser cannot reach directly.
  • More than one Is RegEx row. Rows are written as source>pattern, for example data>/([^|,]+)/g. Each ticked row gets its own slot: the first fills regEx[0][…], the second regEx[1][…]. Note the extra index compared with this page.
  • Errors are swallowed. A row that fails is skipped instead of stopping the rest, which is more forgiving while you experiment.
Expressions are not interchangeable between the two pages: the main page uses regEx[4] where the dev page uses regEx[0][4].
Open the dev page