Skip to main content

Metamodel for Energy Things (MetamEnTh) is an object-oriented metamodel designed to model the operational aspects of buildings. It focuses on the relationships and interactions between mechanical, electrical, and plumbing (MEP) entities and their connections to sensors and spatial entities such as rooms and open spaces within buildings.

Project description

Metamodel for Energy Things (MetamEnTh)

Build Status Version License PyPI version Wiki

MetamEnTh is an object-oriented framework for modeling the operational aspects of buildings, with a focus on mechanical, electrical, and plumbing (MEP) entities. It allows users to model and interact with physical structures, such as rooms, floors, HVAC systems, and appliances, providing a detailed simulation of building components and energy systems.

Read the documentation here: MetamEnTh Documentation

Table of Contents

  1. Setting up MetamEnTh Locally
  2. Example Usage

Setting up MetamEnTh Locally

Cloning the repository:

git clone https://github.com/ptidejteam/metamenth.git
cd metamenth

Creating a virtual environment

python3 -m venv venv

Activating the virtual environment

# Windows
venv\Scripts\activate

# MacOS/Linux
source venv/bin/activate

Installing dependencies

pip install -r requirements.txt

Running tests

chmod +x run_tests.sh
     ./run_tests.sh

Example usage

Model HVAC System Figure 1.0: The HVAC system in this figure is modelled below in the example usage code indicating how modellers could model complex HVAC systems with MetamEnTh

1. Creating the Building

from metamenth.misc import MeasureFactory
from metamenth.enumerations import RecordingType
from metamenth.datatypes.measure import Measure
from metamenth.enumerations import MeasurementUnit
from metamenth.structure.open_space import OpenSpace
from metamenth.enumerations import OpenSpaceType
from metamenth.enumerations import RoomType
from metamenth.structure.room import Room
from metamenth.structure.floor import Floor
from metamenth.enumerations import FloorType
from metamenth.structure.building import Building
from metamenth.enumerations import BuildingType
from metamenth.datatypes.address import Address

floor_area = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                           Measure(MeasurementUnit.SQUARE_METERS, 5))
# height of building
height = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                       Measure(MeasurementUnit.METERS, 30))
# internal mass of the building
internal_mass = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                              Measure(MeasurementUnit.KILOGRAMS, 2000))
area = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                     Measure(MeasurementUnit.SQUARE_METERS, 45))
# create room
room = Room(area, "Room", RoomType.OFFICE)

mechanical_room = Room(area, "Mechanical Room", RoomType.MECHANICAL)

# create a hall
hall = OpenSpace("Hall", area, OpenSpaceType.HALL)

# create a corridor
corridor = OpenSpace("Corridor", area, OpenSpaceType.CORRIDOR)

# create floor with a room and a hall
floor = Floor(area=area, number=1, floor_type=FloorType.REGULAR, rooms=[room, hall, corridor, mechanical_room])

# create the building's address
address = Address("Montreal", "6399 Rue Sherbrooke", "QC", "H1N 2Z3", "Canada")

# create building
building = Building(2009, height, floor_area, internal_mass, address,
                    BuildingType.COMMERCIAL, [floor])

2. Adding an envelope with roof

from metamenth.structure.layer import Layer
from metamenth.structure.material import Material
from metamenth.enumerations import MaterialType
from metamenth.enumerations import LayerRoughness
from metamenth.structure.cover import Cover
from metamenth.structure.envelope import Envelope
from metamenth.enumerations import CoverType
from metamenth.enumerations import RecordingType
from metamenth.datatypes.measure import Measure
from metamenth.enumerations import MeasurementUnit
from metamenth.misc import MeasureFactory

# material properties
density_measure = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                                Measure(MeasurementUnit.KILOGRAM_PER_CUBIC_METER, 0.5))
hc_measure = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                           Measure(MeasurementUnit.JOULES_PER_KELVIN, 4.5))
tt_measure = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                           Measure(MeasurementUnit.WATTS_PER_SQUARE_METER_KELVIN, 2.5))
tr_measure = MeasureFactory.create_measure(RecordingType.BINARY.value,
                                           Measure(MeasurementUnit.SQUARE_METERS_KELVIN_PER_WATTS,
                                                   2.3))

# create roof material
roof_material = Material(
   description="Steel roof",
   material_type=MaterialType.ROOF_STEEL,
   density=density_measure,
   heat_capacity=hc_measure,
   thermal_transmittance=tt_measure,
   thermal_resistance=tr_measure
)

# roof layer measurement
roof_height = MeasureFactory.create_measure(RecordingType.BINARY.value, Measure(MeasurementUnit.METERS, 20))
roof_length = MeasureFactory.create_measure(RecordingType.BINARY.value, Measure(MeasurementUnit.METERS, 15))
roof_width = MeasureFactory.create_measure(RecordingType.BINARY.value, Measure(MeasurementUnit.METERS, 3))
# create a layer of steel roof
roof_layer = Layer(roof_height, roof_length, roof_width, roof_material, LayerRoughness.MEDIUM_ROUGH)

# create a cover for the roof
roof_cover = Cover(CoverType.FLOOR)

# roof layer to cover
roof_cover.add_layer(roof_layer)

# create building envelope and add roof cover
envelope = Envelope()
envelope.add_cover(roof_cover)
building.envelope = envelope # building was created 1 above

3. Create and associate zones to the hall, corridor, room and office

from metamenth.enumerations import ZoneType
from metamenth.enumerations import HVACType
from metamenth.virtual.zone import Zone

hvac_zone_1 = Zone("HVAC Zone 1", ZoneType.HVAC, HVACType.INTERIOR)
hvac_zone_2 = Zone("HVAC Zone 2", ZoneType.HVAC, HVACType.INTERIOR)
# set adjacent zones
hvac_zone_2.add_adjacent_zones([hvac_zone_1])

# assign the mechanical room to hvac zone 1
mechanical_room.add_zone(hvac_zone_1, building) # building and mechanical room were created in 1 above

# assign the hall, corridor and room to hvac zone 2
room.add_zone(hvac_zone_2, building)
corridor.add_zone(hvac_zone_2, building)
hall.add_zone(hvac_zone_2, building)

4. Create and assign thermostat to the hall

from metamenth.transducers.sensor import Sensor
from metamenth.subsystem.appliance import Appliance
from metamenth.enumerations import ApplianceType
from metamenth.enumerations import ApplianceCategory
from metamenth.enumerations import SensorMeasureType
from metamenth.enumerations import SensorMeasure
from metamenth.enumerations import SensorLogType
from metamenth.datatypes.measure import Measure
from metamenth.enumerations import MeasurementUnit
from metamenth.misc import MeasureFactory

temp_op_condition = MeasureFactory.create_measure("Continuous",
                                    Measure(MeasurementUnit.DEGREE_CELSIUS, 4.4, 37.8))
humidity_op_conditions = MeasureFactory.create_measure("Continuous",
                                    Measure(MeasurementUnit.RELATIVE_HUMIDITY, 20, 80))
thermostat = Appliance("Thermostat", [ApplianceCategory.HOME, ApplianceCategory.SMART],
                               ApplianceType.THERMOSTAT,
                               operating_conditions=[temp_op_condition, humidity_op_conditions])

# create three sensors and assign them to the room
presence_sensor = Sensor("PRESENCE.SENSOR", SensorMeasure.OCCUPANCY, MeasurementUnit.PRESENCE,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 0, sensor_log_type=SensorLogType.POLLING)
temp_sensor = Sensor("TEMPERATURE.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
humidity_sensor = Sensor("HUMIDITY.SENSOR", SensorMeasure.HUMIDITY, MeasurementUnit.RELATIVE_HUMIDITY,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)

thermostat.add_transducer(presence_sensor)
thermostat.add_transducer(temp_sensor)
thermostat.add_transducer(humidity_sensor)

# add thermostat to the hall
hall.add_appliance(thermostat) # hall was created in 1 above

5. Create and assign sensors to the corridor, room and mechanical room

from metamenth.transducers.sensor import Sensor
from metamenth.subsystem.appliance import Appliance
from metamenth.enumerations import ApplianceType
from metamenth.enumerations import ApplianceCategory
from metamenth.enumerations import SensorMeasureType
from metamenth.enumerations import SensorMeasure
from metamenth.enumerations import SensorLogType
from metamenth.datatypes.measure import Measure
from metamenth.enumerations import MeasurementUnit
from metamenth.misc import MeasureFactory

# room sensors
room_temp_sensor = Sensor("ROOM.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
room_co2_sensor = Sensor("ROOM.CO2.SENSOR", SensorMeasure.CARBON_DIOXIDE, MeasurementUnit.PARTS_PER_MILLION,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
room.add_transducer(room_co2_sensor)
room.add_transducer(room_temp_sensor)

# mechanical room sensors
mec_room_temp_sensor = Sensor("MEC.ROOM.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.CHANGE_OF_VALUE)
mec_room_humidity_sensor = Sensor("MEC.ROOM.HDT.SENSOR", SensorMeasure.HUMIDITY, MeasurementUnit.RELATIVE_HUMIDITY,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
mechanical_room.add_transducer(mec_room_humidity_sensor)
mechanical_room.add_transducer(mec_room_temp_sensor)

# add smoke detector to mechanical room
temp_op_condition = MeasureFactory.create_measure("Continuous",
                                    Measure(MeasurementUnit.DEGREE_CELSIUS, 0, 38))
humidity_op_condition = MeasureFactory.create_measure("Continuous",
                                    Measure(MeasurementUnit.RELATIVE_HUMIDITY, 0, 95))
smoke_detector = Appliance("SMK.DETECTOR", [ApplianceCategory.HOME, ApplianceCategory.SMART],
                               ApplianceType.SMOKE_DETECTOR,
                               operating_conditions=[temp_op_condition, humidity_op_condition])
mechanical_room.add_appliance(smoke_detector)

# corridor sensors
corr_room_temp_sensor = Sensor("CORR.ROOM.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.CHANGE_OF_VALUE)
corridor.add_transducer(corr_room_temp_sensor)

6. Create and add the fan coil unit, baseboard heater, radiant heat slab, chiller and boiler

from metamenth.subsystem.hvac_components.fan_coil_unit import FanCoilUnit
from metamenth.subsystem.hvac_components.heat_exchanger import HeatExchanger
from metamenth.subsystem.hvac_components.chiller import Chiller
from metamenth.subsystem.hvac_components.boiler import Boiler
from metamenth.subsystem.hvac_components.fan import Fan
from metamenth.enumerations import ChillerType, BoilerCategory, FCUType, FCUPipeSystem, PowerState
from metamenth.enumerations import HeatingType, HeatExchangerType, HeatExchangerFlowType
from metamenth.enumerations import RadiantSlabType, MeterMeasureMode,  MeterType, MeasurementUnit 
from metamenth.subsystem.baseboard_heater import BaseboardHeater
from metamenth.subsystem.hvac_components.variable_frequency_drive import VariableFrequencyDrive
from metamenth.subsystem.radiant_slab import RadiantSlab
from metamenth.subsystem.hvac_components.cooling_tower import CoolingTower
from metamenth.measure_instruments.meter import Meter
from metamenth.subsystem.hvac_components.duct import Duct
from metamenth.enumerations import DuctType, DuctSubType
from metamenth.subsystem.hvac_components.duct_connection import DuctConnection
from metamenth.enumerations import DuctConnectionEntityType

# create boiler and chiller and add them to mechanical room
boiler = Boiler('MEC.BOILER', BoilerCategory.NATURAL_GAS, PowerState.ON)
chiller = Chiller('MEC.CHILLER', ChillerType.WATER_COOLED, PowerState.ON)
mechanical_room.add_hvac_component(boiler)
mechanical_room.add_hvac_component(chiller)

# create baseboard heater add it to the corridor
baseboard_heater = BaseboardHeater('CORR.BS.HEATER', HeatingType.ELECTRIC, PowerState.OUT_OF_SERVICE)
corridor.add_hvac_component(baseboard_heater)

# create fan coil unit and add it to the hall
vfd = VariableFrequencyDrive('VFD')
fan = Fan("FCU.FAN", PowerState.ON, vfd)
heat_exchanger = HeatExchanger("FCU.HT.EXG", HeatExchangerType.FIN_TUBE, HeatExchangerFlowType.PARALLEL)
fcu = FanCoilUnit('HALL.FCU', heat_exchanger, fan, FCUType.STANDALONE, FCUPipeSystem.TWO_PIPE, False)
hall.add_hvac_component(fcu)

# add radiant heat slab to the hall
slab = RadiantSlab('HALL.SLAB', RadiantSlabType.ELECTRIC)
hall.add_hvac_component(slab)

# create the cooling tower and connect it with the chiller
cooling_tower = CoolingTower('CL.TWR')
# create a flow meter and assign it to the cooling tower
flow_meter = Meter('CL.TWR.FL.MTR', 90, MeasurementUnit.LITERS_PER_SECOND, MeterType.FLOW, MeterMeasureMode.AUTOMATIC)
cooling_tower.meter = flow_meter
chiller_tower_duct = Duct("CL.TWR.01", DuctType.WATER)
chiller_tower_duct.duct_sub_type = DuctSubType.HOT_AND_COLD_WATER
chiller_tower_duct_conn = DuctConnection()
chiller_tower_duct_conn.add_entity(DuctConnectionEntityType.SOURCE, chiller)
chiller_tower_duct_conn.add_entity(DuctConnectionEntityType.DESTINATION, cooling_tower)
chiller_tower_duct_conn.is_loop = True
chiller_tower_duct.connections = chiller_tower_duct_conn
chiller.add_duct(chiller_tower_duct) # the duct is accessible from the chiller
cooling_tower.add_duct(chiller_tower_duct) # (optionally) make the duct accessible from the cooling tower as well

7. Create an HVAC system for the building

from metamenth.subsystem.building_control_system import BuildingControlSystem
from metamenth.subsystem.hvac_system import HVACSystem
from metamenth.subsystem.hvac_components.duct import Duct
from metamenth.enumerations import DuctType, DuctSubType
from metamenth.subsystem.hvac_components.duct_connection import DuctConnection
from metamenth.enumerations import DuctConnectionEntityType, VentilationType
from metamenth.subsystem.ventilation_system import VentilationSystem

bcs = BuildingControlSystem("EV Control System")
hvac_system = HVACSystem()
bcs.hvac_system = hvac_system

# Create the fresh air duct for the ventilation system
supply_air_duct = Duct("SUPP.VNT.01", DuctType.AIR)
supply_air_duct.duct_sub_type = DuctSubType.FRESH_AIR

# create the return air duct for the ventilation system
return_air_duct = Duct("RET.VNT.01", DuctType.AIR)
return_air_duct.duct_sub_type = DuctSubType.RETURN_AIR

# create the recirculation air duct
recirculation_air_duct = Duct("REC.VNT.01", DuctType.AIR)
recirculation_air_duct.duct_sub_type = DuctSubType.RETURN_AIR

# connect the fresh air, return air and recirculation air ducts
duct2duct_conn = DuctConnection()
# add the return air duct as the source of the connection
duct2duct_conn.add_entity(DuctConnectionEntityType.SOURCE, return_air_duct)
# add the fresh air duct as the destination of the connection
duct2duct_conn.add_entity(DuctConnectionEntityType.DESTINATION, supply_air_duct)
# set the connection object as a property of the recirculation air duct
recirculation_air_duct.connections = duct2duct_conn

# set the recirculation air duct as the source for the supply air duct
supp_duct_conn = DuctConnection()
supp_duct_conn.add_entity(DuctConnectionEntityType.SOURCE, recirculation_air_duct)
supply_air_duct.connections = duct2duct_conn

# create the ventilation system with the supply air duct as the principal duct
ventilation_system = VentilationSystem(VentilationType.AIR_HANDLING_UNIT, supply_air_duct)

# set the ventilation system for the HVAC system
hvac_system.add_ventilation_system(ventilation_system)

8. Supply air duct components

from metamenth.transducers.sensor import Sensor
from metamenth.enumerations import SensorMeasureType
from metamenth.enumerations import SensorMeasure
from metamenth.enumerations import SensorLogType
from metamenth.enumerations import MeasurementUnit
from metamenth.subsystem.hvac_components.damper import Damper
from metamenth.subsystem.hvac_components.filter import Filter
from metamenth.enumerations import DamperType, FilterType
from metamenth.subsystem.hvac_components.fan import Fan
from metamenth.subsystem.hvac_components.variable_frequency_drive import VariableFrequencyDrive
from metamenth.subsystem.hvac_components.duct import Duct
from metamenth.subsystem.hvac_components.duct_connection import DuctConnection
from metamenth.enumerations import DuctConnectionEntityType, HeatExchangerType, HeatExchangerFlowType, DuctType, DuctSubType
from metamenth.subsystem.hvac_components.heat_exchanger import HeatExchanger
from metamenth.subsystem.hvac_components.air_volume_box import AirVolumeBox
from metamenth.enumerations import AirVolumeType

# create the four temperature sensors and one pressure sensor for the supply air duct
supp_vnt_temp_sensor_1 = Sensor("SUPP.VNT.TEMP.SENSOR.1", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
supp_vnt_temp_sensor_2 = Sensor("SUPP.VNT.TEMP.SENSOR.2", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
supp_vnt_temp_sensor_3 = Sensor("SUPP.VNT.TEMP.SENSOR.3", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
supp_vnt_temp_sensor_4 = Sensor("SUPP.VNT.TEMP.SENSOR.4", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
supp_vnt_pressure_sensor = Sensor("SUPP.VNT.PRS.SENSOR", SensorMeasure.PRESSURE, MeasurementUnit.PASCAL,
                            SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
supply_air_duct.add_transducer(supp_vnt_temp_sensor_1) #supply_air_duct was created in Section 7
supply_air_duct.add_transducer(supp_vnt_temp_sensor_2)
supply_air_duct.add_transducer(supp_vnt_temp_sensor_3)
supply_air_duct.add_transducer(supp_vnt_temp_sensor_4)
supply_air_duct.add_transducer(supp_vnt_pressure_sensor)

# create and add the damper and filter to the supply air duct
damper = Damper("SUPP.VNT.DP", DamperType.BACK_DRAFT)
filter = Filter("SUPP.VNT.FLT", FilterType.ELECTROSTATIC)
supply_air_duct.add_filter(filter)
supply_air_duct.add_damper(damper)

# add fan to the supply air duct
vfd = VariableFrequencyDrive('VFD')
fan = Fan("SUPP.VNT.FAN", PowerState.ON, vfd)
supply_air_duct.add_fan(fan)

# add the two heat exchangers
heat_exchanger_1 = HeatExchanger("SUPP.VNT.HT.EXG.1", HeatExchangerType.FIN_TUBE, HeatExchangerFlowType.PARALLEL)
heat_exchanger_2 = HeatExchanger("SUPP.VNT.HT.EXG.2", HeatExchangerType.FIN_TUBE, HeatExchangerFlowType.PARALLEL)
supply_air_duct.add_heat_exchanger(heat_exchanger_1)
supply_air_duct.add_heat_exchanger(heat_exchanger_2)

# connect heat exchanger 1 to the boiler
heat_exchanger_boiler_pipe = Duct("HXG.BLR.PIPE", DuctType.WATER)
heat_exchanger_boiler_pipe.duct_sub_type = DuctSubType.HOT_AND_COLD_WATER

heat_exchanger_boiler_conn = DuctConnection()
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.SOURCE, heat_exchanger_1)
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.DESTINATION, boiler) # boiler was created in Section 6
heat_exchanger_boiler_conn.is_loop = True # source can become destination and vice versa
heat_exchanger_boiler_pipe.connections = heat_exchanger_boiler_conn
heat_exchanger_1.add_duct(heat_exchanger_boiler_pipe)

# connect heat exchanger 2 to the chiller
heat_exchanger_chiller_pipe = Duct("HXG.CHL.PIPE", DuctType.WATER_WITH_ANTI_FREEZE)
heat_exchanger_chiller_conn = DuctConnection()
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.SOURCE, heat_exchanger_2)
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.DESTINATION, chiller) # chiller was created in Section 6
heat_exchanger_boiler_conn.is_loop = True # source can become destination and vice versa
heat_exchanger_chiller_pipe.connections = heat_exchanger_chiller_conn
heat_exchanger_2.add_duct(heat_exchanger_chiller_pipe)

# create the two VAV boxes for the supply air duct
vav_box_1 = AirVolumeBox('SUPP.VNT.VAV.1', AirVolumeType.VARIABLE_AIR_VOLUME)
vav_box_1.inlet_dampers = [Damper('SUP.VNT.VAV.DMP.1', DamperType.MANUAL_VOLUME)]
vav_box_1_temp_sensor = Sensor("VAV.1.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
vav_box_1.add_transducer(vav_box_1_temp_sensor)
supply_air_duct.add_connected_air_volume_box(vav_box_1)

vav_box_2 = AirVolumeBox('SUPP.VNT.VAV.2', AirVolumeType.VARIABLE_AIR_VOLUME)
vav_box_2.inlet_dampers = [Damper('SUP.VNT.VAV.DMP.2', DamperType.MANUAL_VOLUME)]
vav_box_2_temp_sensor = Sensor("VAV.2.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
vav_box_2.add_transducer(vav_box_2_temp_sensor)
supply_air_duct.add_connected_air_volume_box(vav_box_2)

# add the mechanical room to vav box 2 (the vav box suppliers air to that room)
vav_box_2.add_spaces([mechanical_room])

# add the corridor, hall and room to vav box 1
vav_box_1.add_spaces([room, corridor, hall])

9. Recirculation air duct components

from metamenth.subsystem.hvac_components.damper import Damper
from metamenth.enumerations import DamperType

# create the damper for the recirculation air duct
rec_damper = Damper('REC.VNT.DMP', DamperType.MANUAL_VOLUME)
recirculation_air_duct.add_damper(rec_damper) # recirculation_air_duct created in section 7

10. Return air duct components

from metamenth.transducers.sensor import Sensor
from metamenth.enumerations import SensorMeasureType
from metamenth.enumerations import SensorMeasure
from metamenth.enumerations import SensorLogType
from metamenth.enumerations import MeasurementUnit
from metamenth.subsystem.hvac_components.damper import Damper
from metamenth.subsystem.hvac_components.filter import Filter
from metamenth.enumerations import DamperType, FilterType
from metamenth.subsystem.hvac_components.fan import Fan
from metamenth.subsystem.hvac_components.variable_frequency_drive import VariableFrequencyDrive
from metamenth.subsystem.hvac_components.duct import Duct
from metamenth.subsystem.hvac_components.duct_connection import DuctConnection
from metamenth.enumerations import RecordingType, HeatExchangerType, HeatExchangerFlowType, DuctType, DuctSubType, PowerState
from metamenth.subsystem.hvac_components.heat_exchanger import HeatExchanger
from metamenth.subsystem.hvac_components.air_volume_box import AirVolumeBox
from metamenth.enumerations import AirVolumeType
from metamenth.transducers.actuator import Actuator
from metamenth.subsystem.hvac_components.controller import Controller
from metamenth.misc import MeasureFactory
from metamenth.datatypes.measure import Measure

# create the damper and add it to the duct
ret_damper = Damper('RET.VNT.DMP', DamperType.MANUAL_VOLUME)
return_air_duct.add_damper(ret_damper)

# add the two temperature sensors
ret_duct_temp_sensor_1 = Sensor("RET.VNT.TEMP.SENSOR.1", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
ret_duct_temp_sensor_2 = Sensor("RET.VNT.TEMP.SENSOR.2", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
                            SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
return_air_duct.add_transducer(ret_duct_temp_sensor_1)
return_air_duct.add_transducer(ret_duct_temp_sensor_2)

# create the fan, actuator and controller and link them together
vfd = VariableFrequencyDrive('RET.VNT.VRD')
fan = Fan("RET.VNT.FN", PowerState.ON, vfd)
# the actuator actuates the fan
actuator = Actuator("RET.ACT.FN", fan)
controller = Controller('RET.CTL')
controller.add_controller_entity(fan)
# the controller controls the actuator
actuator.controller = controller
controller.add_transducer(actuator)
# the controller gets its temperature input from ret_duct_temp_sensor_1
controller.add_transducer(ret_duct_temp_sensor_1)

# add temperature set point for the controller. The set point is related to ret_duct_temp_sensor_1 and the actuator
temperature_set_point = MeasureFactory.create_measure(RecordingType.CONTINUOUS.value,
                                                              Measure(MeasurementUnit.DEGREE_CELSIUS, 10, 20))
controller.add_set_point(temperature_set_point, (ret_duct_temp_sensor_1.name, actuator.name))

# add the actuator and fan to the duct
return_air_duct.add_transducer(actuator)
return_air_duct.add_fan(fan)

# (optionally) set the spaces (hall, corridor, room and mechanical room as source entities for the return air duct)
return_air_duct.connections.add_entity(DuctConnectionEntityType.SOURCE, room)
return_air_duct.connections.add_entity(DuctConnectionEntityType.SOURCE, hall)
return_air_duct.connections.add_entity(DuctConnectionEntityType.SOURCE, corridor)
return_air_duct.connections.add_entity(DuctConnectionEntityType.SOURCE, mechanical_room)

NB: Refer to the test directory for more insight on usage

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

metamenth-1.0.5.tar.gz (175.2 kB view details)

Uploaded Source

Built Distribution

metamenth-1.0.5-py3-none-any.whl (133.4 kB view details)

Uploaded Python 3

File details

Details for the file metamenth-1.0.5.tar.gz.

File metadata

  • Download URL: metamenth-1.0.5.tar.gz
  • Upload date:
  • Size: 175.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.15

File hashes

Hashes for metamenth-1.0.5.tar.gz
Algorithm Hash digest
SHA256 cec2616d33b08daa75c0a798956ac69537673ac1f6e275399a6900ce75b0be13
MD5 7b07ce960b105f475898fcb1cf9af7a9
BLAKE2b-256 a6b4c9c4a485cc0d08a6ec1b8ce756b4d8df8cb95d5a7a575b7bda80c7dff0dd

See more details on using hashes here.

File details

Details for the file metamenth-1.0.5-py3-none-any.whl.

File metadata

  • Download URL: metamenth-1.0.5-py3-none-any.whl
  • Upload date:
  • Size: 133.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.15

File hashes

Hashes for metamenth-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 8f018692ff16a8d317fdf39783b79763c4ced9f2be83ade3f44565041fc01216
MD5 cb29fcaa3ee4c9798e72009eb61cf241
BLAKE2b-256 12856460b64f1ba4505363abd05690c769f7d48b4753a6ec456e847292612e5b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page