Back
Climacert‑X — Certification Scoring & Shifts — Consolidated Spec v1
Wireframe

Table of Contents

1) Goals & Scope

Goals

  • Deliver a fair, transparent, auditable IEQ certification with compact storage.
  • Support clear roll‑ups from device → asset → facility with minimal ambiguity.
  • Make tenant shift edits possible (if allowed) while capping Non‑Active misuse.

Scope

In Scope (Facilities): Retail Stores, Villas, Offices, Schools.

Out of Scope (for now): other facility types (e.g., clinics, hospitals, DCs). Automated HVAC control and occupancy inference.

2) Glossary & Key Definitions

  • Asset: A scoring unit under a facility (Location/Space/Subspace).
  • Bucket: Fixed window. Hourly (Temp/RH/Odor/Cold/Water) or 15‑min (CO₂; 96/day).
  • Within (device): 1 if device’s bucket value is inside the active band at bucket time; otherwise 0.
  • Expected (device): Temp/RH/Odor/Cold/Water = D×24, CO₂ = D×96; D = days in the scoring window.
  • Actual (device): number of device buckets actually produced in the window.
  • Within% (asset/facility): within_bucket_count / Expected × 100.
  • Provisional: First 7 scoring days; counts toward math but certificate is hidden.
  • Trending: Month‑to‑date indication only; not a certificate.

3) Policy Decisions (Final)

  • Roll‑up: Facility score = simple average of its assets’ scores (equal weight).
  • Per‑device completeness gates (monthly): Silver ≥ 70%, Gold ≥ 80%, Platinum ≥ 90%.
  • Retention: Monthly rollups kept forever; device‑bucket rows purged month close + 7 days.
  • Shift Editing: Super Admin may allow tenant edits; daily Non‑Active caps enforced at asset and facility scopes; Cold/Water cannot be Non‑Active.
  • Mid‑Month Start: Start after 48h stability → next local midnight; Provisional 7 days; partial‑month denominator from scoring start.
  • Vape KPI: Days with ≥1 event during Active hours / days in window < 10%.
  • Tie rule: For IAQ/Odor/CO₂ quorum, ≥ 50% within counts as within; equals (ties) are within.

4) Architecture & Flow

Component responsibilities: Ingest → Evaluate → Roll‑up → Publish → Admin.

5) Data & Storage (Lean)

Device×Bucket (upsert)
- bucketStartUtc, value_last, within (0/1)
- Upsert semantics; last‑write‑wins inside bucket window
- No long‑term raw time series
Retention
- Purge Device×Bucket +7 days after month close
- Keep MonthlyRollup indefinitely

6) Templates, Shifts & Caps

Templates

  • Threshold bands per parameter family. Versioned with effective_from; prospective only.
  • Cold/Water: enforced 24/7 bands; cannot be set to Non‑Active.

Shifts & Tenant Editing

  • Policy: allowTenantShiftEdit, dailyMaxNonActiveHours, exemptParameters=["Cold","Water"].
  • Tenant edits validated against caps; prospective only; historical results unchanged.

Caps (Daily‑Only)

  • Daily max Non‑Active hours per asset and per facility (both enforced, choose stricter); default 8h/day.
  • Monthly caps are removed in this version.

7) Ingestion → Evaluation Pipeline

  • Normalize timestamps to UTC; track facility TZ for band evaluation and UI.
  • Bucketize: Hourly for Temp/RH/Odor/Cold/Water; 15‑min for CO₂.
  • Device×Bucket Persist: upsert value_last; compute within against band at bucket local time.
  • Quorum (asset per bucket):
    • IAQ/Odor: valid if ≥ ceil(n/2) devices report; asset within=1 if ≥ 50% of reporting devices within.
    • CO₂: same, per 15‑min bucket.
    • Cold/Water: all devices must report; asset within=1 only if all within.
  • Roll‑up: compute counters and percentages; facility = average of assets.

8) Scoring Model (Formulas)

Let D = number of days in the scoring window for the month (partial allowed).
Expected (per device):
- Temp/RH/Odor/Cold/Water: Expected_device = D × 24
- CO₂: Expected_device = D × 96
Actual (per device): Count of device buckets produced.
Completeness_device = (Actual / Expected_device) × 100
Asset Level (apply quorum):
- Promote device buckets → asset buckets using quorum rules.
- Expected_asset equals the device expected for that family.
- Actual_asset = count of valid asset buckets (quorum satisfied).
- Within%_asset = (within_asset_bucket_count / Expected_asset) × 100
Per‑Device Completeness Gates (month):
- If any mapped device for a family has Completeness_device below tier gate (70/80/90), cap that family at Silver(⚠).
Facility Level:
- For each family, facility Within% = simple average across assets.
- Final level uses tier bars: IAQ/Odor (70/80/90), Cold/Water require ≥ 99%.
- Vape KPI: days_with_event_in_active / days_in_window < 10%.

9) Mid‑Month Activation & Provisional

  • Activation gate: Admin completed + Tenant confirmed install.
  • 48h stability: ignore buckets until 48h of healthy ingestion pass.
  • Scoring start: next local midnight after stability.
  • Provisional: days 1–7 counted but certificate hidden.
  • Partial‑month denominator: Expected starts from scoring start (e.g., start on the 22nd of a 30‑day month → D = 9).

10) Vape Rules

  • Primary: VapeIndex ≥ 80 for ≥ 10s → 1 event; dead‑time 120s.
  • Fallback: TVOC ≥ 800 ppb AND PM1.0 ≥ 75 µg/m³ for ≥ 10s → 1 event; dead‑time 120s.
  • KPI: Days with ≥ 1 event during Active hours divided by days in window must be < 10%.

11) Worked Examples (Facility)

11.1 Retail (Activation on 20th; start 22nd → D=9)

Illustrative assets/devices, quorum per hour, Cold 24/7 rule. Example outcomes: IAQ/Odor within% 88–92%; Cold within% 99.2%. Completeness cap: A3 Temp device=75% → Temp capped at Silver(⚠); Facility level Gold.

11.2 Office (Two floors; no Cold/Water)

IAQ within% averages to ~86%; completeness ≥ 90%. Level = Gold.

11.3 Tie Case (2 sensors per asset)

[1,1] → within; [1,0] → within (tie); [0,0] → out. Single reporting within=1 → within; within=0 → out.

12) Non‑Functional Requirements (SLOs)

  • Ingestion latency p95 ≤ 10 minutes; roll‑up job p95 < 5 minutes/facility/hour.
  • Device‑offline alert: IAQ/Odor > 2h without buckets; CO₂ > 30m.
  • Certificate close within 30 minutes after month end.
  • Storage budget: only Device×Bucket for current month + purge buffer; MonthlyRollup forever.

13) API Stubs (Shapes)

// Admin Policy (per facility)
{
  "allowTenantShiftEdit": true,
  "caps": {
    "dailyMaxNonActiveHours": 8,
    "scope": ["asset","facility"],
    "exemptParameters": ["Cold","Water"]
  }
}

// Bucket Upsert (internal)
{
  "facilityId":"F1","assetId":"A1","deviceId":"D1",
  "param":"TEMP","bucketStartUtc":"2025-08-22T10:00:00Z",
  "valueLast":24.3,"within":1
}

// Monthly Rollup (denormalized)
{
  "scope":"asset","scopeId":"A1","param":"TEMP","month":"2025-08-01",
  "expected":216,"actual":210,"withinCount":194,
  "completenessPct":97.2,"withinPct":89.8,
  "flags":{"gate":"gold"}
}

14) UX Copy & Errors (EN/AR)

  • EN: “You can set up to {hours}h of Non‑Active per day. Cold/Water are always Active.”
    AR: “يمكنك ضبط ما يصل إلى {hours} ساعة غير نشطة يوميًا. معايير البرودة/المياه فعّالة دائمًا.”
  • EN: “Change saved. Applies to new buckets only.”
    AR: “تم حفظ التغيير. سيتم تطبيقه على الدُفعات الجديدة فقط.”
  • EN: “Blocked: proposed Non‑Active exceeds the daily cap of {hours}h.”
    AR: “مرفوض: الإعداد المقترح لغير النشط يتجاوز الحد اليومي وهو {hours} ساعة.”
  • EN: “New devices are enrolled for next month’s scoring.”
    AR: “سيتم إدراج الأجهزة الجديدة في تقييم الشهر القادم.”

15) Edge Cases & Rules

  • New device mid‑month → excluded from current month; starts next month’s cohort.
  • Device removal/replacement → replacement starts next month (no mid‑month swap).
  • Template change → prospective from effective_from; historical unchanged.
  • Shift edit (tenant) → prospective only; must respect daily cap; Cold/Water exempt.
  • Late data → accepted while month open; purge after month close +7 days.
  • DST/TZ changes → evaluate bands using facility local time; handle 23/25h days.
  • Quorum tie → ≥ 50% within counts as within.
  • Incomplete devices but quorum OK → family may still be capped at Silver(⚠).
  • VapeIndex unavailable → fallback rule (TVOC+PM1.0) applies.
  • Cold/Water violations → facility ineligible if Within% < 99% for these families.

16) Acceptance Criteria

  • New device Aug 10 → not included in Aug; appears in Sep.
  • Template effective Aug 12 → buckets from Aug 12 00:00 local use new band; earlier unchanged.
  • Asset with 2 Temp sensors, one within & one out → asset within (≥ 50% rule).
  • Any device in Temp family has completeness 75% → Temp capped at Silver(⚠).
  • Vape events on 4 days in 30‑day window → 13.3% → Fail the <10% bar.
  • Tenant proposes 10h/day Non‑Active with cap 8h → Blocked with explanatory error.

17) Analytics (Events)

ingest.bucket_upsert { facility, asset, device, param, bucketStartUtc, within }
scoring.rollup_update { scope, param, expected, actual, within_count }
policy.shift_edit_attempt { tenant, before, after, allowed, violation }
policy.shift_edit_blocked { capType:"dailyMaxNonActiveHours", capValue:8, proposedValue:… }
cert.trending_computed { level }
cert.month_close_published { month, level, reasons }
alert.device_offline { device, last_seen }
alert.cold_water_breach { asset, bucket }