Live streams
Open history in the app
Open any time range of a history, zoom to every stored value, follow it live, keep incidents and export CSV, MF4 or Parquet.
A stream its collector records (record: always or trigger) is stored day by day. This page shows how project members open any time range of it in the Kymoscope app, zoom down to every stored value, follow it live, keep the raw data of an incident and export it. It is for the customer engineer who reads the data and for the IT reviewer who approves what the browser connects to. The Cloud window itself (recordings, marks, cycles) is described in Recordings.
What you can open
Any stream recorded by a collector in a project you belong to. Open it from the Cloud button in the workspace rail: such streams are marked Automatic under Projects.
Open a range
- Click Cloud and pick the stream under Projects.
- Pick a range: Today, Last 7 days, Last 30 days, or Custom with From and To in your browser's time.
- Leave the selection empty and click Open range. The range opens as one dataset in the workspace, with every channel (up to 1,000).
To open single recordings instead (a shift, a run), select them and click Open N recordings; see Recordings.
The chart's X axis reads as date and time in the site's time zone: the zone the collector cuts days in (recording.timezone). Chart times: Site time / My time under the range switches the chart to your browser's zone. Your choice is remembered in this browser. With several streams in different zones open, the first one's zone is used for all of them.
To cut the range into batches, cycles or shifts and compare them, see Cycles.
Zoom and resolution
The app reads the level of detail that fits the span on screen:
| Span shown | What is read |
|---|---|
| About 6 weeks or more | 1-hour summaries: the minimum and maximum of every hour |
| About 17 hours to 6 weeks | 1-minute summaries: the minimum and maximum of every minute |
| Less than about 17 hours | Every stored value |
Zooming reads the finer level for what you see, and zooming out shows the whole range again at once. Summaries draw the true minimum and maximum of every minute or hour, so no spike is lost on a long range.
Today and the live part
Today's 1-minute and 1-hour summaries arrive during the day, every 15 minutes by default (the collector's recording.today_every_min; 0 uploads them only at midnight). Today at full resolution arrives after the site's midnight, when the day is closed.
A preset range (Today, Last 7 days, Last 30 days) ends now. When the stream is live, Open range adds the live stream after the stored data, in the same colour, and keeps today's summaries up to date. A custom range has no live part. If the live stream can't be connected, the range still opens and the window says so.
Gaps
Where the collector stored nothing, the line breaks instead of drawing a flat line: spans with no value at all (longer than a few times the usual spacing between points at the current zoom), and days not uploaded yet. A gap longer than the collector's recording.split_gap also ends a recording, so it shows as a break between bars on Coverage.
Keep full-resolution data
Keep on a recording holds every raw value of it past its normal retention, for example a batch or an incident you may be asked about. The recording then shows Kept.
- Any project member can keep a recording while the Historian is on for your organization.
- The whole site-local days the recording touches are kept, up to 7 days per recording, for as long as it is kept.
- Each organization has 10 kept recordings per calendar year included; more are billed as extra.
Export
Click Export on a recording, then CSV, MF4 or Parquet. The browser asks where to save the file, then writes it day by day, with every channel (up to 1,000).
| Format | Columns |
|---|---|
| CSV | Wide: time, then one column per channel. The second row holds the units. One row per distinct time; times are ISO 8601 UTC with microseconds (2026-10-24T08:15:00.250000Z); a cell is empty where a channel has no value then. Values are written exactly as stored. |
| MF4 (ASAM MDF 4) | Wide: time in seconds since the first row (the file’s start time is that row, in UTC), then one channel per channel; no value is NaN. Opens in MDF tools such as asammdf or CANape. |
| Parquet | Long: time (timestamp with time zone, microseconds), channel, value (float), sorted by time and channel, zstd-compressed. The best choice for many channels or long ranges. |
Every stored raw value of the range is exported. Today is not included: its full-resolution data is stored after the site's midnight. Days whose raw data has expired and that only have summaries left are skipped, and the window names them when the export ends.
Limits, because the file is built in the browser: CSV and MF4 hold up to 25 million cells per day (distinct times × channels); Parquet holds up to 30 million values per export. Past them, export a shorter range or fewer channels.
Automating what comes next
An exported Parquet file reads directly in pandas or DuckDB:
import pandas as pd
df = pd.read_parquet("Customer_A.parquet") # time (UTC), channel, value
wide = df.pivot_table(index="time", columns="channel", values="value")
print(wide.resample("1min").mean().tail())-- DuckDB CLI
SELECT channel, min(value), max(value), count(*) FROM 'Customer_A.parquet' GROUP BY channel ORDER BY channel;Your own web app can do what the Cloud window does with the SDK: readHistoryRange reads a range at a level of detail, engine.datasets.openHistoryRange and updateHistoryRange show it in a chart, exportHistoryTo writes CSV, MF4 or Parquet, and blockCache keeps the bytes read in the browser. The app provides the stored files, the history key and the byte ranges to fetch. With onMissing: 'gap', a file your fetchRange reports as gone (an error with code: 'missing') is read as a gap for its day and listed in missingDays; an export then lists that day in skippedDays and missingDays.
import { blockCache, chooseLevel, exportHistoryTo, readHistoryRange } from '@kymoscope/sdk'
// segments: the stored files of the days in range; key: the history key by id;
// fetchRange: bytes [start, end) of a file. Your app provides all three.
const cache = blockCache()
const view = await readHistoryRange({
historyStreamId, segments, t0, t1, channels: ['FIC101', 'TIC200'],
level: chooseLevel(t1 - t0), key, fetchRange, cache,
})
engine.datasets.updateHistoryRange(datasetId, { name: 'Customer A', pieces: view.pieces, units: view.units })
// The same days as a file: every stored raw value, written part by part.
const { skippedDays } = await exportHistoryTo({ historyStreamId, segments, t0, t1, channels, key, fetchRange, cache },
'parquet', (part) => writer.write(part))Who can read it
- Members of the project with view access.
- When the project requires two-step verification or browser approval, they apply to reading history too.
- Your browser downloads the encrypted day files and decrypts them itself. The Kymoscope server never sees the values.
- Reading does not need the Historian to be on: stored days stay readable until each day's retention ends, also after the add-on ends.
Offline copy
The browser keeps the encrypted bytes it has read, up to 2 GB, so a range opens again instantly. Only encrypted bytes are stored on the device, never decrypted values. Clearing the site's data in the browser removes them.
Troubleshooting
| Message | What to do |
|---|---|
| This history isn’t available to you. | You are not a member of its project, or it was deleted. Ask a project lead to add you. |
| This project needs two-step verification. | Turn on two-step verification in your account settings, then open the range again. |
| This browser needs to be approved before it can read this project’s history. | Ask a project member to approve this browser in the project, then try again. |
| This history’s key isn’t available on this browser. Approve this browser in the project, or the project key was regenerated after these days were stored. | Ask a project member to approve this browser in the project, then open the range again. If it is already approved, the project key may have been regenerated; ask a project lead. |
| Nothing is stored for these channels in this range. | Pick another range or other channels. The collector may not have uploaded these days yet. |
| This range has too many distinct times for one table. Export it as Parquet, or pick fewer channels or a shorter range. | CSV and MF4 hold one row per distinct time. Use Parquet, or split the export. |
| This export has more than 30 million values, too many for Parquet in the browser: export a shorter range or fewer channels. | Export the range in parts. |
| History storage can’t be reached. Try again. | Check that the browser can reach the storage host below. |
| Keep windows need the Historian on your organization’s plan. | Ask your organization owner. Reading and exporting work without it. |