avg_CO2 output is always zero while max_CO2 is correct (GhPython, Ladybug 1.9.21, external chart window)

Hello,

I am trying to visualize how indoor CO₂ concentration changes according to window opening ratio.

I divided the window opening ratio into 10 discrete steps (from 0 to 10) and I want to plot:

  • indoor CO₂ behavior
  • ventilation rate effects

as separate graphs in external OS windows (not embedded in the Grasshopper UI).


this is a PY3 Code

1) Safety guards

dt_min = 1.0 if (dt_min is None or dt_min <= 0) else float(dt_min)
sim_hours = 1.0 if (sim_hours is None or sim_hours <= 0) else float(sim_hours)

steps = int(sim_hours * 60.0 / dt_min)
if steps < 1:
steps = 1
dt_h = dt_min / 60.0

2) Initialize lists (must always be length 12)

avg_CO2, max_CO2, ach_out, label_out = , , ,

3) Safe casting for inputs

def f_or(x, default):
try:
v = float(x)
return v if v > 0 else default
except:
return default

_v = f_or(v, 1.0)
_n = f_or(n_occ, 1.0)
_G = f_or(G_pp, 1.0)
_Cout = f_or(Cout, 420.0)
_C0 = f_or(C0, 420.0)

4) Flatten ach_list (DataTree compatible)

try:
from ghpythonlib import treehelpers
ach_flat = treehelpers.tree_to_list(ach_list, retrieve_base=True)
except:
ach_flat = ach_list

If it is a nested list, flatten it

if isinstance(ach_flat, list) and len(ach_flat) > 0 and isinstance(ach_flat[0], list):
ach_flat = [x for sub in ach_flat for x in sub]

If ach_flat is None or invalid, replace with empty list

if ach_flat is None:
ach_flat =

5) Simulation loop (always fill exactly 12 slots)

for i in range(12):

# Default values (keep 12 entries even if data is missing)
ach_val = 0.0
avg_val = 0.0
max_val = 0.0
label   = "No Data"

try:
    if i < len(ach_flat) and ach_flat[i] is not None:
        ach_val = float(ach_flat[i])
        C = _C0

        s = 0.0
        max_val = C

        for _ in range(steps):
            dCdt = (_G * _n / _v) + ach_val * (_Cout - C)
            C = C + dCdt * dt_h
            s += C
            if C > max_val:
                max_val = C

        avg_val = s / float(steps)
        label = "ACH = {:.2f}".format(ach_val)

except:
    # Keep default values on error
    pass

# Always append all 4 outputs (fixed length = 12)
avg_CO2.append(float(avg_val))
max_CO2.append(float(max_val))
ach_out.append(float(ach_val))
label_out.append(str(label))

End here. Do NOT use list_to_tree / ensure_list.

1 Like