Skip to content

Devices#

smart_control.simulator.smart_device #

Library for creating SmartDevices.

A SmartDevice allows for observable and action fields to be defined easily and in an extensible way. SmartDevices are meant to be used by the simulator to produce observations and actions for an RL environment.

Any device that wants to expose observable or action fields should extend the SmartDevice class, supplying the appropriate information to the SmartDevice constructor.

AttributeInfo #

Bases: NamedTuple

PODO containing information about an attribute.

The attribute_name is the literal attribute name of an object. This name will be used with setattr/getattr.

Attributes:

Name Type Description
attribute_name str

Name of the internal attribute.

clazz Type[object]

Class of the attribute.

SmartDevice #

SmartDevice(
    observable_fields: Mapping[str, AttributeInfo],
    action_fields: Mapping[str, AttributeInfo],
    device_type: DeviceType,
    device_id: str,
    zone_id: Optional[str] = None,
)

Represents a SmartDevice which exposes observable/action fields.

Creates SmartDevice.

Parameters:

Name Type Description Default
observable_fields Mapping[str, AttributeInfo]

Fields that will be exposed as observables.

required
action_fields Mapping[str, AttributeInfo]

Fields that will be exposed as actions.

required
device_type DeviceType

Type of device.

required
device_id str

Id of device.

required
zone_id Optional[str]

Which zone the device is in.

None

action_field_names #

action_field_names() -> Sequence[str]

Returns all action field names.

device_id #

device_id() -> str

Returns device id.

device_type #

device_type() -> smart_control_building_pb2.DeviceInfo.DeviceType

Returns device type.

get_action_type #

get_action_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the action field.

required

get_observable_type #

get_observable_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the observable field.

required

get_observation #

get_observation(
    observable_field_name: str, observation_timestamp: Timestamp
) -> Any

Returns the value of an observable field.

Parameters:

Name Type Description Default
observable_field_name str

Name of the observable field.

required
observation_timestamp Timestamp

validity time of the observation.

required

Raises:

Type Description
AttributeError

If requested field was not declared observable or does not

observable_field_names #

observable_field_names() -> Sequence[str]

Returns all observable field names.

set_action #

set_action(
    action_field_name: str, value: Any, action_timestamp: Timestamp
) -> None

Sets an action field with a given value.

Parameters:

Name Type Description Default
action_field_name str

Name of the observable field.

required
value Any

Value to set action field to.

required
action_timestamp Timestamp

Timestamp of the action

required

Raises:

Type Description
AttributeError

If requested field was not declared action or does

ValueError

If given value is not the declared type.

zone_id #

zone_id() -> Optional[str]

Returns zone_id.

smart_control.simulator.air_handler #

Models an air handler in an HVAC system.

AirHandler #

AirHandler(
    recirculation: float,
    heating_air_temp_setpoint: int,
    cooling_air_temp_setpoint: int,
    fan_differential_pressure: float,
    fan_efficiency: float,
    max_air_flow_rate: float = 8.67,
    device_id: Optional[str] = None,
    sim_weather_controller: Optional[WeatherController] = None,
)

Bases: SmartDevice

Models an air hander with heating/cooling, input/exhaust and recirculation.

Attributes:

Name Type Description
recirculation float

Proportion of air recirculated.

air_flow_rate float

Flow rate produced by fan in m^3/s.

heating_air_temp_setpoint int

Minimum temperature in K until air will need to be heated.

cooling_air_temp_setpoint int

Maximum temperature in K until air will be cooled.

fan_differential_pressure float

Amount of pressure in Pa needed to push air effectively.

fan_efficiency float

Electrical efficiency of fan (0 - 1).

cooling_request_count int

count of VAVs that have requested cooling in this cycle.

max_air_flow_rate float

max air flow rate in kg/s

ambient_flow_rate property #

ambient_flow_rate: float

Returns rate of flow coming from outside.

recirculation_flow_rate property #

recirculation_flow_rate: float

Returns rate of flow from recirculated air.

supply_fan_speed_percentage property #

supply_fan_speed_percentage: float

Returns supply fan speed percentage.

action_field_names #

action_field_names() -> Sequence[str]

Returns all action field names.

add_demand #

add_demand(flow_rate: float)

Adds to current flow rate demand.

Parameters:

Name Type Description Default
flow_rate float

Flow rate to add.

required

Raises:

Type Description
ValueError

If flow_rate is not positive.

compute_exhaust_fan_energy_rate #

compute_exhaust_fan_energy_rate() -> float

Returns power in W consumed by the exhaust fan.

compute_fan_power #

compute_fan_power(
    flow_rate: float, fan_differential_pressure: float, fan_efficiency: float
) -> float

Returns power in W consumed by fan.

Derived from: https://www.engineeringtoolbox.com/fans-efficiency-power-consumption-d_197.html

Parameters:

Name Type Description Default
flow_rate float

Rate of air flow in m^3/s.

required
fan_differential_pressure float

Pressure difference in Pa between fan intake and fan output.

required
fan_efficiency float

Electrical efficiency of fan (0-1).

required

compute_intake_fan_energy_rate #

compute_intake_fan_energy_rate() -> float

Returns power in W consumed by the intake fan.

compute_thermal_energy_rate #

compute_thermal_energy_rate(
    recirculation_temp: float, ambient_temp: float
) -> float

Returns energy in W needed by the air handler to meet supply temp.

Parameters:

Name Type Description Default
recirculation_temp float

Temperature in K of recirculated air.

required
ambient_temp float

Temperature in K of outside air.

required

device_id #

device_id() -> str

Returns device id.

device_type #

device_type() -> smart_control_building_pb2.DeviceInfo.DeviceType

Returns device type.

get_action_type #

get_action_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the action field.

required

get_mixed_air_temp #

get_mixed_air_temp(recirculation_temp: float, ambient_temp: float) -> float

Returns temperature in K of air after recirculation.

Parameters:

Name Type Description Default
recirculation_temp float

Temperature in K of recirculated air.

required
ambient_temp float

Temperature in K of ambient/outside air.

required

get_observable_type #

get_observable_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the observable field.

required

get_observation #

get_observation(
    observable_field_name: str, observation_timestamp: Timestamp
) -> Any

Returns the value of an observable field.

Parameters:

Name Type Description Default
observable_field_name str

Name of the observable field.

required
observation_timestamp Timestamp

validity time of the observation.

required

Raises:

Type Description
AttributeError

If requested field was not declared observable or does not

get_supply_air_temp #

get_supply_air_temp(recirculation_temp: float, ambient_temp: float) -> float

Returns temperature of air output from air handler after A/C or heat.

Temperatures are measured in Kelvin.

Parameters:

Name Type Description Default
recirculation_temp float

Temperature in K of recirculated air.

required
ambient_temp float

Temperature in K of ambient/outside air.

required

observable_field_names #

observable_field_names() -> Sequence[str]

Returns all observable field names.

set_action #

set_action(
    action_field_name: str, value: Any, action_timestamp: Timestamp
) -> None

Sets an action field with a given value.

Parameters:

Name Type Description Default
action_field_name str

Name of the observable field.

required
value Any

Value to set action field to.

required
action_timestamp Timestamp

Timestamp of the action

required

Raises:

Type Description
AttributeError

If requested field was not declared action or does

ValueError

If given value is not the declared type.

zone_id #

zone_id() -> Optional[str]

Returns zone_id.

smart_control.simulator.boiler #

Models a boiler for the simulation.

Boiler #

Boiler(
    reheat_water_setpoint: float,
    water_pump_differential_head: float,
    water_pump_efficiency: float,
    device_id: Optional[str] = None,
    heating_rate: Optional[float] = 0,
    cooling_rate: Optional[float] = 0,
    convection_coefficient: Optional[float] = 5.6,
    tank_length: Optional[float] = 2.0,
    tank_radius: Optional[float] = 0.5,
    water_capacity: Optional[float] = 1.5,
    insulation_conductivity: Optional[float] = 0.067,
    insulation_thickness: Optional[float] = 0.06,
)

Bases: SmartDevice

Models a central boiler with water pump.

Attributes:

Name Type Description
_total_flow_rate

Flow rate of water in m3/s.

reheat_water_setpoint float

Temperature in K that the boiler will maintain.

_water_pump_differential_head float

Length in meters of pump head.

_water_pump_efficiency float

Electrical efficiency of water pump [0,1].

device_code float

unique name of the device.

heating_request_count int

count of VAVs that have requested heat in this cycle.

supply_water_temperature_sensor float

temp [K] of water being supplied to VAVs.

supply_water_setpoint float

setpoint [K] of the supply water.

return_water_temperature_sensor float

temp [K] of return water

heating_rate float

degrees C / minute a boiler can heat

cooling_rate float

degrees C / minute the boiler temp will drop

convection_coefficient float

convection (airflow) loss external to the boiler [W/m^2/K]

water_capacity float

boiler water capacity [m^3]

tank_length float

tank interior length [m]

tank_radius float

tank interior radius [m]

insulation_conductivity float

conductivity of the insulating walls [W/m/K]

insulation_thickness float

thickness of the cylindrical insulating wall [m]

action_field_names #

action_field_names() -> Sequence[str]

Returns all action field names.

add_demand #

add_demand(flow_rate: float)

Adds to current flow rate demand.

Parameters:

Name Type Description Default
flow_rate float

Flow rate to add.

required

Raises:

Type Description
ValueError

If flow_rate is not positive.

compute_pump_power #

compute_pump_power() -> float

Returns power consumed by pump in W to move water to VAVs.

derived from: https://www.engineeringtoolbox.com/pumps-power-d_505.html

compute_thermal_dissipation_rate #

compute_thermal_dissipation_rate(
    water_temp: float, outside_temp: float
) -> float

Returns the amount of thermal loss in W from a boiler tank.

Thermal dissipation is the loss of heat due from the tank to the environment due to imperfect insulation, measured in Watts.

The tank is assumed to be a cylindrical annulus, with an internal radius internal length, and an insulation thickness. Heat is dissapated only through the cylinder walls, and no heat is lost through the ends/caps.

The equation is computed by applying an energy balance of: Q = Q_conduction = Q_convection, where Q_condition is the heat transferred from water at water_temp (T1) to the exterior surface temp (T2), and Q_convection is the transfer of the heat from the external surface at T2 to the outside at T_inf.

Q_conduction = (T1 - T2) / (ln(R2/R1) / 2 x pi x L x k), and Q_convection = (T2 - Tinf) / (1 / h x A), where A = the area of the annulus = 2 x pi x R2 x L

Solving for Q: Q = (T1 - Tinf) / [ln(R2/R1) / 2pi / L / k + 1 / h / A]

Source: Heat Transfer, E. M. Sparrow, 1993

Parameters:

Name Type Description Default
water_temp float

average temperature of the water [K]

required
outside_temp float

temperature outside of the tank, can be ambient [K]

required

Returns:

Type Description
float

thermal loss rate of the tank in Watts

compute_thermal_energy_rate #

compute_thermal_energy_rate(
    return_water_temp: float, outside_temp: float
) -> float

Returns energy rate in W consumed by boiler to heat water.

Parameters:

Name Type Description Default
return_water_temp float

Temperature in K that water is received at.

required
outside_temp float

Temperature in K that the water tank is in.

required

device_id #

device_id() -> str

Returns device id.

device_type #

device_type() -> smart_control_building_pb2.DeviceInfo.DeviceType

Returns device type.

get_action_type #

get_action_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the action field.

required

get_observable_type #

get_observable_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the observable field.

required

get_observation #

get_observation(
    observable_field_name: str, observation_timestamp: Timestamp
) -> Any

Returns the value of an observable field.

Parameters:

Name Type Description Default
observable_field_name str

Name of the observable field.

required
observation_timestamp Timestamp

validity time of the observation.

required

Raises:

Type Description
AttributeError

If requested field was not declared observable or does not

observable_field_names #

observable_field_names() -> Sequence[str]

Returns all observable field names.

set_action #

set_action(
    action_field_name: str, value: Any, action_timestamp: Timestamp
) -> None

Sets an action field with a given value.

Parameters:

Name Type Description Default
action_field_name str

Name of the observable field.

required
value Any

Value to set action field to.

required
action_timestamp Timestamp

Timestamp of the action

required

Raises:

Type Description
AttributeError

If requested field was not declared action or does

ValueError

If given value is not the declared type.

zone_id #

zone_id() -> Optional[str]

Returns zone_id.

smart_control.simulator.hvac #

Models HVAC for simulation.

The model assumes a single boiler and air handler, with one VAV per zone in the building.

Hvac #

Hvac(
    zone_coordinates: List[Tuple[int, int]],
    air_handler: AirHandler,
    boiler: Boiler,
    schedule: SetpointSchedule,
    vav_max_air_flow_rate: float,
    vav_reheat_max_water_flow_rate: float,
)

Model for the HVAC components of the building.

Creates a single boiler and air handler, along with one vav for each zone.

Attributes:

Name Type Description
vavs Mapping[Tuple[int, int], Vav]

Mapping from zone_coordinates to VAV.

air_handler AirHandler

AirHandler

boiler Boiler

Boiler

zone_infos Mapping[Tuple[int, int], ZoneInfo]

information about each zone in the building.

Initialize HVAC.

Parameters:

Name Type Description Default
zone_coordinates List[Tuple[int, int]]

List of 2-tuple containing zone coordinates to service.

required
air_handler AirHandler

the air handler for hte HVAC

required
boiler Boiler

the boiler for the HVAC

required
schedule SetpointSchedule

the setpoint_schedule for the thermostats

required
vav_max_air_flow_rate float

the max airflow rate for the vavs

required
vav_reheat_max_water_flow_rate float

the max water reheat flowrate for the vavs

required

is_comfort_mode #

is_comfort_mode(current_time: Timestamp) -> bool

Returns True if building is in comfort mode.

smart_control.simulator.hvac_floorplan_based #

Models HVAC for simulation post refactor for flexible floorplan geometries.

The model assumes a single boiler and air handler, with one VAV per zone in the building.

FloorPlanBasedHvac #

FloorPlanBasedHvac(
    air_handler: AirHandler,
    boiler: Boiler,
    schedule: SetpointSchedule,
    vav_max_air_flow_rate: float,
    vav_reheat_max_water_flow_rate: float,
    zone_identifier: Optional[List[str]] = None,
)

Model for the HVAC components of the building.

Creates a single boiler and air handler, along with one vav for each zone.

Attributes:

Name Type Description
vavs Mapping[str, Vav]

Mapping from zone_identifier to VAV.

air_handler AirHandler

AirHandler

boiler Boiler

Boiler

zone_infos Mapping[str, ZoneInfo]

information about each zone in the building.

fill_zone_identifier_exogenously

flag to tell simulator to fill the zone coordinates exogenously or not.

Initialize HVAC.

Parameters:

Name Type Description Default
air_handler AirHandler

the air handler for the HVAC

required
boiler Boiler

the boiler for the HVAC

required
schedule SetpointSchedule

the setpoint_schedule for the thermostats

required
vav_max_air_flow_rate float

the max airflow rate for the vavs

required
vav_reheat_max_water_flow_rate float

the max water reheat flowrate for the vavs

required
zone_identifier Optional[List[str]]

List of strings containing zone coordinates to service. If None, then the Simulator which calls the hvac must have a list of rooms that it plans on passing.

None

initialize_zone_identifier #

initialize_zone_identifier(zone_identifier: List[str])

Initializes the zone devices with zone coordinates passed in.

Parameters:

Name Type Description Default
zone_identifier List[str]

list of strings with the room names.

required

is_comfort_mode #

is_comfort_mode(current_time: Timestamp) -> bool

Returns True if building is in comfort mode.

smart_control.simulator.thermostat #

Models a thermostat in the simulation.

The thermostat is given a SetpointSchedule, which defines for any given time the deadband. The SetpointSchedule also determines when the thermostat should operate in Comfort mode or Eco mode.

In Comfort mode, the thermostat can be in one of 3 states. If the temperature goes beneath the heating setpoint, Heat mode is activated until the temperature reaches midway between the 2 setpoints. Similarly, if the temperature is higher than the cooling setpoint, the thermostat enters Cool mode until the mid-point. Otherwise, it enters Off mode.

In Eco mode, there is an additional state, Passive Cool mode. Upon entering Eco mode, the thermostat is initially placed in this state, and remains that way until the temperature cools beyond the eco heating setpoint, upon which the thermostat operates as it did in Comfort mode.

Thermostat #

Thermostat(schedule: SetpointSchedule)

Local thermostat control for each VAV/zone.

Is constructed by passing in a SetpointSchedule, which, for any timestamp, provides heating and cooling setpoints, as well as whether the thermostat should operate in Eco mode/.

Attributes:

Name Type Description
_setpoint_schedule

SetpointSchedule to determine temperature windows.

_previous_timestamp

Last timestamp the thermostat was called with.

_current_mode

Current mode thermostat is in.

Mode #

Bases: Enum

Modes of the thermostat.

Values

OFF: Temperature is within windows and does not need active adjustments. HEAT: VAV is actively heating zone. COOL: VAV is actively cooling zone. PASSIVE_COOL: Building is allowed to cool naturally until within eco mode window.

update #

update(zone_temp: float, current_timestamp: Timestamp) -> Thermostat.Mode

Returns updated mode, allowing passive cool if shifting into eco.

Should be invoked once per iteration of the simulation, after all control volume temperatures have been updated.

Parameters:

Name Type Description Default
zone_temp float

Temperature in k of zone.

required
current_timestamp Timestamp

Pandas timestamp.

required

smart_control.simulator.vav #

Models a Variable Air Volume device for the simulation.

Vav #

Vav(
    max_air_flow_rate: float,
    reheat_max_water_flow_rate: float,
    therm: Thermostat,
    boiler: Boiler,
    device_id: Optional[str] = None,
    zone_id: Optional[str] = None,
)

Bases: SmartDevice

Models a Variable Air Volume device with damper and reheat.

Attributes:

Name Type Description
max_air_flow_rate float

Air flow rate when damper is fully open.

reheat_max_water_flow_rate float

Water flow rate when valve is fully open.

reheat_valve_setting float

Proportion of water the valve is allowing through [0, 1].

damper_setting float

Proportion of air the damper is allowing through [0, 1].

thermostat Thermostat

Thermostat which controls VAV.

boiler Boiler

Boiler supplying hot water to the VAV.

flow_rate_demand float

the flow rate demand

reheat_demand float

the reheat demand

zone_air_temperature float

the average temperature in the zone

action_field_names #

action_field_names() -> Sequence[str]

Returns all action field names.

compute_energy_applied_to_zone #

compute_energy_applied_to_zone(
    zone_temp: float, supply_air_temp: float, input_water_temp: float
) -> float

Returns thermal energy in W to apply to the zone.

Parameters:

Name Type Description Default
zone_temp float

Current temperature in K of the zone.

required
supply_air_temp float

Temperature in K of input air.

required
input_water_temp float

Temperature in K of input water.

required

compute_reheat_energy_rate #

compute_reheat_energy_rate(
    supply_air_temp: float, input_water_temp: float
) -> float

Returns energy consumption in W due to heating the air.

Parameters:

Name Type Description Default
supply_air_temp float

Temperature in K of input air.

required
input_water_temp float

Temperature in K of input water.

required

compute_zone_supply_temp #

compute_zone_supply_temp(
    supply_air_temp: float, input_water_temp: float
) -> float

Returns temperature of air output from the VAV, supplied to the zone.

Temperatures are measured in Kelvin.

Parameters:

Name Type Description Default
supply_air_temp float

Temperature in K of input air.

required
input_water_temp float

Temperature in K of input water.

required

device_id #

device_id() -> str

Returns device id.

device_type #

device_type() -> smart_control_building_pb2.DeviceInfo.DeviceType

Returns device type.

get_action_type #

get_action_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the action field.

required

get_observable_type #

get_observable_type(field_name: str) -> Type[object]

Returns class type expected for field_name.

Parameters:

Name Type Description Default
field_name str

Name of the observable field.

required

get_observation #

get_observation(
    observable_field_name: str, observation_timestamp: Timestamp
) -> Any

Returns the value of an observable field.

Parameters:

Name Type Description Default
observable_field_name str

Name of the observable field.

required
observation_timestamp Timestamp

validity time of the observation.

required

Raises:

Type Description
AttributeError

If requested field was not declared observable or does not

observable_field_names #

observable_field_names() -> Sequence[str]

Returns all observable field names.

output #

output(zone_temp: float, supply_air_temp: float) -> Tuple[float, float]

Returns values corresponding to current output.

Parameters:

Name Type Description Default
zone_temp float

Current temperature in K of zone.

required
supply_air_temp float

Temperature in K of air being supplied to VAV.

required

Returns:

Type Description
Tuple[float, float]

Tuple containing energy to apply to zone and temperature applied to zone.

set_action #

set_action(
    action_field_name: str, value: Any, action_timestamp: Timestamp
) -> None

Sets an action field with a given value.

Parameters:

Name Type Description Default
action_field_name str

Name of the observable field.

required
value Any

Value to set action field to.

required
action_timestamp Timestamp

Timestamp of the action

required

Raises:

Type Description
AttributeError

If requested field was not declared action or does

ValueError

If given value is not the declared type.

update #

update(
    zone_temp: float, current_timestamp: Timestamp, supply_air_temp: float
) -> Tuple[float, float]

Returns values corresponding to current output.

Adjusts the VAV configuration based on thermostat mode.

Parameters:

Name Type Description Default
zone_temp float

Current temperature in K of zone.

required
current_timestamp Timestamp

Pandas timestamp representing current time.

required
supply_air_temp float

Temperature in K of air being supplied to VAV.

required

Returns:

Type Description
float

Tuple containing energy to apply to zone, temperature applied to zone, and

float

flow rate demand.

update_settings #

update_settings(zone_temp: float, current_timestamp: Timestamp) -> None

Adjusts the VAV configuration based on thermostat mode.

Parameters:

Name Type Description Default
zone_temp float

Current temperature in K of zone.

required
current_timestamp Timestamp

Pandas timestamp representing current time.

required

zone_id #

zone_id() -> Optional[str]

Returns zone_id.