Skip to content

Commit 7bd1dff

Browse files
authored
Merge pull request #13 from ptidejteam/dev
Dev
2 parents 3b5af07 + 1819ab3 commit 7bd1dff

File tree

3 files changed

+240
-22
lines changed

3 files changed

+240
-22
lines changed

README.md

Lines changed: 238 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Metamodel for Energy Things (MetamEnTh)
22

3-
![Build Status](https://github.com/peteryefi/metamenth/actions/workflows/build.yml/badge.svg)
3+
![Build Status](https://github.com/ptidejteam/metamenth/actions/workflows/build.yml/badge.svg)
44
![Version](https://img.shields.io/badge/version-1.0.0-blue)
5-
[![License](https://img.shields.io/github/license/peteryefi/metamenth)](https://github.com/username/repository/blob/main/LICENSE)
5+
[![License](https://img.shields.io/github/license/ptidejteam/metamenth)](https://github.com/ptidejteam/metamenth/blob/main/LICENSE)
66
![PyPI version](https://img.shields.io/pypi/v/metamenth.svg)
7-
[![Wiki](https://img.shields.io/badge/docs-wiki-blue.svg)](https://github.com/peteryefi/metamenth/wiki)
7+
[![Wiki](https://img.shields.io/badge/docs-wiki-blue.svg)](https://github.com/ptidejteam/metamenth/wiki)
88

99
**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.
1010

11-
Read the documentation here: [MetamEnTh Documentation](https://github.com/peteryefi/metamenth/wiki)
11+
Read the documentation here: [MetamEnTh Documentation](https://github.com/ptidejteam/metamenth/wiki)
1212

1313
## Table of Contents
1414
1. [Setting up MetamEnTh Locally](#setting-up-metamEnTh-locally)
@@ -25,7 +25,7 @@ Read the documentation here: [MetamEnTh Documentation](https://github.com/petery
2525
### Cloning the repository:
2626

2727
```sh
28-
git clone https://github.com/peteryefi/metamenth.git
28+
git clone https://github.com/ptidejteam/metamenth.git
2929
cd metamenth
3030
```
3131

@@ -86,15 +86,18 @@ internal_mass = MeasureFactory.create_measure(RecordingType.BINARY.value,
8686
area = MeasureFactory.create_measure(RecordingType.BINARY.value,
8787
Measure(MeasurementUnit.SQUARE_METERS, 45))
8888
# create room
89-
room = Room(area, "Office 1", RoomType.OFFICE)
89+
room = Room(area, "Room", RoomType.OFFICE)
9090

91-
mechanical_room = Room(area, "MR 01", RoomType.MECHANICAL)
91+
mechanical_room = Room(area, "Mechanical Room", RoomType.MECHANICAL)
9292

9393
# create a hall
94-
hall = OpenSpace("Dinning Hall", area, OpenSpaceType.HALL)
94+
hall = OpenSpace("Hall", area, OpenSpaceType.HALL)
95+
96+
# create a corridor
97+
corridor = OpenSpace("Corridor", area, OpenSpaceType.CORRIDOR)
9598

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

99102
# create the building's address
100103
address = Address("Montreal", "6399 Rue Sherbrooke", "QC", "H1N 2Z3", "Canada")
@@ -103,7 +106,7 @@ address = Address("Montreal", "6399 Rue Sherbrooke", "QC", "H1N 2Z3", "Canada")
103106
building = Building(2009, height, floor_area, internal_mass, address,
104107
BuildingType.COMMERCIAL, [floor])
105108
```
106-
### 2. Adding an Envelope with Roof
109+
### 2. Adding an envelope with roof
107110
```python
108111
from metamenth.structure.layer import Layer
109112
from metamenth.structure.material import Material
@@ -157,22 +160,27 @@ envelope.add_cover(roof_cover)
157160
building.envelope = envelope # building was created 1 above
158161
```
159162

160-
### 3. Create and associate Zones to the hall
163+
### 3. Create and associate zones to the hall, corridor, room and office
161164
```python
162165
from metamenth.enumerations import ZoneType
163166
from metamenth.enumerations import HVACType
164167
from metamenth.virtual.zone import Zone
165168

166-
hvac_cooling_zone = Zone("HVAC_COOLING_ZONE", ZoneType.HVAC, HVACType.INTERIOR)
167-
hvac_heating_zone = Zone("HVAC_HEATING_ZONE", ZoneType.HVAC, HVACType.PERIMETER)
168-
# make the cooling zone adjacent to the heating zone
169-
hvac_heating_zone.add_adjacent_zones([hvac_cooling_zone])
169+
hvac_zone_1 = Zone("HVAC Zone 1", ZoneType.HVAC, HVACType.INTERIOR)
170+
hvac_zone_2 = Zone("HVAC Zone 2", ZoneType.HVAC, HVACType.INTERIOR)
171+
# set adjacent zones
172+
hvac_zone_2.add_adjacent_zones([hvac_zone_1])
173+
174+
# assign the mechanical room to hvac zone 1
175+
mechanical_room.add_zone(hvac_zone_1, building) # building and mechanical room were created in 1 above
170176

171-
# assign the zone to the room
172-
hall.add_zone(hvac_heating_zone, building) # building and hall were created in 1 above
177+
# assign the hall, corridor and room to hvac zone 2
178+
room.add_zone(hvac_zone_2, building)
179+
corridor.add_zone(hvac_zone_2, building)
180+
hall.add_zone(hvac_zone_2, building)
173181

174182
```
175-
### 4. Create and assign thermostats to the hall
183+
### 4. Create and assign thermostat to the hall
176184
```python
177185
from metamenth.transducers.sensor import Sensor
178186
from metamenth.subsystem.appliance import Appliance
@@ -207,8 +215,219 @@ thermostat.add_transducer(humidity_sensor)
207215

208216
# add thermostat to the hall
209217
hall.add_appliance(thermostat) # hall was created in 1 above
218+
```
219+
#### 5. Create and assign sensors to the corridor, room and mechanical room
220+
```python
221+
from metamenth.transducers.sensor import Sensor
222+
from metamenth.subsystem.appliance import Appliance
223+
from metamenth.enumerations import ApplianceType
224+
from metamenth.enumerations import ApplianceCategory
225+
from metamenth.enumerations import SensorMeasureType
226+
from metamenth.enumerations import SensorMeasure
227+
from metamenth.enumerations import SensorLogType
228+
from metamenth.datatypes.measure import Measure
229+
from metamenth.enumerations import MeasurementUnit
230+
from metamenth.misc import MeasureFactory
210231

232+
# room sensors
233+
room_temp_sensor = Sensor("ROOM.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
234+
SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
235+
room_co2_sensor = Sensor("ROOM.CO2.SENSOR", SensorMeasure.CARBON_DIOXIDE, MeasurementUnit.PARTS_PER_MILLION,
236+
SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
237+
room.add_transducer(room_co2_sensor)
238+
room.add_transducer(room_temp_sensor)
239+
240+
# mechanical room sensors
241+
mec_room_temp_sensor = Sensor("MEC.ROOM.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
242+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.CHANGE_OF_VALUE)
243+
mec_room_humidity_sensor = Sensor("MEC.ROOM.HDT.SENSOR", SensorMeasure.HUMIDITY, MeasurementUnit.RELATIVE_HUMIDITY,
244+
SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
245+
mechanical_room.add_transducer(mec_room_humidity_sensor)
246+
mechanical_room.add_transducer(mec_room_temp_sensor)
247+
248+
# add smoke detector to mechanical room
249+
temp_op_condition = MeasureFactory.create_measure("Continuous",
250+
Measure(MeasurementUnit.DEGREE_CELSIUS, 0, 38))
251+
humidity_op_condition = MeasureFactory.create_measure("Continuous",
252+
Measure(MeasurementUnit.RELATIVE_HUMIDITY, 0, 95))
253+
smoke_detector = Appliance("SMK.DETECTOR", [ApplianceCategory.HOME, ApplianceCategory.SMART],
254+
ApplianceType.SMOKE_DETECTOR,
255+
operating_conditions=[temp_op_condition, humidity_op_condition])
256+
mechanical_room.add_appliance(smoke_detector)
257+
258+
# corridor sensors
259+
corr_room_temp_sensor = Sensor("CORR.ROOM.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
260+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.CHANGE_OF_VALUE)
261+
corridor.add_transducer(corr_room_temp_sensor)
211262
```
263+
#### 6. Create and add the fan coil unit, baseboard heater, chiller and boiler
264+
```python
265+
from metamenth.subsystem.hvac_components.fan_coil_unit import FanCoilUnit
266+
from metamenth.subsystem.hvac_components.heat_exchanger import HeatExchanger
267+
from metamenth.subsystem.hvac_components.chiller import Chiller
268+
from metamenth.subsystem.hvac_components.boiler import Boiler
269+
from metamenth.subsystem.hvac_components.fan import Fan
270+
from metamenth.enumerations import ChillerType, BoilerCategory, FCUType, FCUPipeSystem, PowerState
271+
from metamenth.enumerations import HeatingType, HeatExchangerType, HeatExchangerFlowType
272+
from metamenth.subsystem.baseboard_heater import BaseboardHeater
273+
from metamenth.subsystem.hvac_components.variable_frequency_drive import VariableFrequencyDrive
274+
275+
# create boiler and chiller and add them to mechanical room
276+
boiler = Boiler('MEC.BOILER', BoilerCategory.NATURAL_GAS, PowerState.ON)
277+
chiller = Chiller('MEC.CHILLER', ChillerType.WATER_COOLED, PowerState.ON)
278+
mechanical_room.add_hvac_component(boiler)
279+
mechanical_room.add_hvac_component(chiller)
280+
281+
# create baseboard heater add it to the corridor
282+
baseboard_heater = BaseboardHeater('CORR.BS.HEATER', HeatingType.ELECTRIC, PowerState.OUT_OF_SERVICE)
283+
corridor.add_hvac_component(baseboard_heater)
284+
285+
# create fan coil unit and add it to the hall
286+
vfd = VariableFrequencyDrive('VFD')
287+
fan = Fan("FCU.FAN", PowerState.ON, vfd)
288+
heat_exchanger = HeatExchanger("FCU.HT.EXG", HeatExchangerType.FIN_TUBE, HeatExchangerFlowType.PARALLEL)
289+
fcu = FanCoilUnit('HALL.FCU', heat_exchanger, fan, FCUType.STANDALONE, FCUPipeSystem.TWO_PIPE, False)
290+
hall.add_hvac_component(fcu)
291+
```
292+
#### 7. Create an HVAC system for the building
293+
```python
294+
from metamenth.subsystem.building_control_system import BuildingControlSystem
295+
from metamenth.subsystem.hvac_system import HVACSystem
296+
from metamenth.subsystem.hvac_components.duct import Duct
297+
from metamenth.enumerations import DuctType, DuctSubType
298+
from metamenth.subsystem.hvac_components.duct_connection import DuctConnection
299+
from metamenth.enumerations import DuctConnectionEntityType, VentilationType
300+
from metamenth.subsystem.ventilation_system import VentilationSystem
301+
302+
bcs = BuildingControlSystem("EV Control System")
303+
hvac_system = HVACSystem()
304+
bcs.hvac_system = hvac_system
305+
306+
# Create the fresh air duct for the ventilation system
307+
supply_air_duct = Duct("SUPP.VNT.01", DuctType.AIR)
308+
supply_air_duct.duct_sub_type = DuctSubType.FRESH_AIR
309+
310+
# create the return air duct for the ventilation system
311+
return_air_duct = Duct("RET.VNT.01", DuctType.AIR)
312+
return_air_duct.duct_sub_type = DuctSubType.RETURN_AIR
313+
314+
# create the recirculation air duct
315+
recirculation_air_duct = Duct("REC.VNT.01", DuctType.AIR)
316+
recirculation_air_duct.duct_sub_type = DuctSubType.RETURN_AIR
317+
318+
# connect the fresh air, return air and recirculation air ducts
319+
duct2duct_conn = DuctConnection()
320+
# add the return air duct as the source of the connection
321+
duct2duct_conn.add_entity(DuctConnectionEntityType.SOURCE, return_air_duct)
322+
# add the fresh air duct as the destination of the connection
323+
duct2duct_conn.add_entity(DuctConnectionEntityType.DESTINATION, supply_air_duct)
324+
# set the connection object as a property of the recirculation air duct
325+
recirculation_air_duct.connections = duct2duct_conn
326+
327+
# set the recirculation air duct as the source for the supply air duct
328+
supp_duct_conn = DuctConnection()
329+
supp_duct_conn.add_entity(DuctConnectionEntityType.SOURCE, recirculation_air_duct)
330+
supply_air_duct.connections = duct2duct_conn
331+
332+
# create the ventilation system with the supply air duct as the principal duct
333+
ventilation_system = VentilationSystem(VentilationType.AIR_HANDLING_UNIT, supply_air_duct)
334+
335+
# set the ventilation system for the HVAC system
336+
hvac_system.add_ventilation_system(ventilation_system)
337+
```
338+
#### 8. Supply air duct components
339+
```python
340+
from metamenth.transducers.sensor import Sensor
341+
from metamenth.enumerations import SensorMeasureType
342+
from metamenth.enumerations import SensorMeasure
343+
from metamenth.enumerations import SensorLogType
344+
from metamenth.enumerations import MeasurementUnit
345+
from metamenth.subsystem.hvac_components.damper import Damper
346+
from metamenth.subsystem.hvac_components.filter import Filter
347+
from metamenth.enumerations import DamperType, FilterType
348+
from metamenth.subsystem.hvac_components.fan import Fan
349+
from metamenth.subsystem.hvac_components.variable_frequency_drive import VariableFrequencyDrive
350+
from metamenth.subsystem.hvac_components.duct import Duct
351+
from metamenth.subsystem.hvac_components.duct_connection import DuctConnection
352+
from metamenth.enumerations import DuctConnectionEntityType, HeatExchangerType, HeatExchangerFlowType, DuctType, DuctSubType
353+
from metamenth.subsystem.hvac_components.heat_exchanger import HeatExchanger
354+
from metamenth.subsystem.hvac_components.air_volume_box import AirVolumeBox
355+
from metamenth.enumerations import AirVolumeType
356+
357+
# create the four temperature sensors and one pressure sensor for the supply air duct
358+
supp_vnt_temp_sensor_1 = Sensor("SUPP.VNT.TEMP.SENSOR.1", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
359+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
360+
supp_vnt_temp_sensor_2 = Sensor("SUPP.VNT.TEMP.SENSOR.2", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
361+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
362+
supp_vnt_temp_sensor_3 = Sensor("SUPP.VNT.TEMP.SENSOR.3", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
363+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
364+
supp_vnt_temp_sensor_4 = Sensor("SUPP.VNT.TEMP.SENSOR.4", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
365+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
366+
supp_vnt_pressure_sensor = Sensor("SUPP.VNT.PRS.SENSOR", SensorMeasure.PRESSURE, MeasurementUnit.PASCAL,
367+
SensorMeasureType.THERMO_COUPLE_TYPE_B, 900, sensor_log_type=SensorLogType.POLLING)
368+
supply_air_duct.add_transducer(supp_vnt_temp_sensor_1) #supply_air_duct was created in Section 7
369+
supply_air_duct.add_transducer(supp_vnt_temp_sensor_2)
370+
supply_air_duct.add_transducer(supp_vnt_temp_sensor_3)
371+
supply_air_duct.add_transducer(supp_vnt_temp_sensor_4)
372+
supply_air_duct.add_transducer(supp_vnt_pressure_sensor)
373+
374+
# create and add the damper and filter to the supply air duct
375+
damper = Damper("SUPP.VNT.DP", DamperType.BACK_DRAFT)
376+
filter = Filter("SUPP.VNT.FLT", FilterType.ELECTROSTATIC)
377+
supply_air_duct.add_filter(filter)
378+
supply_air_duct.add_damper(damper)
379+
380+
# add fan to the supply air duct
381+
vfd = VariableFrequencyDrive('VFD')
382+
fan = Fan("SUPP.VNT.FAN", PowerState.ON, vfd)
383+
supply_air_duct.add_fan(fan)
384+
385+
# add the two heat exchangers
386+
heat_exchanger_1 = HeatExchanger("SUPP.VNT.HT.EXG.1", HeatExchangerType.FIN_TUBE, HeatExchangerFlowType.PARALLEL)
387+
heat_exchanger_2 = HeatExchanger("SUPP.VNT.HT.EXG.2", HeatExchangerType.FIN_TUBE, HeatExchangerFlowType.PARALLEL)
388+
supply_air_duct.add_heat_exchanger(heat_exchanger_1)
389+
supply_air_duct.add_heat_exchanger(heat_exchanger_2)
390+
391+
# connect heat exchanger 1 to the boiler
392+
heat_exchanger_boiler_pipe = Duct("HXG.BLR.PIPE", DuctType.WATER)
393+
heat_exchanger_boiler_pipe.duct_sub_type = DuctSubType.HOT_AND_COLD_WATER
394+
395+
heat_exchanger_boiler_conn = DuctConnection()
396+
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.SOURCE, heat_exchanger_1)
397+
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.DESTINATION, boiler) # boiler was created in Section 6
398+
heat_exchanger_boiler_conn.is_loop = True # source can become destination and vice versa
399+
heat_exchanger_boiler_pipe.connections = heat_exchanger_boiler_conn
400+
heat_exchanger_1.add_duct(heat_exchanger_boiler_pipe)
401+
402+
# connect heat exchanger 2 to the chiller
403+
heat_exchanger_chiller_pipe = Duct("HXG.CHL.PIP", DuctType.WATER_WITH_ANTI_FREEZE)
404+
heat_exchanger_chiller_conn = DuctConnection()
405+
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.SOURCE, heat_exchanger_2)
406+
heat_exchanger_boiler_conn.add_entity(DuctConnectionEntityType.DESTINATION, chiller) # chiller was created in Section 6
407+
heat_exchanger_boiler_conn.is_loop = True # source can become destination and vice versa
408+
heat_exchanger_chiller_pipe.connections = heat_exchanger_chiller_conn
409+
heat_exchanger_2.add_duct(heat_exchanger_chiller_pipe)
410+
411+
# create the two VAV boxes for the supply air duct
412+
vav_box_1 = AirVolumeBox('SUPP.VNT.VAV.1', AirVolumeType.VARIABLE_AIR_VOLUME)
413+
vav_box_1.inlet_dampers = [Damper('SUP.VNT.VAV.DMP.1', DamperType.MANUAL_VOLUME)]
414+
vav_box_1_temp_sensor = Sensor("VAV.1.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
415+
SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
416+
vav_box_1.add_transducer(vav_box_1_temp_sensor)
417+
supply_air_duct.add_connected_air_volume_box(vav_box_1)
212418

419+
vav_box_2 = AirVolumeBox('SUPP.VNT.VAV.2', AirVolumeType.VARIABLE_AIR_VOLUME)
420+
vav_box_2.inlet_dampers = [Damper('SUP.VNT.VAV.DMP.2', DamperType.MANUAL_VOLUME)]
421+
vav_box_2_temp_sensor = Sensor("VAV.2.TEMP.SENSOR", SensorMeasure.TEMPERATURE, MeasurementUnit.DEGREE_CELSIUS,
422+
SensorMeasureType.THERMO_COUPLE_TYPE_A, 900, sensor_log_type=SensorLogType.POLLING)
423+
vav_box_2.add_transducer(vav_box_2_temp_sensor)
424+
supply_air_duct.add_connected_air_volume_box(vav_box_2)
425+
426+
# add the mechanical room to vav box 2 (the vav box suppliers air to that room)
427+
vav_box_2.add_spaces([mechanical_room])
428+
429+
# add the corridor, hall and room to vav box 1
430+
vav_box_1.add_spaces([room, corridor, hall])
431+
```
213432

214-
NB: Refer to the [test directory](https://github.com/peteryefi/metamenth/tree/main/tests) for more insight on usage
433+
NB: Refer to the [test directory](https://github.com/ptidejteam/metamenth/tree/main/tests) for more insight on usage

metamenth/enumerations/sensor_measure.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class SensorMeasure(AbstractEnum):
1414
LIQUID_VELOCITY = "LiquidVelocity"
1515
LUMINANCE = "Luminance"
1616
CARBON_DIOXIDE = "CarbonDioxide"
17+
CARBON_MONOXIDE = "CarbonMonoxide"
1718
NOISE = "Noise"
1819
CURRENT = "Current"
1920
VOLTAGE = "Voltage"

setup.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
install_requires=requirements,
1111
entry_points={
1212
'console_scripts': [
13-
# Define command-line scripts here
14-
# e.g., 'your-script=your_module:main_function'
1513
],
1614
},
1715
author="Peter Yefi",
@@ -22,7 +20,7 @@
2220
"entities such as rooms and open spaces within buildings.",
2321
long_description=open('README.md').read(),
2422
long_description_content_type='text/markdown',
25-
url="https://github.com/peteryefi/metamenth",
23+
url="https://github.com/ptidejteam/metamenth",
2624
classifiers=[
2725
"Programming Language :: Python :: 3",
2826
"License :: OSI Approved :: Apache Software License",

0 commit comments

Comments
 (0)