Page MenuHomec4science

room_data.py
No OneTemporary

File Metadata

Created
Mon, Jun 3, 19:37

room_data.py

__author__ = 'Olivier Van Cutsem'
from bmsinterface.bms_interface_config import *
from building_data_management.comfort_data import BuildingComfortData
from building_data_management.interface_management.generic_interfaces import EMS_INTERFACE_WINDOW, EMS_INTERFACE_DOOR, EMS_INTERFACE_WALL
from building_data_management.interface_management.generic_interfaces import WindowInterface, WallInterface, DoorInterface
from ems_config import EMS_OUTSIDE_ROOM_NAME
# TODO: remove it later !
from bmsinterface.bms_missing_data import BMS_MISSING_DATA_ENVIRONMENTAL_SIGNAL
from building_data_management.signal_and_constraint_management.signal_data import PiecewiseConstantSignal
# Useful thermal constant
VTEMPSENSOR_TEMP_STC = 273.15
RHO_AIR_STC = 1.292
AIR_HEAT_CAPA = 1004
class BuildingRoomData():
"""
TODO
"""
TYPE_COMFORT_LIST = [EMS_COMFORT_temperature, EMS_COMFORT_luminosity, EMS_COMFORT_presence, EMS_COMFORT_humidity]
def __init__(self, name):
# General room data
self.__name = name
self.__surface = None
self.__volume = None
# Sensors of this room
self.__comfort = {EMS_COMFORT_temperature: None,
EMS_COMFORT_luminosity: None,
EMS_COMFORT_presence: None,
EMS_COMFORT_humidity: None}
# Interface with other rooms
self.__interface = dict()
### INIT ###
def initSensordata(self, room_sensors):
"""
Fill the empty structures with the BMS data
:param room_sensors: all the sensors of this room and their data
:return: /
"""
#TODO: avoid using Database-key dependent here ..
for sensor_id in room_sensors.keys():
type_measure = room_sensors[sensor_id][DB_KEY_COMFORT_TYPE]
current_value = room_sensors[sensor_id][DB_KEY_COMFORT_VALUE]
self.__comfort[type_measure] = BuildingComfortData(type_measure, None, current_value)
self.__comfort[type_measure].sensor = sensor_id
def setInterface(self, neighborID, interface, multi_interface=False):
"""
Insert or modify an interface with a neighbor room
:param neighborID: the ID of the interfaced room
:param interface: the interface object, describing its properties
:param multi_interface: if True, add this interface in addition to others
:return: /
"""
if not multi_interface:
self.__interface[neighborID] = interface
else:
if neighborID in self.__interface:
self.__interface[neighborID].append(interface)
else:
self.__interface[neighborID] = [interface]
### SENSORS & ACTUATORS manipulation
def get_comfort_type(self, sensor_id):
"""
Identify the comfort linked to the given sensor
:param sensor_id: the unique ID of the sensor
:return: the type of comfort associated to sensor_id
"""
for type in self.__comfort.keys():
if sensor_id == self.__comfort[type].sensor: # the type of sensor has been identified
return type
return None
def get_forecast(self, type_comf, t_data):
"""
If this room data structure has a vector forecast for the "type_comf" in the period t_data, return the
appropriate vector
:param sensor_id: the unique ID of the sensor
:return: the type of comfort associated to sensor_id
"""
(t_cur, t_hor, t_step) = t_data
if type_comf == EMS_COMFORT_temperature and self.name == EMS_OUTSIDE_ROOM_NAME:
data_raw = BMS_MISSING_DATA_ENVIRONMENTAL_SIGNAL['outside_temperature']
sig_object = PiecewiseConstantSignal(data_raw['t'], data_raw['v'])
return sig_object.get_interval_val(t_cur, t_cur+t_hor, t_step)
else:
return int(t_hor/t_step) * [0]
def set_comfort_value(self, value, sensor_id=None, type_comf=None):
"""
Set the comfort value linked to a specific sensor or type of comfort.
:param value : the new comfort value
:param sensor_id [optional]: the ID of the sensor linked to the comfort
:param type_comf [optional]: the type of comfort
:return: sensor_id and type_comf cannot be both undefined
remark:
"""
assert(not(sensor_id is None and type_comf is None)) # cannot both be undefined
if type_comf is None:
type_comf = self.get_comfort_type(sensor_id)
if type_comf is not None: # Now the value can be updated
self.__comfort[type_comf].comfort_value = value
def hasSensor(self, sensor_id, type_comf=None):
"""
return True if this room contains the sensor_id - corresponding to an optional type_comf
:param sensor_id:
:param type_comf:
:return:
"""
if type_comf is None:
list_comfort = self.__comfort.keys()
else:
list_comfort = [type_comf]
for type in list_comfort:
if self.__comfort[type] is not None and sensor_id == self.__comfort[type].sensor: # the type of sensor has been identified
return True
return False
def set_comfort_constraint(self, type_comf, constr):
"""
Set the comfort constraint linked to a specific type of comfort
:param type_comf: the type of comfort
:param constr: the comfort constraint to set
:return: /
"""
self.__comfort[type_comf].comfort_constraints = constr
def has_interface_with(self, neighbor, type_interface = None):
if neighbor in self.__interface.keys():
if type_interface is None:
return True
else:
if type_interface == EMS_INTERFACE_WINDOW and type(self.__interface[neighbor]) is WindowInterface:
return True
elif type_interface == EMS_INTERFACE_DOOR and type(self.__interface[neighbor]) is DoorInterface:
return True
elif type_interface == EMS_INTERFACE_WALL and type(self.__interface[neighbor]) is WallInterface:
return True
else:
return False
else:
return False
### GETTER & SETTER ###
@property
def name(self):
return self.__name
@name.setter
def name(self, v):
self.__name = v
@property
def volume(self):
return self.__volume
@volume.setter
def volume(self, v):
self.__volume = v
@property
def surface(self):
return self.__surface
@property
def comfort(self):
return self.__comfort
@property
def interfaces(self):
return self.__interface
@surface.setter
def surface(self, v):
self.__surface = v
@property
def thermal_capa(self):
temp = self.get_comfort_value(EMS_COMFORT_temperature) + VTEMPSENSOR_TEMP_STC # in K
rho_air = RHO_AIR_STC * VTEMPSENSOR_TEMP_STC / temp
return rho_air * AIR_HEAT_CAPA * self.volume
def get_comfort_value(self, type_comfort):
if type_comfort not in self.__comfort or self.__comfort[type_comfort] is None:
return None
return self.__comfort[type_comfort].comfort_value
def get_comfort_constraint(self, type_comfort):
if type_comfort not in self.__comfort or self.__comfort[type_comfort] is None:
return None
return self.__comfort[type_comfort].comfort_constraints
def get_comfort_loads(self, type_comfort):
if type_comfort not in self.__comfort or self.__comfort[type_comfort] is None:
return None
return self.__comfort[type_comfort].loads
def get_solar_heat_gain(self, t_data, irr_pred):
# TODO
(t_cur, t_hor, t_step) = t_data
return int(t_hor/t_step) * [0]
def has_forecast(self, t_data, type_comfort):
"""
Return TRUE if this room data structure has forecast data concerning "type_comfort", for the period indicated by "t_data"
:param t_data:
:param type_comfort:
:return:
"""
# TODO: TEMPORARY :D !!
return self.name == EMS_OUTSIDE_ROOM_NAME
def has_thermalsimu_data(self):
"""
:return: TRUE if this room data structure owns data concerning thermal simulation
"""
# TODO: more complete conditions?
# If there is no indication concerning the room volume, this room is considered out of the simulation model
return self.volume > 0

Event Timeline