In September, UNR switched on a network of sensors in and around Lake Tahoe and made it public. Two days later I started reading along. There was no manual, so I learned the network the slow way, one question at a time. Along the way I found a lake that only looked short of breath, trees that breathe on a daily schedule, a forest station sitting in a soggy canyon, and a plate on a rope that still keeps score for all of it. Here’s what I built and what the lake has taught me so far.

The project at a glance

What it is
A live dashboard for Lake Tahoe and the forest around it: sondes in the lake, weather, soil and tree sensors in the woods, and USGS stream gauges, all on one page.
Where the data comes from
Mostly the Tahoe Environmental Observatory Network (TEON, University of Nevada, Reno), with the U.S. Geological Survey. A few long records from outside the network sit alongside as context.
How much
About 12 million observations, June 2024 to now, in a store anyone can clone and query with SQL.
How it runs
GitHub Actions fetch new data through the day, publish the page, and keep an eye on TEON’s inventory for anything that changes.
Go look
brooksgroves.com/secchi · code on GitHub

A plate on a rope

In 1865 a commander in the Papal Navy asked an astronomer a simple question: how clear is the water?

Angelo Secchi lowered a white plate over the side of a yacht in the Mediterranean and wrote down the depth at which it disappeared.

That’s the whole instrument, and it’s still the world standard for lake clarity a hundred and sixty-one years later. It’s how Lake Tahoe’s famous clarity gets reported every year. In the late 1960s the disk stayed visible down to nearly 100 feet. In 2025 the yearly average was 69.2 feet. A great deal of restoration work around the lake is aimed at closing that gap, and the scorecard is still a plate on a rope.

The disk tells you how clear. It can’t tell you why. The why lives in sediment washing in off the hillsides, algae growing in the water, snowmelt, storms, and the soil in between. On September 15, 2026, UNR put the why on the internet: sondes in the lake, data loggers in the forest, cameras on the ridgelines, reporting every fifteen minutes.

I got my undergraduate degree at UNR. Two days later I was pulling their data, and I named the project after the plate.

Learning the network’s language

TEON’s website is a friendly map that talks to a backend in the background. There was no published guide to that backend yet, so everything I know about it came from watching what my browser asked for and trying URLs until they answered.

The naming turned out to have a charming logic of its own. The data addresses don’t use a sensor’s full display name. They use its first idea:

"Air Temperature & Relative Humidity"  →  /sensors/air-temperature
"Tree stress and growth"               →  /sensors/tree-stress
"Soil Environmental Conditions"        →  /sensors/soil-moisture

All ten sensor types resolved eventually. The last one was the oxygen logger, minidot-sensor, the one spelling my first guesses happened to skip.

The habit that came out of this turned out to be the most useful thing in the whole project. Don’t write code that assumes a URL. Write a little probe that tries the possibilities against the real server and reports which ones answer. Wherever I did that, I learned fast. Wherever I skipped it, I learned later.

Forty-three sensors, thirteen boxes

TEON’s inventory lists forty-three sensors. Out in the woods, it’s a tidier picture than that.

At each forest station, the soil, air, tree and stream readings all come from one data logger, a single box on a post with everything wired into it. The giveaway was a column called PTemp_C_Avg: the logger reporting the temperature inside its own enclosure. Put that next to the battery readings and a storage bucket named teon-loggernet-data-storage, and the hardware more or less introduced itself: Campbell Scientific loggers sending their readings to the cloud.

Count the boxes and forty-three sensors become thirteen physical devices. It’s a small thing, but it matters for anyone comparing sites: thirteen places, each measured many ways.

One lesson took me a while. Each slice of a logger’s table shares the same rows but carries different columns, soil fields in one, air fields in another. Early on I fetched one slice and let it stand in for the rest, and quietly lost every air-temperature, humidity and tree reading in the history. Same rows, different columns: ask for each one. They’re all back now.

The ones you have to swim out to

Two of the lake sondes have Manual in their names, and their records stop every so often. My first guess was that they kept breaking. The completeness numbers told a much nicer story:

Sonde Telemetry Records Expected Complete
Blackwood 3manual15,45115,64298.8 %
Meeksmanual15,44115,63298.8 %
4H Camplive52,44354,34496.5 %
Glenbrooklive46,27147,81196.8 %
Sunnysidelive38,56252,42273.6 %

The “manual” sondes are the most complete records in the lake. They log to their own memory and almost never miss a reading. The live ones lose whatever the radio drops along the way.

Then came the detail that settled it. Both manual sondes are short by exactly 191 readings, which is 47.75 hours. Two instruments, the same two-day gap: that’s a service visit, with both units out of the water at once. TEON’s own StoryMap fills in the rest:

“Emily Carlson and Katie Senft ride and snorkel to their sensors every month, come rain, shine, and even snow in the winter months.”

Every month, by boat and snorkel, to wipe algae off the optical windows before the readings drift. I think about that every time I open the dashboard.

It changed how I think about monitoring, too. A radio buys you timeliness. A logger someone faithfully visits can buy you a better record. Often the radio’s best gift is simply knowing the station is still out there, alive.

The lake that looked out of breath

This is my favorite finding in the project, and I guessed wrong on the way to it.

TEON’s big EXO sondes report dissolved-oxygen saturation of about 83 to 86 %. For a cold, clear, well-mixed mountain lake, that reads like a lake that’s slightly short of breath.

Here’s the thing about altitude. Tahoe’s surface sits around 6,227 feet, where the air pressure is only about 80 % of what it is at sea level. How much oxygen water can hold depends on that pressure, so if you measure the percentage against sea-level air, a perfectly healthy lake up here looks about twenty points low.

So I recomputed saturation from each sonde’s own oxygen and temperature readings, at the lake’s real pressure:

InstrumentSitesPublishedAt lake pressureMean gap
EXO sondes483–86 %104–108 %+21.75
MiniDOT loggers6100–104 %99–104 %−0.41

I expected both kinds of instrument to show the same offset. They don’t. The little MiniDOT loggers already account for altitude, agreeing with my math to within half a point at all six sites across 265,000 readings. It’s the EXO sondes that are referenced to sea level. That turned out to be the most useful part: it points to a settings detail on one model of sonde, and the network’s own MiniDOTs show the altitude-aware way already working beside it.

The lake isn’t short of breath at all. It’s slightly over-saturated, which is normal in summer, when warming water and daytime photosynthesis nudge oxygen a little above equilibrium. The dashboard shows TEON’s number and the altitude-corrected one side by side and never overwrites theirs. Anything I calculate is labeled “computed from…” so nobody mistakes my number for theirs.

Growing pains

Any brand-new network has a few readings that make you tilt your head, and this one is no exception. The pH probes, always the shortest-lived sensor on a sonde, read zero or nothing. One sonde’s turbidity sits a steady couple of units below zero, which looks like a zero point that needs resetting rather than noise, and a USGS gauge on a nearby creek agrees the water there is about as clear as water gets. The cameras keep UTC while the loggers keep Pacific time, so one camera frame appeared to arrive six hours after the snapshot that contained it. None of it is surprising in a network that had been public for a few days, and I’ve shared what I noticed with the TEON team.

Same storm, two shores

The question I most wanted to answer: does the same storm treat the two sides of the lake differently?

Tahoe sits in a rain shadow. The west shore catches Pacific storms first, and the east shore, tucked behind the Carson Range, gets what’s left. Find two stations at the same latitude on opposite shores and you have a natural experiment: same storm, same sun, opposite sides.

Picking the pair took three tries. The one I settled on is Homewood on the west shore and Glenbrook 5 on the east, both on hillslopes and just 64 meters apart in latitude. TEON’s watershed layer, 60 catchments with 164 attributes each, gave the setup a number to start from:

Homewood      (Madden Creek catchment)     1,463 mm/yr
Glenbrook 5   (Glenbrook Creek catchment)    689 mm/yr
                                           ─────────
                                               2.12×

About twice the precipitation, on the same line across the map. So does twice the water reach the soil? Over 376 days of overlapping record, the west-shore soil took in 2.32 times as much wetting as the east. And 15 of the 18 storms both stations felt reached the west shore first, just as you’d expect from weather rolling in off the Pacific.

Then I checked it against the rain that actually fell, from the federal snow-survey gauges near each shore. The answer came back as a range rather than a single number, which I’ve come to like. At the gauge closest to Homewood’s catchment, the west got 2.16 times the east’s precipitation; at a second west-shore gauge ten kilometers south, 1.20 times. Precipitation on the west shore changes a lot over a few miles. In the ten real storms, the shore that got more rain also wetted more seven times. And eight of the soil’s wetting events came with no rain at all. They all fell between October and April, and five of them line up with a shrinking snowpack: snowmelt, soaking in on its own schedule.

One honest footnote. Early versions of this analysis reported a precise time for storms to cross the lake, first three hours and then twelve. Both came from how I matched events, not from the weather. Soil moisture rises and falls every day, so storm arrivals can only be pinned to the day, not the hour. The direction is solid. The crossing time will have to wait for a better method.

The trees breathe

This one delighted me. Five of TEON’s forest stations carry band dendrometers: fine metal bands around tree trunks, read to the micrometer. Every fifteen minutes they report how the trunk’s size has changed.

A trunk turns out to breathe on a daily schedule. It refills with water overnight and shrinks through the day as the tree loses water through its needles faster than its roots can replace it. At every station, across 33 of 36 working bands, the stems are largest around 7 in the morning and smallest in the middle of the afternoon.

How far a trunk shrinks between that morning peak and the afternoon low is how hard the tree worked for water that day. In winter it’s close to nothing. By July and August it’s 30 to 40 micrometers, about the width of a fine human hair. Hotter days bring more of it at every station, and at Blackwood 2, on the west shore, drier soil does too.

The trees at Homewood shrink about a third as much as Glenbrook 5’s do in the same weeks. That fits the wetter west shore beautifully, but I don’t yet know which species each band is on or how big each trunk is, and either could explain the difference by itself. It’s on my list of things to ask.

The soggy station, and the ground that explained it

Glenbrook 2 is a forest station on the east shore, and it is wet. For a while I quoted it as twelve times wetter than its neighbors, which came from comparing it to dry sites on one late-summer afternoon. Over a full year it averages 46 % soil moisture against 11 to 16 % nearby: three or four times wetter, still easily the wettest station in the network.

I first tried to explain it with the data I already had, three different ways, comparing the soil with the creek next to it. None of them could tell a stream-fed soil from an ordinary one. It was a good lesson in testing a method on data where you already know the answer before trusting what it says.

So I went and looked at the ground itself, which as a GIS person I probably should have done first. I sampled the national soil survey, USGS elevation data and USGS stream maps at every forest station, and Glenbrook 2 stood right out:

It’s a riparian site on a canyon floor, where the water from the slopes gathers. I’d call it probably explained rather than proven. A photo of the site would settle it, and I’d love to see one.

A five-digit code that turned out to matter

Late in the build, a USGS parameter code I didn’t recognize showed up at the Upper Truckee River gauge: 70369. Rather than guess, I wrote a small lookup and asked:

70369 — Suspended sediment particles between 0.50 to 16.00 microns, water, unfiltered, computed by regression equation, counts per liter

Half a micron to sixteen microns is exactly the size of fine sediment that’s blamed for Tahoe’s lost clarity. It’s the main pollutant in the lake’s cleanup plan, which aims to bring clarity back to 97.4 feet, the late-1960s average. So that code, at the lake’s biggest tributary, is the very thing the plan is working to reduce, estimated continuously. On the dashboard it’s labeled as what it is: an estimate calculated from turbidity, not particles counted in a lab.

The long records

A fifteen-minute sensor network is wonderful at telling you what’s happening now. It can’t tell you what’s normal. For that, the dashboard now keeps a few long records alongside TEON’s, tucked into their own section and drawn quietly beneath TEON’s pins on the map:

Keeping watch

A lot of what I care about here changes without warning. The manual sondes post nothing until somebody snorkels out. Stations go quiet for a while and come back. TEON can mark a site as non-public, and the dashboard respects that; if it can’t read the flag, it leaves the station out rather than guess.

So a small watcher runs every six hours. It compares TEON’s inventory with what it saw last time and opens a GitHub issue, which lands in my email, when something real changes. It also reads each station’s battery voltage, so when a field crew swaps a battery on a remote ridge, the dashboard notices that too.

I learned the importance of all this the hard way, once. My first attempt at pulling the full history rewrote the whole store every time it saved, filled up the disk halfway through, and lost about 76,000 readings in the process. Every one of them came back from TEON, and now every save is written safely first and swapped into place. It was a humbling night and a good lesson.

What I learned

Here’s what I’d pass along to anyone starting a project like this.

  1. Count the rows. Almost every bug I made was the same bug in a different outfit: something that quietly returned nothing and reported success. Zero rows looks exactly like no data, so check the count, not just that it ran.
  2. Ask, don’t assume. A few dozen lines of probe code, asking the real server what it actually has, caught more problems than anything else I wrote.
  3. When everything misses, look for one mistake. My first attempt to place stations in their catchments matched zero of twenty-eight. A scattered miss means messy data; a total miss means one systematic error. Here, the catchment map was in meters and my stations were in degrees. The fix came from the one thing I knew for sure: the data should land on Lake Tahoe.
  4. Try a method where you know the answer. Glenbrook 2 taught me that a method that can’t tell your idea apart from its opposite isn’t weak evidence. It’s no evidence.
  5. Dramatic numbers tend to soften. Twelve times wetter became three or four. A precise storm-crossing time became “not measurable yet.” Every correction moved toward less dramatic, which is usually how you know you’re getting closer.
  6. Corrections are part of the record. I’ve kept my early numbers in this post on purpose. They’re how you can tell the current ones were earned.

What’s next

To be clear about what this is and isn’t: the researchers at TERC have been lining up decades of clarity drivers against the Secchi record for years, with the instruments, the history and the expertise. This project isn’t new science. It’s a fast, public, reproducible window onto data that’s otherwise spread across several agencies, with its own uncertainties written right on the page. I think that has real value. It’s just a different kind of value.

The personal bit

I went to UNR. I drove around that lake more times than I can count and never once wondered how the clarity number gets made.

It gets made by researchers in a boat with a snorkel, every month, in the snow, wiping algae off optical windows. It gets made by a plate on a rope that a Vatican astronomer came up with in 1865 and that nobody has improved on since. And now it also gets made by a dozen quiet boxes in the woods and on the water, sending their readings to the cloud every fifteen minutes.

My favorite thing in the whole dataset isn’t a sensor reading. It’s one line in USGS’s description of the Tahoe City gauge:

Datum of gage is 6,220.00 ft above U.S. Bureau of Reclamation datum.

Without that line, the lake level reads 7.07 feet, which means nothing. With it, the surface is at 6,227.07 feet: about four feet above the natural rim and two feet below the legal maximum. Above the rim, Tahoe spills into the Truckee River and on toward Pyramid Lake. Below it, the lake stops draining and holds onto its water.

Four feet of margin, tucked into a station note. The dashboard shows it now, with the rim and the legal ceiling beside it, because 7.07 tells you nothing and 6,227.07 tells you where the lake stands.

To Emily, Katie and everyone at TEON who built this network and opened it up for anyone to read: thank you. It’s been a joy to get to know the lake this way.


🌲 The code is on GitHub, MIT licensed. The data belongs to TEON (University of Nevada, Reno) and USGS, with context from UC Davis TERC, UC Berkeley’s Central Sierra Snow Laboratory, NRCS SNOTEL and NOAA. If you’re at TEON and reading this: hello! I’m always happy to compare notes.

First published September 18, 2026. Rewritten September 26 with the oxygen finding and the storm results, and again October 3 with the trees, the Glenbrook 2 explanation, the rainfall check and the long records, in a friendlier voice.


Go deeper

🎧 Listen & watch

#022 – Geoffrey Schladow: Exploring Lake Tahoe’s Ecosystem From Clarity to Microplastics — Discovering Academia, 20 July 2023, about 1 hr 13 min. The longtime director of UC Davis TERC on clarity, oxygen and what’s washing into the lake.

#019 – Brant Allen: Aquatic Explorations: Lake Tahoe & Why You Need to Get Your Face Wet — Discovering Academia, 30 June 2023, about 1 hr 1 min. TERC’s boat captain and field director on lowering the Secchi disk and why fieldwork means getting wet.

Lake Tahoe clarity improves slightly, but researchers see no meaningful change — KUNR Public Radio, 12 June 2026, about 2 min. Maria Palma on the 2025 number, just over 69 feet, and why it’s still a plateau.

📄 Read

Goldman, C.R. (1988). Primary productivity, nutrients, and transparency during the early onset of eutrophication in ultra-oligotrophic Lake Tahoe, California-Nevada. Limnology and Oceanography 33(6), 1321–1333.

Swift, T.J., Perez-Losada, J., Schladow, S.G., Reuter, J.E., Jassby, A.D. & Goldman, C.R. (2006). Water clarity modeling in Lake Tahoe: linking suspended matter characteristics to Secchi depth. Aquatic Sciences 68(1), 1–15.

Benson, B.B. & Krause, D. Jr. (1984). The concentration and isotopic fractionation of oxygen dissolved in freshwater and seawater in equilibrium with the atmosphere. Limnology and Oceanography 29(3), 620–632.

Zweifel, R., Haeni, M., Buchmann, N. & Eugster, W. (2016). Are trees able to grow in periods of stem shrinkage? New Phytologist 211(3), 839–849.

Tahoe: State of the Lake Report — UC Davis TERC’s yearly checkup, with the Secchi record front and center.

The Tahoe Environmental Observatory Network goes live — Nevada Today, 15 September 2026; the launch story, with short videos of the dive team at work.

📊 Data & agencies

TEON — the University of Nevada, Reno network behind most of the dashboard. · UC Davis TERC — keepers of the Secchi record since 1967.

USGS 10337000, Lake Tahoe at Tahoe City — home of that favorite datum line. · USGS 10336610, Upper Truckee River at South Lake Tahoe — where code 70369 turned up.

Central Sierra Snow Laboratory — UC Berkeley’s snowfall record since 1879. · NRCS Snow Survey & SNOTEL — the snow-survey rain gauges. · NOAA Hazard Mapping System — the satellite smoke analysis.

Lahontan Water Board: Lake Tahoe TMDL — the cleanup plan aiming for 97.4 feet. · secchi dashboard — the live page. · secchi on GitHub — this project’s code.