コード例 #1
0
def plot_zone_constructions(con_file, geo_file, ax=None):
    """Plot all zone constructions."""
    zone_geometry = get.geometry(geo_file)
    con = get.constructions(con_file, geo_file)
    layer_therm_props = con["layer_therm_props"]

    for i, _ in enumerate(zone_geometry["edges"]):
        con_data = layer_therm_props[i]
        surface = zone_geometry["edges"][i]
        # map vertex indices in edges list to x,y,z vertices
        vertices_surf_i = []
        for vertex in surface:
            vertices_surf_i.append(zone_geometry["vertices"][vertex - 1])
        plot_construction(con_data, vertices_surf_i, ax=ax)
コード例 #2
0
def plot_zone(geo_file, ax=None, show_roof=True):
    """Plot zone from surfaces

    Example:

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.set_aspect('equal')
    plot.plot_zone(geo_file, ax=ax)
    plot.set_axes_equal(ax)
    plt.show()

    """
    geo = get.geometry(geo_file)
    vertices = geo["vertices"]
    edges = geo["edges"]

    for i, surface in enumerate(edges):
        # Translate vertex no. to vertex x,y,z pos.
        vs = []
        for vertex in surface:
            vs.append(vertices[vertex - 1])
        # Plot surface from vertex coordinates)
        if (
            geo["props"][i][1] == "CEIL" or geo["props"][i][1] == "SLOP"
        ) and not show_roof:
            print("not showing roof")
        else:
            if geo["props"][i][6] == "OPAQUE" and geo["props"][i][7] == "EXTERIOR":
                if "DOOR" in geo["props"][i][3] or "FRAME" in geo["props"][i][3]:
                    plot_zone_surface(vs, ax=ax, facecolour="#c19a6b", alpha=None)
                else:
                    # default grey surface
                    plot_zone_surface(vs, ax=ax, facecolour="#afacac", alpha=None)
            elif geo["props"][i][6] == "OPAQUE" and geo["props"][i][7] == "ANOTHER":
                if "DOOR" in geo["props"][i][3]:
                    # door
                    plot_zone_surface(vs, ax=ax, facecolour="#f5f2d0", alpha=None)
                else:
                    # default 25% lighter surface
                    plot_zone_surface(vs, ax=ax, facecolour="#ffffff", alpha=None)
            elif geo["props"][i][6] == "OPAQUE" and geo["props"][i][7] == "SIMILAR":
                # opaque, similar
                plot_zone_surface(vs, ax=ax, facecolour="#d8e4bc", alpha=None)
            elif geo["props"][i][6] == "OPAQUE" and geo["props"][i][7] == "GROUND":
                plot_zone_surface(vs, ax=ax, facecolour="#654321", alpha=None)
            else:
                # Transparent surfaces
                plot_zone_surface(vs, ax=ax, facecolour="#008db0")
コード例 #3
0
ファイル: convert.py プロジェクト: johnallison0/espy
def zone_to_predef_entity(geo_file, name, desc, category):
    """Convert a zone geometry file to a predefined entity entry.

    Args:
        geo_file: ESP-r geometry file.

    Returns:
        A text file that can be copied into an ESP-r predefined entities
        database.
    """
    # TODO(j.allison): Process visual entities
    # TODO(j.allison): Shift x,y,z to (0,0,0) origin

    geo = get.geometry(geo_file)
    all_vertices = geo["vertices"]
    props = geo["props"]
    surfaces = geo["edges"]
    vx = [v[0] for v in all_vertices]
    vy = [v[1] for v in all_vertices]
    vz = [v[2] for v in all_vertices]
    size = (max(vx) - min(vx), max(vy) - min(vy), max(vz) - min(vz))

    out_file = f"{name}.txt"
    with open(out_file, "w+") as the_file:
        the_file.write(f"*item,{name},{desc} # tag name menu entry\n")
        the_file.write(f"*incat,{category}           \n")
        the_file.write("*sourced,Custom built.\n")
        the_file.write("*origin,0.0,0.0,0.0  # local origin\n")
        the_file.write(
            f"*bounding_box,  {size[0]:.3f}  {size[1]:.3f}  {size[2]:.3f}  # extents of object\n"
        )
        the_file.write("*Text\n")
        the_file.write(f"{desc}\n")
        the_file.write("*End_text\n")
        the_file.write("#\n")
        for i, vertex in enumerate(all_vertices):
            the_file.write(
                f"*vertex,{vertex[0]:.5f},{vertex[1]:.5f},{vertex[2]:.5f}  #   {i + 1}\n"
            )
        the_file.write("#\n")
        for i, (s, p) in enumerate(zip(surfaces, props)):
            the_file.write(f"*mass,{p[0]},{p[5]},OPAQUE,{len(s)}," +
                           "  ".join(map(str, s)) + f"  #   {i + 1}\n")
        the_file.write("#\n")
        # the_file.write(f"*vobject,{name},{desc},{len(self.vis)},{','.join([v[8] for v in self.vis])}")
        the_file.write("*end_item")
コード例 #4
0
def plot_building_component(geo_file, con_file, idx_surface, ax=None, show_roof=True):
    """Plot generic 3D building component.

    This function plots a 3D building component (wall, floor, roof etc.)
    from its surface geometry and construction data.

    The inside surface is plotted as white, while the external surface colour
    is dependent on the surface properties from the geometry file.

    vertices    list of x,y,z position vertices of the inside (zone-facing) surface
    """

    # TODO(j.allison): Create new figure and axes if none are provided

    # Read geometry file
    zone_geometry = get.geometry(geo_file)
    surface_props = zone_geometry["props"][idx_surface]

    # Get vertex numbers that comprise surface
    surface_edges = zone_geometry["edges"][idx_surface]

    # Get vertex positions that comprise surface
    vertices_surf = get.pos_from_vert_num_list(zone_geometry["vertices"], surface_edges)

    # Plot inside (zone-facing) surface
    if (surface_props[1] == "CEIL" or surface_props[1] == "SLOP") and not show_roof:
        pass
    else:
        if surface_props[6] == "OPAQUE":
            plot_zone_surface(vertices_surf, ax=ax, facecolour="w", alpha=None)
        else:
            plot_zone_surface(vertices_surf, ax=ax, facecolour="#008db0")

    # Plot construction layers
    con = get.constructions(con_file, geo_file)
    layer_therm_props = con["layer_therm_props"]
    con_data = layer_therm_props[idx_surface]
    if (surface_props[1] == "CEIL" or surface_props[1] == "SLOP") and not show_roof:
        pass
    else:
        plot_construction(con_data, vertices_surf, ax=ax)

    # -------------------------------------
    # Plot outer surface
    # -------------------------------------
    normal = get.calculate_normal(vertices_surf)
    # vertices_surf += [vertices_surf[0]]
    total_thickness = sum([x[3] for x in con_data])
    # Extend vertex position along surface normal by the total thickness
    x_pos = [v[0] + total_thickness * normal[0] for v in vertices_surf]
    y_pos = [v[1] + total_thickness * normal[1] for v in vertices_surf]
    z_pos = [v[2] + total_thickness * normal[2] for v in vertices_surf]
    # Restructure to surface vertices
    # Can probably do this in a zip list comprehension...
    vertices_surf_outer = []
    for i, _ in enumerate(vertices_surf):
        vertices_surf_outer.append([x_pos[i], y_pos[i], z_pos[i]])
    if (surface_props[1] == "CEIL" or surface_props[1] == "SLOP") and not show_roof:
        pass
    else:
        if surface_props[6] == "OPAQUE" and surface_props[7] == "EXTERIOR":
            if "DOOR" in surface_props[3] or "FRAME" in surface_props[3]:
                # door or frame
                plot_zone_surface(
                    vertices_surf_outer, ax=ax, facecolour="#c19a6b", alpha=None
                )
            else:
                # default grey surface
                plot_zone_surface(
                    vertices_surf_outer, ax=ax, facecolour="#afacac", alpha=None
                )
        elif surface_props[6] == "OPAQUE" and surface_props[7] == "ANOTHER":
            if "DOOR" in surface_props[3]:
                # door
                plot_zone_surface(
                    vertices_surf_outer, ax=ax, facecolour="#f5f2d0", alpha=None
                )
            else:
                # default 25% lighter surface
                plot_zone_surface(
                    vertices_surf_outer, ax=ax, facecolour="#ffffff", alpha=None
                )
        elif surface_props[6] == "OPAQUE" and surface_props[7] == "SIMILAR":
            plot_zone_surface(
                vertices_surf_outer, ax=ax, facecolour="#d8e4bc", alpha=None
            )
        elif surface_props[6] == "OPAQUE" and surface_props[7] == "GROUND":
            plot_zone_surface(
                vertices_surf_outer, ax=ax, facecolour="#654321", alpha=None
            )
        else:
            # Transparent surfaces
            plot_zone_surface(vertices_surf_outer, ax=ax, facecolour="#008db0")
コード例 #5
0
ファイル: res.py プロジェクト: johnallison0/espy
def time_series(cfg_file, res_file, param_list, out_file=None, time_fmt=None):
    """Extract results from results database to CSV.

    Args:
        cfg_file: ESP-r configuration file.
        res_file: ESP-r results database.
        param_list: List of parameters to extract.
            Examples -
            param_list = [['all', 'Zone db T']]
            param_list = [['id:reception', 'Zone db T']]
            param_list = [[['id:roof_space', 'id:reception'], 'Zone db T']]
            param_list = [[['a', 'b'], 'Zone db T'], [['id:reception', 'b'], 'Wind direction']]
        out_file (optional): Name of exported CSV file.
        time_fmt: Format of DateTime in exported CSV. Julian or DateTime

    Returns:
        res: Console feedback from res.
    """
    res_dict = {
        # Climate
        "Ambient temperature": ["a", "a"],
        "Solar Dir N": ["a", "b"],
        "Solar diffuse": ["a", "c"],
        "Wind speed": ["a", "d"],
        "Wind direction": ["a", "e"],
        "Ambient RH": ["a", "f"],
        "Sky illuminance": ["a", "g"],
        # Temperatures
        "Zone db T": ["b", "a", "-"],
        "Zone db T - ambient db T": ["b", "b", "-"],
        "Zone db T - other zone db T": ["b", "c", "-"],
        "Zone control point T": ["b", "d", "-"],
        "Zone Resultant T": ["b", "e", "-"],
        "Mean Radiant T (area wtd)": ["b", "f", "-"],
        "Mean Radiant T (at sensor)": ["b", "g", "-"],
        "Dew point T": ["b", "h", "-"],
        "Surf inside face T": ["b", "i", "-"],
        "Surf T - dewpoint T": ["b", "j", "-"],
        "Surf outside face T": ["b", "k", "-"],
        "Surf node T": ["b", "l", "-"],
        # Comfort metrics
        # <TBC> requires extra inputs from user
        # 'Predicted Mean Vote (PMV)': ['c', 'a'],
        # 'PMV using SET': ['c', 'b'],
        # 'Percentage Dissatisfied (PPD)': ['c', 'c'],
        # 'Local delta T head-foot': ['c', 'd'],
        # 'Dissatisfied due to floor T': ['c', 'e'],
        # 'Diss. warm/ cool ceiling': ['c', 'f'],
        # 'Diss. wall rad T assymetry': ['c', 'g'],
        # 'Dissatisfied due to draught': ['c', 'h'],
        # Solar processes
        "Solar entering from outside": ["d", "a"],
        "Solar entering from adj": ["d", "b"],
        "Solar absorbed in zone": ["d", "c"],
        # Zone flux
        "Infiltration (from outside)": ["f", "a"],
        "Ventilation (adj zones)": ["f", "b"],
        "Occupant casual gains (R+C)": ["f", "c"],
        "Lighting casual gains (R+C)": ["f", "d"],
        "Small power casual gains (R+C)": ["f", "e"],
        "Other casual gains (R+C)": ["f", "f"],
        "Controlled casual gains (R+C": ["f", "g"],
        "Opaq surf conv @extrn": ["f", "h"],
        "Opaq surf conv @partns": ["f", "i"],
        "Tran surf conv @extrn": ["f", "j"],
        "Tran surf conv @partns": ["f", "k"],
        "Total surface conv": ["f", "l"],
        # Surface flux
        "conduction (inside)": ["g", "a", "-", "N"],
        "convection (inside)": ["g", "b", "-", "N"],
        # Heat/cool/humidify
        "Sensible heating load": ["h", "a"],
        "Sensible cooling load": ["h", "b"],
        "Dehumidification load": ["h", "c"],
        "Humidification load": ["h", "d"],
        "Sensible H+C loads": ["h", "e"],
        "Latent H+C loads": ["h", "f"],
        "All Sensible + latent load": ["h", "g"],
        "Aggregate heating load": ["h", "h"],
        "Aggregate cooling load": ["h", "i"],
        "Aggregate dehumidification": ["h", "j"],
        "Aggregate humidification": ["h", "k"],
        # Zone RH
        "Zone RH": ["i"],
        # Casual gains (more to complete)
        "occupant convective": ["j", "f", "-"],
        "lighting convective": ["j", "j", "-"],
        "equipment convective": ["j", "n", "-"],
    }

    # Read cfg file for list of zones
    cfg = get.config(cfg_file)
    zones = cfg["zones"]

    # Loop through each zone file and get zone name
    zone_names = []
    for ind, _ in enumerate(zones):
        file_path = zones[ind][1]["geo"]
        zone_names.append(get.geometry(file_path)["name"])

    # TODO(j.allison): Check/validate time_fmt
    res_open = ["", "c"]
    time_dict = {"Julian": ["*", "a"], "DateTime": ["*", "a", "*", "a"]}
    if time_fmt is not None:
        csv_open = [">", "temp.csv", "desc"] + time_dict[time_fmt] + ["&", "^", "e"]
    else:
        csv_open = [">", "temp.csv", "desc"] + ["&", "^", "e"]
    perf_met = ["g"]

    res_select = []
    for item in param_list:
        zone_select = []
        zone_input = item[0]
        metric_input = item[1]
        # ---------------------------------
        # Select all zones
        # ---------------------------------
        if zone_input == "all":
            # res_select.append(["4", "*", "-"])
            res_select.append(["4", "*"])
        # ---------------------------------
        # Multiple zone selections
        # ---------------------------------
        elif isinstance(zone_input, list) and len(zone_input) > 1:
            for j in zone_input:
                # Selection by id:
                if j[:3] == "id:":
                    selected_zone = j[3:]
                    chr_zone = [
                        chr(96 + ind + 1)
                        for ind, x in enumerate(zone_names)
                        if x == selected_zone
                    ]
                    # If exists select it, otherwise throw error
                    if chr_zone:
                        zone_select.append(chr_zone[0])
                    else:
                        print(
                            "zone selection error, '{}' not found".format(selected_zone)
                        )
                # Assume direct letter selection of zones if len = 1
                elif len(j) == 1:
                    zone_select.append(j[0])
                else:
                    print("zone selection error for '{}', check input format".format(j))
            res_select.append(["4"] + zone_select + ["-"])
        # ---------------------------------
        # Single selection
        # ---------------------------------
        # From zone name
        elif zone_input[:3] == "id:":
            selected_zone = zone_input[3:]
            chr_zone = [
                chr(96 + ind + 1)
                for ind, x in enumerate(zone_names)
                if x == selected_zone
            ]
            # If exists select it, otherwise throw error
            if chr_zone:
                zone_select.append(chr_zone[0])
                res_select.append(["4"] + zone_select + ["-"])
            else:
                print("zone selection error, '{}' not found".format(selected_zone))
        # Assume single letter selection
        elif len(zone_input) == 1:
            zone_select.append(zone_input[0])
            res_select.append(["4"] + zone_select + ["-"])
        else:
            print(
                "zone selection error for '{}', check input format".format(zone_input)
            )
        # Select metric
        # If error in single selection, gets all zones (for now)
        res_select.append(res_dict[metric_input])
        # Surface flux
        if res_dict[metric_input][0] == "g":
            surface_input = item[2]
            res_select.append(surface_input + ["-"])

    # Flatten list
    res_select = list(itertools.chain.from_iterable(res_select))

    csv_close = ["!", ">"]
    res_close = ["-", "-", "-", "-"]

    cmd = res_open + csv_open + perf_met + res_select + csv_close + res_close
    cmd = "\n".join(cmd)
    # print(cmd)
    res = run(
        ["res", "-file", res_file, "-mode", "script"],
        input=cmd,
        stdout=PIPE,
        stderr=PIPE,
        encoding="ascii",
    )

    header_lines = 4
    if out_file:
        with open("temp.csv", "r") as infile, open(
            out_file, "w", newline=""
        ) as outfile:
            reader = csv.reader(infile)
            writer = csv.writer(outfile)
            line_count = 1
            for row in reader:
                if line_count < header_lines:
                    pass
                elif line_count == header_lines:
                    newrow = ["Time"] + row[1:]
                    writer.writerow(newrow)
                else:
                    newrow = row
                    writer.writerow(newrow)
                line_count += 1

    data_frame = pandas.read_csv(
        "temp.csv", sep=",", header=3, index_col=0, parse_dates=True
    )
    os.remove("temp.csv")

    return data_frame