Data centres: multi-storey shell, racks and pods, cooling, fire safety, power
Deploy web Studio / deploy (push) Successful in 1m4s

datacentre.rhai (palette groups Data centre, Cooling, Fire safety, Power):

- dc_building: multi-storey shell (storeys of storey_h), walls in pieces,
  slabs, roof with parapet, louvres, front door and loading dock; levels
  cut it open storey by storey
- raised_floor; rack_row and dc_pod (cabinets by U, width, depth,
  equipment, fill, doors, LEDs; in-row coolers; cold / hot aisle
  containment with vent tiles, roof, end doors, ceiling duct, airflow);
  dc_cage for colocation
- crah, chiller (air-cooled, dry, adiabatic), cooling_tower, pipe_run
- smoke_detectors (grid + coverage), fire_pipe (VESDA, sprinkler, gas),
  gas_bank (Novec 1230, FM-200, Inergen sized for its halls), fire_device
  (panels, call points, abort switches, beacons, extinguishers)
- power_cab (UPS, battery, PDU, switchgear, RPP), busway, cable_tray,
  transformer
- tooltips sum IT load, kW/m2, cooling redundancy per storey, UPS load,
  battery runtime, plant cooling and agent quantity (warning when short)

Engine and stdlib:

- part_hidden(o) in house.rhai: parts on closed storeys inside a
  dc_building are not drawn (they only made sort cycles under the slab
  above); house parts, furniture and people use it. Existing examples
  render byte-identical.
- overhead services sort in their own "ceiling" layer with tight boxes
- sort records which sprites each broken cycle involved; isokit check
  names them (Rendered.cycle_at)

examples/datacentre (three storeys and a roof plant), Data centre demo in
the web Studio, tests, SCRIPTING/README/ROADMAP, MCP instructions.
This commit is contained in:
grabowski committed 2026-10-27 17:08:39 +07:00
1 parent c8becc2e59
commit 2810477f1b
22 files changed
+2281 -18

No files matched your search

+28
View File
@@ -404,6 +404,34 @@ try:
check(len(g) == 1 and members == ["bush-1", "bush-2"] and hid == 0 and not any(o["type"] == "group" for o in doc(pg)["objects"]),
f"web Studio groups: {members} in {g[0]['id'] if g else None}, hidden with it, undone")
# ---------------------------------------------------------------- the data centre demo: storeys, racks, cooling, fire safety
pg.locator("#wb-projects").click()
pg.locator("#wb-ndc").click()
pg.wait_for_load_state()
ready(pg)
pg.wait_for_timeout(800)
nd = len(doc(pg)["objects"])
ids_in = lambda sel: pg.evaluate(f"() => [...new Set([...document.querySelectorAll(`{sel}`)].map(e => e.dataset.obj))]")
pods = [i for i in ids_in(".iso-svg [data-obj]") if i.startswith("1f-pod")]
overhead = ids_in(".iso-svg [data-layer='ceiling'] [data-obj]")
# it opens on 1F: 8 pods; trays, busways, VESDA and gas pipes, detectors sort in the ceiling layer
check(title(pg) == "isokit data centre" and nd == 179 and len(pods) == 8 and len(overhead) == 21
and pg.evaluate("() => __studio.S.warnings.length") == 0,
f"Data centre demo opens on 1F ({nd} objects, {len(pods)} pods, {len(overhead)} overhead runs, no warnings)")
irow = lambda id_, k: pg.evaluate(f"() => Object.fromEntries((__studio.view.info('{id_}') || {{rows: []}}).rows)['{k}'] || ''")
red, gas = irow("1f-crah-n1", "Redundancy"), irow("1f-gas", "Status")
check(red == "N+2, 348 kW spare" and gas == "enough, 3 % spare", f"1F cooling {red}; Novec bank {gas}")
shot(pg, "web-datacentre.jpg")
# GF cut open: the power room shows, the halls above are left out
pg.evaluate("__studio.view.setLevel('gf')")
pg.wait_for_timeout(1200)
gf = ids_in(".iso-svg [data-obj]")
run = irow("batt-1", "Runtime")
check("ups" in gf and not any(i.startswith("1f-") for i in gf) and run == "about 21.7 min at 3,584 kW IT",
f"GF shows the power room and none of 1F; batteries {run}")
pg.evaluate("__studio.view.setLevel('1f')")
pg.wait_for_timeout(600)
# ---------------------------------------------------------------- a system asking for less motion
# (Windows: Animation effects off): the view starts still, but the button stays and turns it on
rctx = b.new_context(viewport={"width": 1200, "height": 800}, reduced_motion="reduce")