OverviewFilesCommitsIssuesDocsReleasesPeers

electrical-review / design / racking-data.js

180 lines · javascript ref:
/* ============================================================================
   PRSM SOLAR — RACKING / STRUCTURAL WORKSTREAM DATA
   Source: SOLAR_RACKING_HANDOFF (Drive) — mechanical/structural handoff.
   Base design: Vandewetering, Hayibo & Pearce, Designs 2022, 6, 41
   (CERN-OHL-S, DOI 10.3390/designs6030041 · drawings osf.io/yx8mq).
   ----------------------------------------------------------------------------
   Structural numbers = strong engineering ESTIMATE confirming member sizing,
   NOT a stamped calc. VT engineer review before pour (quick check).
   Per-unit $ are SEED ESTIMATES — user overrides them in the calculator.
   ========================================================================== */
window.PRSM_RACK = (function () {

  const meta = {
    title: "Ground-Mount Racking",
    subtitle: "Mechanical / Structural Handoff",
    scope: "Phase 1 · 14 panels · landscape 2-high × 7-wide · ~8 post-pairs / 7 bays",
    basis: "Open-source wood-rack design (Vandewetering/Hayibo/Pearce 2022) verified for Greensboro Bend loads. One upsize from the published London design; the rest transfers.",
    band: { lo: 1400, hi: 2800 },
    status: "Design verified vs. published engineering · pending local sign-off + stockpile netting",
  };

  /* ---- headline structural facts -------------------------------------- */
  const structural = [
    { k: "Tilt", v: "~55°", n: "off-grid winter-priority · joists cut 55°", tone: "warn" },
    { k: "Snow (surface)", v: "1.0–1.3 kPa", n: "21–27 psf · 65 lb/ft² ground, shed by steep tilt · slope factor 0.11", tone: "pine" },
    { k: "Factored load", v: "1.8–2.2 kPa", n: "38–46 psf · 1.25D + 1.5S · ≈ London 1.80 kPa demand", tone: "pine" },
    { k: "Frost footing", v: "4–5 ft", n: "1.2–1.5 m · NEK frost depth · ~3 bags concrete/hole", tone: "pine" },
    { k: "Concrete", v: "30 MPa min", n: "≈ 4,350 psi · freeze–thaw rated (not 20 MPa)", tone: "pine" },
    { k: "The one upsize", v: "2×8 → 2×10", n: "inside joists · higher load + longer Waaree span", tone: "amber" },
  ];

  /* ---- member verification vs Table A7 (factored, No.1/2 SPF) ---------- */
  const members = [
    { m: "Inside joist", demand: "M = 1.10 kNm (2×8)", cap: "Mr 1.17", verdict: "Tight ~6% → UPSIZE 2×10 (Mr 1.90)", flag: "amber" },
    { m: "Beam (2×8)", demand: "M 0.50 · V 1.90 kN", cap: "Mr 1.17 / Vr 3.99", verdict: "OK ample", flag: "pine" },
    { m: "Back post (6×6)", demand: "M 0.90 · C 2.70 kN", cap: "Mr 2.49 / Cr 142.9", verdict: "OK large margin", flag: "pine" },
    { m: "Front post (4×4)", demand: "C 2.70 kN", cap: "Cr 57.8", verdict: "OK large margin", flag: "pine" },
    { m: "Outside joist (2×6)", demand: "M 0.55 kNm", cap: "Mr 0.67", verdict: "OK", flag: "pine" },
  ];

  /* ---- locked Greensboro adaptations ---------------------------------- */
  const adaptations = [
    "Tilt ~55° → all joists cut at 55° (not the paper's 34°).",
    "Inside joists upsized to 2×10.",
    "Frost footing 4 ft min, plan up to 5 ft; ~3 bags concrete/hole.",
    "Concrete 30 MPa minimum (freeze–thaw).",
    "Stainless or hot-dipped galvanized hardware ONLY — no plain zinc. WEEB washers at panel interface.",
    "Hand-treat every field cut & drilled hole with 2% copper naphthenate.",
    "Buried posts UC4A below-ground rated; upper members ground-contact rated.",
    "Keep bottom panel edge above max snow depth + slide-off pile.",
  ];

  /* ---- BOM line items (calculator rows) -------------------------------
     need    : planning quantity
     unit    : each | bag | lb | qt | set
     price   : SEED per-unit estimate (USD) — user overrides
     netting : true → STOCKPILE can offset
     ------------------------------------------------------------------- */
  const bom = [
    { id: "backpost",  member: "Back posts",          spec: "6×6, below-ground (UC4A), ~3 m, MCA", need: 8,  unit: "each", price: 52,   netting: true,  note: "" },
    { id: "frontpost", member: "Front posts",         spec: "4×4, below-ground (UC4A), MCA",        need: 8,  unit: "each", price: 22,   netting: true,  note: "" },
    { id: "beam",      member: "Beams",               spec: "2×8, MCA",                             need: 16, unit: "each", price: 16,   netting: true,  note: "~16" },
    { id: "injoist",   member: "Inside joists",       spec: "2×10, MCA · cut 55°",                  need: 14, unit: "each", price: 25,   netting: true,  note: "the upsize" },
    { id: "outjoist",  member: "Outside joists",      spec: "2×6, MCA · cut 55°",                   need: 2,  unit: "each", price: 14,   netting: true,  note: "" },
    { id: "brace",     member: "Lateral bracing",     spec: "2×4, MCA",                             need: 20, unit: "each", price: 8,    netting: true,  note: "~20" },
    { id: "block",     member: "Module-attach blocks",spec: "scrap/offcut MCA lumber",             need: 56, unit: "each", price: 0.5,  netting: true,  note: "likely all from stockpile" },
    { id: "concrete",  member: "Footing concrete",    spec: "30 MPa min · ~3 bags/hole · 16 holes", need: 48, unit: "bag",  price: 7,    netting: true, note: "" },
    { id: "bpbolt",    member: "Beam-post bolts",     spec: '½" carriage (6\u2033 & 8\u2033) · SS/HDG + nut+washer', need: 32, unit: "set", price: 4, netting: true, note: "~32" },
    { id: "modbolt",   member: "Module bolts",        spec: '¼" × 2½" stainless + WEEB washers',    need: 56, unit: "set",  price: 5,    netting: true, note: "WEEB = bond + isolation" },
    { id: "bracket",   member: "Fence brackets",      spec: "joist/brace connections · HDG",        need: 60, unit: "each", price: 2.5,  netting: true, note: "~60" },
    { id: "screw",     member: "Deck screws",         spec: '2½" exterior-rated',                   need: 3,  unit: "lb",   price: 8,    netting: true,  note: "2–3 lb" },
    { id: "nail",      member: "Joist hanger nails",  spec: '1½" HDG',                              need: 2,  unit: "lb",   price: 6,    netting: true, note: "1–2 lb" },
    { id: "naph",      member: "Copper naphthenate",  spec: "2% solution · field-cut treatment",    need: 1,  unit: "qt",   price: 22,   netting: true, note: "essential for 25-yr life" },
    { id: "stone",     member: "Clear stone",         spec: "150 mm at footing base (if marginal)", need: 0,  unit: "bag",  price: 6,    netting: true,  note: "as needed" },
  ];

  /* ---- electrical ↔ structural integration points --------------------- */
  const integration = [
    { t: "Grounding / bonding", d: "WEEB washers bond each module to rack — confirm this satisfies the NEC 690/250 plan (wood rack is non-conductive)." },
    { t: "Rapid shutdown (690.12)", d: "Detached-array exception may grant relief — electrical project to confirm if RSD required and site the device." },
    { t: "Conduit / trenching", d: "DC/AC run to house at NEC depth (18\u2033 / 24\u2033 RMC); coordinate stub-up vs. rear posts & array low end." },
    { t: "Equipment mounting", d: "Combiner/disconnect/RSD enclosures rack-mounted vs. house-mounted — affects post selection & bracing." },
    { t: "Wire management", d: "Clips along joists/beams; off the ground; allow thermal expansion + snow slide." },
    { t: "Inverter/charger location", d: "Islanded DC-bus charger drives array-to-equipment conductor sizing (690.8 / 710.15)." },
    { t: "NFPA 855 signage", d: "Exterior ESS signage + location designator (VT amendment) — electrical scope." },
    { t: "String vs. physical layout", d: "14-panel series-parallel config must fit the 2-high × 7-wide bay geometry." },
  ];

  /* ---- consolidated open actions -------------------------------------- */
  const actions = [
    { id: "A1", t: "Confirm architecture: islanded/off-grid vs grid-interactive.", who: "Electrical", done: true, resolved: "off-grid committed — Grade-B panels valid." },
    { id: "A2", t: "Pull Waaree mounting-hole spacing from datasheet → enables cut list.", who: "Owner", done: false },
    { id: "A3", t: "Walk lumber stockpile; fill STOCKPILE (exterior/PT only).", who: "Owner", done: false, resolved: "→ use the calculator below" },
    { id: "A4", t: "Get local VT MCA-treated SPF lumber quote.", who: "Owner", done: false, resolved: "→ override unit prices below" },
    { id: "A5", t: "Confirm soil vs. ledge at posts; if ledge, pivot to ballasted foundation.", who: "Owner", done: false },
    { id: "A6", t: "Confirm Greensboro ground snow + frost depth with VT AHJ.", who: "Owner", done: false },
    { id: "A7", t: "VT engineer review of completed analysis before pour.", who: "Owner", done: false },
    { id: "A8", t: "Reconcile all §7 electrical-integration points.", who: "Electrical", done: false },
  ];

  /* ---- PHASE-1 RACKING OPTIONS (comparison) --------------------------
     Energy = script-computed (15_tilt_sweep.py). Structure/cost = inherited
     estimate, not stamped — engineer review before pour. All options:
     Phase-1, 14 × Waaree 575 W bifacial (8.05 kW), 2-high × 7-wide, off-grid NEK.
     Options 2 and 3 yield the SAME annual energy — they differ in mechanism,
     cost & handling, not kWh. Option 3 is owner-favored but presented as a peer.
     ------------------------------------------------------------------- */
  const options = [
    {
      id: "fixed55", n: "1", name: "Fixed 55°", tag: "baseline build", owner: false, diagram: "fixed",
      tiltMode: "Fixed 55° · winter-weighted + snow-shed",
      energy: "10,446 kWh/yr", energyNote: "Phase-1 · BOM bifacial 0.80", delta: "baseline", deltaTone: "plain",
      summary: "The committed build — a rigid wood A-frame holding the array at a fixed 55°, steep for winter sun and snow-shed. No moving parts, nothing to maintain.",
      specs: [
        ["Tilt", "Fixed 55°"],
        ["Annual energy", "10,446 kWh/yr"],
        ["Δ vs fixed-55", "— (baseline)"],
        ["Posts", "6×6 back / 4×4 front"],
        ["Joists / beams", "2×10 / 2×8 · 4–5 ft frost footings"],
        ["Hardware", "MCA lumber · SS/HDG + WEEB"],
      ],
      pros: ["Simplest & cheapest", "Zero maintenance", "Sheds snow cleanly", "No moving-array hazards"],
      cons: ["No seasonal optimization", "Leaves ~5.5% gross energy unclaimed"],
      adjust: "None — set once", moving: "None · none", complexity: "Lowest", cost: "$ · lowest",
      safety: "No moving-array hazard.",
      provEnergy: "computed · 15_tilt_sweep.py", provStruct: "inherited · not stamped",
    },
    {
      id: "seasonal", n: "2", name: "Seasonal adjustable", tag: "drilled-preset wood", owner: false, diagram: "seasonal",
      tiltMode: "4 presets 55/45/35/30° · ~4×/yr",
      energy: "11,023 kWh/yr", energyNote: "4-position · +577 (+5.5%) gross", delta: "+577 kWh · +5.5%", deltaTone: "pine",
      summary: "T-hinge pivot at the low edge with a drilled rear brace — flip between four preset angles (55/45/35/30°) about four times a year. Open-source design (Pearce, Designs 2022, CERN-OHL-S).",
      specs: [
        ["Tilt", "Presets 55 / 45 / 35 / 30°"],
        ["Annual energy", "11,023 kWh/yr"],
        ["Δ vs fixed-55", "+577 kWh (+5.5%) gross"],
        ["Useful seasonal gain", "~+135 kWh (+2.5%) on the shoulders"],
        ["Built as", "3–4 tiltable 4-panel bays (~260 lb ea)"],
        ["2 → 4 presets", "adds only ~8 kWh/yr"],
      ],
      pros: ["Captures the (modest) seasonal gain", "Open-source plans (~$133/panel)", "Still all-wood, low-tech"],
      cons: ["Manual re-tilt ~4×/yr", "Gain is small after bifacial", "More joints to build & maintain"],
      adjust: "Manual · ~4×/yr", moving: "T-hinge + drilled brace · low", complexity: "Moderate", cost: "$$ · ~$133/panel",
      safety: "Re-tilt only when pinned into a preset hole.",
      provEnergy: "computed · 15_tilt_sweep.py", provStruct: "inherited · not stamped",
    },
    {
      id: "pivot", n: "3", name: "Single-pivot tilt", tag: "owner-favored", owner: true, diagram: "pivot",
      tiltMode: "Whole plane on a through-bolt pivot · manual monthly",
      energy: "11,023 kWh/yr", energyNote: "≈ Option 2 · monthly ≈ 4-position", delta: "+577 kWh · +5.5%", deltaTone: "pine",
      summary: "A whole-plane “tilting table” rotating on one through-bolt pivot, hand-tilted monthly. From a DIY YouTube build — but it must be up-sized and wind-locked for 575 W panels in Vermont. The video’s “+500–1000 W” is instantaneous power, not annual energy.",
      specs: [
        ["Tilt", "Continuous · set monthly"],
        ["Annual energy", "11,023 kWh/yr"],
        ["Δ vs fixed-55", "+577 kWh (+5.5%) gross"],
        ["Useful seasonal gain", "~+135 kWh (+2.5%)"],
        ["4 → monthly", "adds ≈ 0 kWh/yr"],
        ["Mandatory up-size", "2×10 rails · 6×6 posts · 4–5 ft footings"],
      ],
      pros: ["Owner-favored", "Low-cost wood", "Easy hand-tilt when balanced"],
      cons: ["Moving-array wind & pivot-wear risk", "Locking undocumented in source video", "Needs engineer review", "Bonding jumper + service loops across pivot"],
      adjust: "Manual · monthly", moving: "1 pivot · higher (wind, wear)", complexity: "Highest", cost: "$$ · ~$360 (light build)",
      safety: "Positive wind-lock MANDATORY — the ~390 ft² plane is a sail.",
      provEnergy: "computed · 15_tilt_sweep.py", provStruct: "inherited + adapted · not stamped",
    },
  ];

  const optionCompare = {
    cols: ["Option", "Tilt mode", "Annual kWh", "Δ vs fixed-55", "Adjust freq", "Moving parts / maint.", "Complexity", "Cost", "Key safety note", "Provenance"],
    rows: [
      { n: "1", cells: ["Fixed 55°", "Fixed", "10,446", "— baseline", "Never", "None / none", "Lowest", "$", "No moving-array hazard", "kWh computed · structure inherited"] },
      { n: "2", cells: ["Seasonal adjustable", "4 presets 55/45/35/30°", "11,023", "+577 (+5.5%)", "~4×/yr", "T-hinge + brace / low", "Moderate", "$$", "Re-tilt only when pinned", "kWh computed · structure inherited"] },
      { n: "3", cells: ["Single-pivot tilt", "Continuous", "11,023", "+577 (+5.5%)", "Monthly", "1 pivot / higher", "Highest", "$$", "Positive wind-lock mandatory", "kWh computed · structure inherited+adapted"] },
    ],
    foot: "Options 2 and 3 produce the SAME annual energy — they differ in mechanism, cost & handling, not kWh. Only fixed → adjustable changes output (+5.5% gross / ~+2.5% useful after bifacial + off-grid summer curtailment).",
  };

  return { meta, structural, members, adaptations, bom, integration, actions, options, optionCompare };
})();