Thermal camera · Studio 45

Taking data off the P3 thermal camera

How to watch, record and pull the thermal camera's data at Studio 45, from anywhere. Every recipe below was run on Sat 17 Oct 2026 (week 42), 04:1x–04:3x PDT, from a Mac outside the lab, while the phone streamed on the lab's Ethernet with app 1.5.4.

The short version: anyone with the link gets the live temperatures at once, and the video after a quick "are you a person" check. For a temperature record, press Record on the page, from anywhere. For full 256×192 frames at 25 a second, use the phone's own API from inside the lab network.

What the camera sends

A Thermal Master P3 (256×192 pixels, 25 frames a second) is clamped behind an ET-SoC-1 card in the AI Foundry lab. A phone drives it and publishes three things:

Stream What it is Radiometric? Rate
Video on the page colour picture, 768×576 No: auto-gained 8-bit, for looking 25 fps
Telemetry on the page min, max, mean, centre °C, the camera's own temperature, and an 80×60 grid of the scene Yes, see the limits below about 8 a second
Raw frames on the lab network every pixel, 1/64 K counts Yes: the full data 25 a second

Pick your path

You want Use You need Resolution
To watch it the live page a browser; the video starts after a person check, or a sign-in the picture plus live °C readouts
A temperature record, from anywhere the page's ● Record button the page open while you record every reading's summary; the 80×60 °C grid once a second
Full frames the phone's HTTP API, http://p3-phone:8080 a login on aifoundry1–3, or a laptop on the Studio45 Wi-Fi 256×192, 1/64 K, 25 a second

1. Watch

Open spacesheep.dev/@yaroslavvb/thermal-master-p3-live-camera-stream. The temperatures and the chart are live at once, with no account. The video starts after spacesheep's quick "Verify you are human" check on the picture, or as soon as you sign in. Hover over or tap the image to read a spot's temperature.

The chip on the video says how fresh the picture is, e.g. "Delay 0.46 s · 25 fps": green under a second, amber up to five, red beyond that. A red banner covers the picture if the video stops moving for more than two seconds, so you never mistake a frozen frame for a live one. The buttons that change the camera work only for the page's editors.

2. Record temperatures from anywhere

In the Take data off the stream box, press ● Record, leave the tab open, then use the download buttons:

It keeps up to 30 minutes, runs entirely in your browser, needs no key and uploads nothing. It records only while the tab is open.

3. Full frames from the lab network

The phone answers on the lab's private Ethernet as p3-phone (10.45.0.55, a fixed lease). From any of aifoundry1–3 that name already works. On the Studio45 Wi-Fi the phone is at 192.168.0.221 (a DHCP lease, so it can change). The read endpoints need no password inside the lab.

One frame in °C (192 lines of 256 comma-separated values, emissivity 0.96):

curl -s http://p3-phone:8080/frame.csv -o frame.csv

Is it alive?

curl -s http://p3-phone:8080/health

The live lossless stream (/stream.raw.z: about 7.7 Mbit/s, every frame), in plain Python:

import array, struct, urllib.request, zlib

r = urllib.request.urlopen("http://p3-phone:8080/stream.raw.z")

def read(n):
    b = b""
    while len(b) < n:
        b += r.read(n - len(b))
    return b

HDR = "<4sIqqqqqihhfBBH"  # 64 bytes: magic "P3FZ", version, frame seq, mono ns, wall ns,
                          # cnt1, cnt2, cnt3, width, height, camera temp °C, gain, auto-FFC, spare
while True:
    (n,) = struct.unpack("<I", read(4))          # each frame: a 4-byte length, then zlib data
    raw = zlib.decompress(read(n))               # 99,392 bytes
    h = struct.unpack(HDR, raw[:64])
    seq, wall_ns, w, ht = h[2], h[4], h[8], h[9]
    counts = array.array("H", raw[1088:1088 + w * ht * 2])   # uint16, row-major, 1/64 K
    temps_c = [c / 64 - 273.15 for c in counts]               # 256 x 192 values in °C
    print(seq, wall_ns, min(temps_c), max(temps_c))

wall_ns is the phone's clock when the frame was captured, so time.time_ns() - wall_ns is how late the frame reached you.

Please:

What the numbers mean

Measured on Sat 17 Oct 2026

Test, from outside the lab Result
The page, signed out, in a fresh browser temperatures live at once; the chip read "Delay 0.42–0.60 s · data only"; the video waits for the person check
Phone to screen, telemetry 0.38–0.42 s
Record, then Download CSV a real download, with grids decoded to each frame's own min and max (in a test browser at phone width)
Telemetry through spacesheep, 15 s 115 values with none missing, 7.9 a second, each about 13 KB
The 80×60 grid, decoded 38.98–45.16 °C, matching the reported min 38.975 and max 45.163
/frame.csv 256×192 °C in 1.6 s
/stream.raw.z, 4 s 97 frames with none missing, 24 fps, 7.7 Mbit/s
Capture to arrival, raw frames about 0.33 s, of which about 0.04 s is the network (72 ms round trip)
p3-phone from inside the lab not run today: there was no lab login from outside. The same endpoints answered from outside the lab, through the same code path