[{"data":1,"prerenderedAt":216},["ShallowReactive",2],{"doc-\u002Fgetting-started\u002Fconcepts":3},{"id":4,"title":5,"body":6,"description":206,"edit":207,"extension":208,"meta":209,"navigation":210,"path":211,"seo":212,"stem":213,"vertical":207,"weight":214,"__hash__":215},"content\u002Fgetting-started\u002Fconcepts.md","Concepts",{"type":7,"value":8,"toc":190},"minimark",[9,13,18,30,34,45,48,52,59,62,69,73,80,88,92,99,110,114,125,129,140,147,161,168],[10,11,12],"p",{},"OpenSense has a small data model on purpose. Once you understand these seven\nnouns, the rest of the manual reads as a sequence of CRUD endpoints around\nthem.",[14,15,17],"h2",{"id":16},"account","Account",[10,19,20,21,25,26,29],{},"The top-level container. One human, one billing relationship. An account holds\none or more ",[22,23,24],"strong",{},"sites"," and zero or more ",[22,27,28],{},"integrations"," (Telegram bot, email\nlist, webhooks, Stripe). Account-level concerns: billing, login email,\nAPI token issuance for owner-scoped operations.",[14,31,33],{"id":32},"site","Site",[10,35,36,37,40,41,44],{},"A site is a ",[22,38,39],{},"physical location",". One street address, one timezone, one\n",[22,42,43],{},"vertical"," preset (HACCP, Legionella, server-room, climate, energy). A\nchain of three cafés would model itself as three sites under one account.",[10,46,47],{},"Site-level concerns: floor-plan image, opening hours (for \"out-of-hours\"\nalarm escalation), default report recipients.",[14,49,51],{"id":50},"device","Device",[10,53,54,55,58],{},"A device is a ",[22,56,57],{},"hardware unit"," that emits measurements: a Shelly H&T, an\nEfento NS-T, a homebrew ESP32. One device may carry one or more sensors —\nthe H&T has temperature and humidity built in; an ESP32 with three DS18B20\nprobes carries three channels.",[10,60,61],{},"Device-level concerns: ingest token (rotatable), reporting cadence, hardware\nserial \u002F MAC, firmware version (reported by the device when it sends).",[10,63,64,65,68],{},"A device belongs to exactly one site at a time. Moving a device to a new\nsite does ",[22,66,67],{},"not"," rewrite history — past readings remain associated with the\nold site, which is what HACCP auditors expect.",[14,70,72],{"id":71},"sensor","Sensor",[10,74,75,76,79],{},"A sensor is a ",[22,77,78],{},"logical input"," on a device. The H&T has two sensors: one\ntemperature, one humidity. A clamp meter has three sensors (one per phase).",[10,81,82,83,87],{},"Sensor-level concerns: kind (temperature, humidity, CO₂, leak, voltage,\ncurrent, power, pressure), unit (the unit the device reports in; we do not\nre-unit), display name (",[84,85,86],"code",{},"Walk-in fridge — front shelf",").",[14,89,91],{"id":90},"channel","Channel",[10,93,94,95,98],{},"A channel is a ",[22,96,97],{},"sensor + the rules attached to it",". The split exists\nbecause the same sensor can play different roles over time. When you move a\nwalk-in fridge probe from a +4 °C wine room to a –18 °C freezer, the\nunderlying sensor is the same but the channel's thresholds change. The\naudit trail records the channel state at the time of each measurement.",[10,100,101,102,105,106,109],{},"Channel-level concerns: operating range (",[84,103,104],{},"[ok_min, ok_max]","), warning range\n(",[84,107,108],{},"[warn_min, warn_max]",", optional), grace period (how long out-of-range\nbefore alarm), severity escalation.",[14,111,113],{"id":112},"measurement","Measurement",[10,115,116,117,120,121,124],{},"The atom. A ",[84,118,119],{},"(channel_id, ts, value)"," tuple. Stored in TimescaleDB. Indexed\nby channel and time. Append-only. No edits, no deletes — corrections are\nnew rows tagged ",[84,122,123],{},"correction_of = \u003Cid>",".",[14,126,128],{"id":127},"alert","Alert",[10,130,131,132,135,136,139],{},"An alert is one event in the rule engine: ",[84,133,134],{},"channel X entered ALARM at T",",\n",[84,137,138],{},"channel X cleared at T+45 min",". Alerts are first-class — they are not derived\nfrom the measurement stream at read time, they are persisted. This is what\nmakes the audit trail reproducible: an auditor running the same query a year\nlater sees the same events.",[14,141,143,144],{"id":142},"a-note-on-kind","A note on ",[84,145,146],{},"kind",[10,148,149,150,152,153,156,157,160],{},"Some channels measure quantities that are unbounded on the warm side\n(temperature in a fridge — too warm is bad, too cold is fine in practice).\nOthers are bounded on both sides (humidity in a museum — too dry cracks\nwood; too damp grows mould). The rule engine treats both as\n",[84,151,104],{}," ranges; you simply set ",[84,154,155],{},"ok_min = -∞"," (or, in practice,\n",[84,158,159],{},"-100",") when only the upper bound matters.",[14,162,164,165,167],{"id":163},"what-is-not-modelled","What is ",[22,166,67],{}," modelled",[169,170,171,178,184],"ul",{},[172,173,174,177],"li",{},[22,175,176],{},"User"," beyond a single email per account. We are not a team product yet.\nMultiple recipients exist for alerts and reports, but they are bare emails\n\u002F Telegram IDs, not user accounts. This will change once the Team tier\nships.",[172,179,180,183],{},[22,181,182],{},"Inventory."," OpenSense does not know what is in the fridge, only the\ntemperature of the fridge. HACCP auditors do not ask \"what was on shelf\n3\", they ask \"was the fridge at the right temperature\".",[172,185,186,189],{},[22,187,188],{},"Hardware location within a site."," A device has a free-text label; there\nis no floor-plan coordinate system. A photo on the device page is the\nintended way to disambiguate \"front fridge\" from \"back fridge\".",{"title":191,"searchDepth":192,"depth":192,"links":193},"",3,[194,196,197,198,199,200,201,202,204],{"id":16,"depth":195,"text":17},2,{"id":32,"depth":195,"text":33},{"id":50,"depth":195,"text":51},{"id":71,"depth":195,"text":72},{"id":90,"depth":195,"text":91},{"id":112,"depth":195,"text":113},{"id":127,"depth":195,"text":128},{"id":142,"depth":195,"text":203},"A note on kind",{"id":163,"depth":195,"text":205},"What is not modelled","Seven nouns that appear everywhere",null,"md",{},true,"\u002Fgetting-started\u002Fconcepts",{"title":5,"description":206},"getting-started\u002Fconcepts",20,"R8dh-s1_obUmVOF4HA6tvtunmcdK-MFcqxEWhR-MH2I",1779022953301]