• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
jhiller

jhiller

IncubatorTempHumidityTracker

Public
Like
IncubatorTempHumidityTracker
Home
Code
8
.claude
1
backend
4
frontend
3
shared
3
.vtignore
AGENTS.md
CLAUDE.md
deno.json
Environment variables
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
CLAUDE.md
Code
/
CLAUDE.md
Search
…
Viewing readonly version of main branch: v187
View latest version
CLAUDE.md

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Quail egg incubator monitoring system built on Val Town. Receives temperature/humidity data from LoRaWAN sensors (RAK7204 and NanoThings NanoTag) via ChirpStack webhooks, stores readings in SQLite, sends email alerts, and displays a React dashboard.

Live URL: https://jhiller--32167624f5bc11f0947042dde27851f2.web.val.run

Development Commands

# Start local development with auto-sync to Val Town vt watch # The app auto-deploys on save - no build step required

Architecture

Platform: Val Town

  • Runs on Deno in a serverless context (not Node.js)
  • Entry point: backend/index.http.tsx exports app.fetch
  • Database: Val Town's hosted SQLite via https://esm.town/v/stevekrouse/sqlite
  • Email: Val Town's email service via https://esm.town/v/std/email
  • File serving: https://esm.town/v/std/utils for readFile and serveFile

Data Flow

  1. ChirpStack sends LoRaWAN uplinks to /webhook/chirpstack?event=up
  2. Webhook routes by DevEUI: RAK7204 (default) or NanoTag (9c65fafffe02607a)
  3. Payloads decoded: RAK7204 uses Cayenne LPP, NanoTag uses port-based format
  4. Readings stored in separate SQLite tables per sensor type
  5. RAK7204 readings trigger alert checks (NanoTag is temperature-only, no alerts)
  6. Dashboard polls /api/status and /api/readings every 60 seconds

Sensor Calibration

Defined in shared/constants.ts:

  • RAK7204: -2Β°F offset
  • NanoTag: +1Β°F offset
  • Dashboard displays calibrated values; alerts use calibrated RAK7204 temperature

Incubation Logic

  • 17-day Coturnix quail incubation starting from configured date
  • Lockdown phase begins day 15 (higher humidity target)
  • Temperature thresholds: ideal 101-102Β°F, warning Β±3Β°F, critical Β±5Β°F
  • Alerts rate-limited: critical every 5 min, warning every 30 min

Frontend

  • React 18.2.0 with TailwindCSS (twind)
  • Initial data injected into HTML via window.__INITIAL_DATA__ to avoid round-trips
  • Chart.js for historical temperature/humidity visualization

Key Conventions

Imports

  • Use https://esm.sh for npm packages (works in both Deno backend and browser)
  • Pin React to 18.2.0: https://esm.sh/react@18.2.0
  • Start React files with /** @jsxImportSource https://esm.sh/react@18.2.0 */

Shared Code

  • shared/ must work in both frontend and backend
  • Cannot use Deno namespace in shared code
  • Types and constants live here

Database

  • Table names include version suffix (e.g., incubator_readings_v1)
  • Migrations run lazily on first request
  • To change schema: create new table with incremented version, don't ALTER

Val Town Specifics

  • Use Response constructor for redirects (not Response.redirect)
  • Avoid alert(), prompt(), confirm() browser APIs
  • Environment variables: Deno.env.get('KEY')
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2026 Val Town, Inc.