building fault diagnosis - cooper union fault diagnosis alexander stephen bush ... was determined by...
TRANSCRIPT
Abstract
Building retuning is the process by which cost-free changes in a building’s operation are
made in order to decrease the building’s total energy consumption. The process is iterative,
time consuming, and requires and intimate knowledge of building systems. For these reasons,
the process will benefit greatly from the automation of some or all parts of the retuning
process. Large commercial buildings are the focus of this project, and a university building, 41
Cooper Square, is used as a case study for the testing of this automation. Software is written
which analyzes the performance of an air handler unit and provides and automated diagnosis of
building faults.
Introduction
Minimizing a commercial building’s energy usage is an issue which is often dealt with at
the beginning of a building’s life cycle, during the design phase. However, the importance of the
issue can sometimes be slowly forgotten throughout the building’s operation. This manifests
itself as a steadily upward creeping cost of building operation. Obviously, mission critical
failures will result in the replacement of certain failing aspects of a building. However, these
catastrophic failures are naught but the result a late diagnosis of the issues which can plague a
building. In many cases, refining the operation of a building can reduce the load on the
mechanical systems of a building, resulting in a much longer lifetime for the building as a whole,
while simultaneously reducing the cost of building operation.
Those who are directly responsible for minimizing the operation costs of a building are
usually not the same people who are in the most practical position to fix the issues which cause
the building to operate below its design point. Building engineers’ first priority is to keep the
indoor environment safe and comfortable. The primary method for prioritizing daily tasks is the
influx of occupant complaints. Maintaining happy and healthy building occupants is a time
consuming process, and often leaves little room for monitoring building efficiency. To this end,
in order to allow building engineers the ability to focus on building energy usage, the process
must be made less time consuming and more straightforward. The building engineers need
tools which can assist them in monitoring and evaluating the building’s performance.
Delegating this analysis to a computer will allow building engineers to maximize field work time,
reducing the time commitment, yet still allow engineers to nip problems in the bud, before they
lead to occupant complaints, safety hazards, or mechanical failures.
The purpose of this project is to develop a methodology, and the accompanying
software tools, to assist a building operator in the diagnosis and prioritization of building energy
usage issues. This methodology is broken down by building system(Boilers, Chillers, AHUs, etc.)
and takes advantage of an existing sensor infrastructure in order to analyze the building’s
performance and suggest energy saving modifications.
Problem Statement
The goal of this project is to develop tools for building retuning which can facilitate the
monitoring and verification of building data, increase energy efficiency, and reduce operation
cost.
Methodology
The methodology consists of 6 main steps: Data Collection, Report Generation, Sensor
Verification and Repair(recollect data as necessary), Data Analysis, Implementation, and
Monitoring and Verification.
Step one is the deployment of sensors in order to determine the current operation of
the building. These sensors can be self-contained data loggers, or they can be integrated with
the building management system(BMS). The aim is to collect data from a variety of sensors over
a period of time in order to be able to determine current building operation.
Once the data is being collected, periodic reports should be created. These reports will
contain recent and relevant data in a format which is easily analyzed. An example of a report is
a csv file which contains the date, time and values for all the sensors related to a specific
system.
Before the data can be analyzed and energy saving measures can be determined, the
sensor data must be verified. Sensor data which is indicative of impossible building operation
can be used to diagnose sensor failures. These faulty sensors can then be recalibrated,
repaired, or replaced. For example, a humidity sensor with a negative value is a failed sensor.
Once the sensors have been verified, the data can be recollected. Data only needs to be
recollected if sensor hardware was replaced or recalibrated. Once all of the sensor data is
collected and verified to be true, the data can then be analyzed. This analysis can be done
manually. Often, BMS systems include graphing capabilities, which can be used to search for
energy wasting building operations. This step is one of the most tedious and time consuming
tasks, as it involves poring over large amounts of data, searching for hidden errors and patterns
which would be indicative of poor building operation. In addition, this step requires an operator
with an intimate knowledge of the entire building. Automation of this step can be extremely
beneficial for finding possible energy saving changes. In addition, energy savings and monetary
savings of proposed changes can be calculated, in order to gauge the effect on the building. The
predicted energy savings can also be used to prioritize building operation modifications.
The next step is implementation. The building schedule can be adjusted in order to
affect the building’s operation.
Of course, the process can be iterated multiple times, at regular intervals, in order to
keep the building operation from degrading. During this process, a solid monitoring and
verification plan should be in place, so that the benefits and savings can be quantified, and
errors can be minimized.
Over the course of this project, in order to minimize the time required to search for
building energy usage faults, automation of certain steps is implemented, through the use of a
Matlab script.
Air Handler Case Study
In order to test this methodology, the air handlers of 41 Cooper Square are used as a
case study. However, before integrating automated retuning, the current air handler operation
was determined by reading the ppcl(Powers Process Control Language) code which controls air
handler operation. From the code, a series of visual representations of the algorithm was
created, with the goal of verifying current operation. These slides are shown in APPENDIX
SOMETHING.
In order to begin automated retuning, data is collected from the building management
system(BMS) computer. This is done by setting up the built-in trending capability of the BMS
software. 33 individual points are trended at 15 minute intervals. Trending means that the BMS
will record the value of each data point at regular intervals. The following pages discuss in detail
the steps required to use the Matlab script in order to analyze the air handler.
Air Handler w/Economizer Retuning Guide(featuring AHUanalyzer.m):
Step 1: Trend points using Building Management System(BMS) software. Examples of BMS
point names for Siemens Insight points shown in parentheses.
Points to Trend for Fault Diagnosis(shown in red):
- Supply Temperature (41CS.RF.AH04.SUP.TEMP)
- Supply Temperature Setpoint (41CS.RF.AH04.SUP.TEMP.STPT)
- Heating Coil Valve Position (41CS.RF.AH04.HCOIL.VLV)
- Cooling Coil Valve Position (41CS.RF.AH04.CCOIL.VLV)
- Supply Static Pressure (41CS.RF.AH04.STATIC)
- Supply Static Pressure Setpoint (41CS.RF.AH04.HI.STATIC.STPT)
- Zone Damper Positions (41CS.303.VAV.301:SUP DMP CMD)
- Zone Temperatures (41CS.508.VAV.408:ROOM TEMP)
- Zone Temperature Setpoints (41CS.405.SAV.404:ROOM STPT)
Points to Trend for Energy Savings Estimation(shown in green):
- Mixed Air Temperature (41CS.RF.AH04.MIX.TEMP)
- Air Temperature after the Heating Coil (41CS.RF.AH04.HCOIL.TEMP)
- Air Temperature after the Cooling Coil (41CS.RF.AH04.CCOIL.TEMP)
- Supply Flow CFM (41CS.RF.AH04.SUP.FLOW)
- Supply Fan Energy Usage (41CS.RF.AH04.kW)
- Building Occupation Level
.
Step 2: Utilize Building Management Software to create a report. Schedule report for automatic
weekly data collection. If the software functionality exists, the report can be automatically
emailed as a comma separated value(.csv) file.
Points to Trend for Fault Diagnosis Points to Trend for Energy Estimation
Step 3: Run the AHUanalyzer Matlab script. This Matlab script will prompt the user to import
the csv file. The Matlab script will output a series of graphs and messages.
In addition to identifying humidity sensors which read negative values, the MATLAB script also
identifies possible changes in the air handler operation which can result in energy consumption
decreases. The program answers six basic building retuning questions. These questions are
discussed on the following pages:
Retuning Question #1: Is reset being used to control the discharge-air temperature setpoint?
Explanation: The discharge-air temperature requires energy from the heating and cooling coils
to maintain. During unoccupied building operation, the discharge-air setpoint can be allowed to
float within a wider margin, consuming less energy.
Pseudocode:
Alert user if discharge air temperature setpoint never changes.
Example:
The difference between any two
sequential data points of the Supply
Temperature Setpoint(green line) is zero
in all cases. Therefore, it can be
concluded that there are no supply
temperature setbacks.
Potential Energy Savings:
Hc = Heating Coil Temperature(°F)
Cc = Cooling Coil Temperature(°F)
M = Mixed Air Temperature(°F)
CFM = Supply Air Flow(ft3/min)
Cp = Specific Heat of Air(0.5861 kg/btu/°F)
ρ = density of air(0.03612 kg/ft3)
∫ ( )
Retuning Question #2: Is the discharge-air meeting set point, or do deviations occur?
Explanation: If the discharge-air temperature is not able to meet the setpoint, there are a few
possible explanations. The discharge-air setpoint could be improperly set. Any number of AHU
control points could be in operator override. A damper could be stuck. If the discharge-air is not
able to meet the setpoint, further investigation is required to determine the source of the
problem.
Pseudocode:
If Temp Error > 2 degrees, Alert user.
Example:
The aggregated difference between the
Supply Temperature(Red) and the
Supply Temperature Setpoint(Green) is a
difference of 5.5 °F. This is above the
threshold of 2 °F, therefore it can be
concluded that something is hindering
the building’s ability to regulate the
Supply Temperature.
Retuning Question #3: Are set points too high or too low; discharge-air temperature too warm
or too cold?
Explanation: If the discharge air temperature is too warm, then the zone temperature could be
too warm for comfort in certain parts of the building. Other parts of the building will then waste
energy to re-cool the air. If the discharge-air temperature is too cold, then there will be
significant waste in reheating the air.
Pseudocode:
HeatFaultCounter = # of instances where sup temp is greater than 60°F
ColdFaultCounter = # of instances where sup temp is less than 50°F
If Heat Fault Counter > 0, alert user.
If Cold Fault Counter > 0, alert user.
Example: The Supply
Temperature(Red) rises above 60°F at
least once. This behavior triggers the
program to throw a flag.
Potential Energy Savings:
T = Discharge Air Temperature(°F) Cp = Specific Heat of Air(0.5861 kg/btu/°F)
ρ = density of air(0.03612 kg/ft3) CFM = Supply Air Flow(ft3/min)
∫| |
Retuning Question #4: Do the discharge-air temperatures remain relatively stable?
Explanation: If the discharge-air temperatures are not stable, then it is indicative of an error
within the control algorithm. This type of error can also indicate that the discharge-air
temperature is improperly set.
Pseudocode:
If Temp Error > 2 degrees, Alert user.
Example: The aggregated slope of the
Supply Temperature(Red) is 20°F/min.
This value is above the threshold of
2°F/min, therefore it can be concluded
that something causing excessive Supply
Temperature variation.
Retuning Question #5: Is there simultaneous heating and cooling occurring in the AHU?
Explanation: Simultaneous heating and cooling should only be used for dehumidification
purposes. Otherwise, simultaneous heating and cooling is a waste of boiler and chiller energy.
Pseudocode:
If (Heating Coil ≠ 0 AND Cooling Coil ≠ 0 AND outside humidity<humidity setpoint),
Then Alert User
Example: The Heating Valve(Dark Orange) and the Cooling Valve(Orange) are never open at the
same time. This is desirable behavior.
Potential Energy Savings:
Hc = Heating Coil Temperature(°F) Cc = Cooling Coil Temperature(°F)
M = Mixed Air Temperature(°F) T = Discharge Air Temperature(°F)
CFM = Supply Air Flow(ft3/min)
Cp = Specific Heat of Air(0.5861 kg/btu/°F)
ρ = density of air(0.03612 kg/ft3)
∫ ( )
∫| |
Retuning Question #6: Is there a reset-schedule for the duct static pressure?
Explanation: The duct static pressure can be allowed to float during unoccupied times, as
ventilation and temperature load decreases heavily. This will potentially allow for the greatest
savings, as the duct static pressure directly relates to the fan speed.
Pseudocode:
Alert user if Discharge Static Pressure Setpoint is constant.
Potential Energy Savings:
( ) ∫ ( )
This graph is generated using empirical data. The raw data for this graph is shown in the
following table:
Supply Fan Energy Usage vs. Supply Air Flow
Fan Energy (kW) 0 5.6 15.49 18.59 22.19 31.79
Fan Speed (%) 0 60 78.80 83.80 88.83 100
Fan Flow (CFM) 0 17820 23404 24889 26383 29700
Retuning Question #7: Is the supply air static pressure too high?
Explanation: The supply air static pressure can be regulated by adjusting the zone dampers, or
by changing the supply fan speed. Increasing the supply fan speed requires a significant
increase in energy consumption, while opening the zone dampers requires a negligible amount
of energy. Therefore, it is considered better operation to have the zone dampers mostly open,
while the fan runs at a minimum speed.
Pseudocode:
If: 60<Average Damper Position<80, this indicates good operation.
Else: Alert User.
Example: The dampers vary
over a wide range. The
average damper position is
50%. This is moderately
desirable behavior, but it
could be slightly improved
to 70%.
In addition to the message box, the graph of the data which is being used to answer these
questions is shown:
There is also a pair of graphs which compare temperature economization with enthalpy
economization. The line labelled “Free Cooling” represents when conditions are favorable for
using outside air. When “Free Cooling” is high, then outside air can be mixed into the return air.
When “Free Cooling” is low, then mixing outside air into the supply would be inefficient.
The following flowchart can be used to determine the amount of energy used by the air handler
unit to treat the air. There are three possible paths of energy usage. There is a heating coil, a
cooling coil, and a reheat coil. If the air is too cold, the heating coil will heat the air to the correct
temperature. If the air is too hot and/or too humid, then the cooling coil will cool the air to the
correct temperature. Then the cooling coil will cool the air to the required temperature for
dehumidification. Then, the reheat coil reheats the air to the setpoint temperature.
Mixed Air
𝐻𝑒𝑎𝑡𝑖𝑛𝑔 𝐸𝑛𝑒𝑟𝑔𝑦
∫ |55 𝐹 𝑀| 𝐶𝑝 𝐶𝐹𝑀 𝜌 𝑑𝑡
𝐶𝑜𝑜𝑙𝑖𝑛𝑔 𝐸𝑛𝑒𝑟𝑔𝑦
∫ |𝑀 55 𝐹| 𝐶𝑝 𝐶𝐹𝑀 𝜌 𝑑𝑡
>55°F
<55°F
𝐷𝑒ℎ𝑢𝑚𝑖𝑑𝑖𝑓𝑦 𝐸𝑛𝑒𝑟𝑔𝑦
∫ |𝑀 4 𝐹| 𝐶𝑝 𝐶𝐹𝑀 𝜌 𝑑𝑡
𝑅𝑒ℎ𝑒𝑎𝑡 𝐸𝑛𝑒𝑟𝑔𝑦
∫ |55 𝐹 4 𝐹| 𝐶𝑝 𝐶𝐹𝑀 𝜌 𝑑𝑡
>60% RH <60% RH
Supply Air
The equations used in the flowchart are implemented in the program. As a case study, the
program analyzed a time span of three spring weeks for average energy usage, based on the
currently implemented enthalpy economization. This energy usage is compared with the
projected energy usage based temperature economization. The temperature economization
projected lower energy usage during all three weeks. Further case studies based on different
types of weather should be analyzed in order to determine when it is beneficial to use enthalpy
economization, and when it is beneficial to use temperature economization.
0 50000000 100000000 150000000 200000000
Feb29-Mar6
Mar7-Mar13
Mar14-Mar20
btu/week
Enthalpy vs Temperature Economization
Enthalpy
Temp
Economization: The purpose behind an economizer is to minimize the amount of energy
required to generate usable supply air. It does this by mixing the outside air and the return air.
The following figure shows the relative amount of energy required to generate usable supply air
at 55F and less than 60%RH.
The most energy is required when the mixed air is hot and humid. The least energy is required
when the mixed air already meets the temperature and relative humidity setpoints. Notice the
discontinuity within the energy function. This discontinuity is due to the energy required to
dehumidify the air by overcooling and reheating.
Sample Energy Calculation:
Given:
Outside Air: relative humidity = 60%, outside air temperature = 70F
Setpoint: relative humidity < 60%, supply air temperature = 55F
Find: Energy per minute required to make outside air meet setpoint.
Step 1: Use a Mollier diagram in order to determine if dehumidification is necessary. Based on
the diagram, the grains of moisture per pound of dry air of the setpoint is about 40. The outside
air, however, is about 65 grains/lb. This difference indicates that dehumidification is in order.
https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Mollier.pdf/page1-1275px-Mollier.pdf.jpg
Step 2: Since the air is too warm, it must be cooled. In addition, because dehumidification is
necessary, it must be cooled even further. At 42F and 100%RH, the air will contain the desired
water content of 40 grains/lb. The energy required to cool the air from 70F to 42F can be
calculated with the following equation:
| |
Where Cp is the specific heat of air, CFM is the volumetric flow rate of the air, and is the
density of the air.
|7 4 | 586
5
6
9 64
Step 3: After the air is dehumidified, it must be reheated to meet the setpoint temperature:
| |
|55 4 | 586
5
6
76
Step 4: Combine heating and cooling energy costs.
76
9 64
4
Conclusion
The Matlab script created in this project provides a proof of concept of automated
building retuning. Building upon existing automated data collection abilities of modern building
management systems, and entirely automated retuning analysis system is not only feasible and
practical, but also provides large long term monetary and time savings for buildings and
building operators.
In the future, the Matlab script can be expanded to be able to handle more building
retuning questions, and the script will be applied to other core areas of building retuning, such
as the chillers, boilers, interior zones, and cogeneration. In addition, as more data is collected, a
more detailed study of the benefits and detriments of enthalpy economization and
temperature economization can be conducted.
References
S. T. Taylor. “Why Enthalpy Economizers Don’t Work”. ASHRAE Journal, November 2010.
S. T. Taylor. “Sizing VAV Boxes”. ASHRAE Journal, March 2004.
M. Hydeman, et all. “Advanced Variable Air Volume System Design Guide”. California Energy Commission. October 2003.
DJ. Taasevigen, et all. “User’s Guide to Energy Charting and Metrics plus Building Re-tuning and Measurement and Verification”. US Department of Energy. Pacific Northwest National Laboratory. June 2013.
“Large Commercial Buildings: Re-tuning for Efficiency”. Pacific Northwest National Laboratory. January 2012. “APOGEE Insight-Basse Workstation” SIEMENS. June 2007.
N. Fernandez et all.“Energy Savings Modeling of Standard Commercial Building Re-tuning Measures: Large Office Buildings”. Pacific Northwest National Laboratory. June 2012.
Rodriguez, Jonathan O. "Technical and Economic Assessment of a Cogeneration System in an Urban Academic Building." Thesis. The Cooper Union, 2014. Print.
Appendix A: Navigating the BMS software
In this tutorial, you will learn to navigate the graphics window and check if a point is being
trended.
Log on to the BMS computer
1. Select Start -> All Programs -> Accessories -> Remote Desktop Connection
2. Enter IP Address: 199.98.16.168
3. Enter User ID: readonly2 and password: readonly2. (you are now remotely logged on the
BMS computer)
4. Click Insight icon on desktop
4a. If Insight does not open, it may already be open, so click the Graphics icon on the upper
control panel
5. Click the picture of the Academic Building.
6. Click “Air Systems” to open the list of air handlers.
7. Click “AH04” to select air handler number four. Alternatively, click the back arrow in order to
return to the previous screen.
8. Hover the cursor over the data point for the outside air damper. Notice the yellow box which
appears. This box contains the name of the point, a description of the point, the status of the
point, the priority of the point(“NONE” is normal operation, “OPER” is operator override, “OVRD”
is an automatic building system override.), the current value of the point, the ex-state, and total.
9. Drag the point to the Trend Definition Editor icon.
This will open the Trend Definition Editor and
automatically select the Outside Air Damper point. Notice
that the point is already being trended in fifteen minute
intervals and also five minute intervals.
10. Opening the Trend Definition Editor simply by clicking the icon will allow a user to manually
select a point to begin trending. By selecting “File”->”New”, the user can then manually browse
to a point which can be selected for trending. This will bring up the Object Selector Window:
Object selector tips:
a. The system queries the database for variable names every time “Find now” is clicked.
b. If you typed a query and don’t appear to have any variables when you think you should,
do a query for “*”. If you see the folder called “trended points”, enter that folder and re-enter
your query.
c. To select more than one variable
at once, hold ctrl while clicking on the
second and subsequent variable
names.
d. “*” is a wildcard placeholder and
can be used in place of any unknown
number of unknown letters or symbols
in the search bar.
e. “?” is also a wildcard, but will
only represent a single unknown letter
or symbol.
11. Alternatively, The trending wizard can be used. This will walk the user through the process
of selecting points to trend and also set up a report at the end.
7. Once the points have been trended, they can then be compiled into a report. To do this,
select Report Builder.
In the Trend Points section, click Configure -> Add in order to select the points to add to the
report. In the Output section, click Configure to set the output of the report to a csv file. Click the
… in order to select the location where the file will be saved. Be sure to save the report before
running it by clicking the floppy disk icon. Saving a report requires admin access.
8. Once a Report has been created, it can be run at any time using the Report Viewer.
.
9. In order to automate the process of running a report, use the Scheduler. Click Schedule ->
Report in order to set up an automatic schedule which will run the report at regular intervals.
This requires admin access.
12. IMPORTANT: In order to end the session, it is imperative that the Insight software is closed.
This will free up a license for others to use. Close the software by rightclicking on the blank
space of the Insight toolbar and selecting “Exit”.
Appendix C: MATLAB Code Temperature vs Enthalpy 3D Graph Generator: clear all close all clc
testTemp = [0:1:100]; testHumid = [0:1:100]; energy = zeros(100,100); %t,h
cpAir = 0.5861; %btu/(kg*F) airDensity = 0.03612; %kg/ft^3 supplyFlow = 50; setPoint = 55;
%relHumidity = 60 temp2check = [40,45,50,55,60,65,70,75,80,85,90,95,100,105,110]; allowableRH = [105,90,75,60,51,42,37,31,26,22,19,17,14,12,10]; polyRHcheck = polyfit(temp2check,allowableRH,3); x = linspace(55,110); y = polyval(polyRHcheck,x); plot(x,y) title('allowable relative humidity') xlabel('temperature') ylabel('maximum RH')
for t = 1:length(testTemp) for h = 1:length(testHumid) if(testTemp(t)<setPoint &&
testHumid(h)<polyval(polyRHcheck,testTemp(t))) %heat without dehumid heatingEnergy = ((setPoint-
testTemp(t))*cpAir*supplyFlow*airDensity); %btu/min energy(t,h) = heatingEnergy; %btu/min elseif(testTemp(t)>=setPoint &&
testHumid(h)<polyval(polyRHcheck,testTemp(t))) %cool without dehumid coolingEnergy = ((testTemp(t)-
setPoint)*cpAir*supplyFlow*airDensity); %btu/min energy(t,h) = coolingEnergy; %btu/min else %cool/heat with dehumid dehumidifyEnergy = ((testTemp(t)-
42)*cpAir*supplyFlow*airDensity); %btu/min reheatEnergy = ((setPoint-42)*cpAir*supplyFlow*airDensity);
%btu/min energy(t,h) = dehumidifyEnergy+reheatEnergy; %btu/min end end end
figure surf(testTemp,testHumid,energy) ylabel('temp (F)')
Air Handler Unit Analyzer: close all clc
button = questdlg('Import a new csv file?'); if strcmp(button,'Yes') clear all button = 'Yes'; [filename1, pathname] = uigetfile('*.csv', 'Select CSV file:'); if (isequal(filename1,0) | isequal(filename1,0)), error('Must provide file or disable the option in "builddr.m" program
file'); return; end end global bmsData; bmsData =
readtable([pathname,filename1],'Delimiter',',','ReadVariableNames',false);
wb = waitbar(0.01,'gathering variable names');
% figure out which points correspond to which variable name. j = 1; for i = 1:height(bmsData) if strncmp(bmsData{i,1},'Point',5) if strncmp(bmsData{i+1,1},'Point',5) break; end bmsDataHeaders(j,1) = bmsData{i,1}; bmsDataHeaders(j,2) = bmsData{i+1,1}; j=j+1; end end
waitbar(0.05,wb,'parsing csv file')
%% %csv2cell if strcmp(button,'Yes')
filename = [pathname,filename1]; fid = fopen(filename); text = char(fread(fid))'; fclose(fid); % First split it into lines lines = regexp(text,'(\r\n|[\r\n])','split'); % lines should now be a
cell array of text split by newlines
% a character is either a delimiter or a field inField = true; inQuoteField = false;
% if inField && ~inQuoteField --> then we're in a raw field
skipNext = false; data = {}; field = ''; for lineNumber = 1:length(lines) nChars = length(lines{lineNumber}); % number of characters in this
line fieldNumber = 1; for charNumber = 1:nChars if skipNext skipNext = false; continue end thisChar = lines{lineNumber}(charNumber); if thisChar == ',' if inField if inQuoteField % this comma is part of the field field(end+1) = thisChar; else % this comma is the delimiter marking the end of the
field data{lineNumber,fieldNumber} = field; field = ''; fieldNumber = fieldNumber + 1; end else % we are not currently in a field -- this is the start
of a new delimiter inField = true; end if charNumber == nChars % this is a hanging comma, indicating
the last field is blank data{lineNumber,fieldNumber} = ''; field = ''; fieldNumber = fieldNumber + 1; end elseif thisChar == '"' if inField if inQuoteField if charNumber == nChars % it's the last character, so
this must be the closing delimiter? inField = false; inQuoteField = false; data{lineNumber,fieldNumber} = field; field = ''; fieldNumber = fieldNumber + 1; else if lines{lineNumber}(charNumber+1) == '"' % this
is translated to be a double quote in the field field(end+1) = '"'; skipNext = true; else % this " is the delimiter ending this field data{lineNumber,fieldNumber} = field; field = ''; inField = false; inQuoteField = false; fieldNumber = fieldNumber + 1; end
end else % this is a delimiter and we are in a new quote
field inQuoteField = true; end else % we are not in a field. This must be an opening quote
for the first field? inField = true; inQuoteField = true; end else % any other character ought to be added to field field(end+1) = thisChar; if charNumber == nChars data{lineNumber,fieldNumber} = field; field = ''; fieldNumber = fieldNumber + 1; elseif charNumber == 1 % we are starting a new raw field inField = true; end end end end bmsData2 = data;
%endcsv2cell %% waitbar(0.10,'removing empty cells')
%find where data starts for y = 1:size(bmsData2,1) if strcmp(bmsData2(y,1),'Report Timings:') dataStarty = y; end end
replaced = 0; breakout = 0; for y = dataStarty:size(bmsData2,1) for x = 1:size(bmsData2,2) for k = 1:size(bmsDataHeaders,1) if strcmp(strcat(bmsData2(y,x),':'),bmsDataHeaders(k,1)) bmsData2(y,x) = bmsDataHeaders(k,2); replaced = replaced + 1; end if replaced == size(bmsDataHeaders,1) breakout = 1; break; end end if breakout == 1; break; end end if breakout == 1; break;
end end
for y = 1:size(bmsData2,1) for x = 1:size(bmsData2,2) if(ischar(bmsData2{y,x}) == 1) bmsData2(y,x) = strrep(bmsData2(y,x), '<', ''); bmsData2(y,x) = strrep(bmsData2(y,x), '>', ''); bmsData2(y,x) = strrep(bmsData2(y,x), 'MIN OA', '0'); bmsData2(y,x) = strrep(bmsData2(y,x), 'FREE CLG', '1'); bmsData2(y,x) = strrep(bmsData2(y,x), 'No Data', 'NaN'); bmsData2(y,x) = strrep(bmsData2(y,x), 'Data Loss', 'NaN'); end if(strncmp(bmsData2{y,x},'41CS',4)) bmsData2{y,x} = strcat('x',bmsData2{y,x}); bmsData2(y,x) = strrep(bmsData2(y,x), '-', '_'); bmsData2(y,x) = strrep(bmsData2(y,x), '.', '_'); bmsData2(y,x) = strrep(bmsData2(y,x), ':', '_'); bmsData2(y,x) = strrep(bmsData2(y,x), ' ', '_'); end end end end
bmsData3 = bmsData2((size(bmsDataHeaders,1)+7):(size(bmsData2,1)-1),:); bmsData3(:,3:size(bmsData3,2)) =
cellfun(@str2num,bmsData3(:,3:size(bmsData3,2)),'UniformOutput',0); bmsData = cell2table(bmsData3); bmsData.Properties.VariableNames = bmsData2((size(bmsDataHeaders,1)+6),:);
global dates; dates = zeros(height(bmsData),1); hAndC = zeros(height(bmsData),1);
for k = 1:height(bmsData) dates(k) = datenum([char(bmsData{k,1}),'
',char(bmsData{k,2})],'mm/dd/yyyy HH:MM:SS'); end
waitbar(0.20,wb,'wasting time')
global avgFan; avgFan = sum(bmsData.x41CS_RF_AH04_SPEED); avgFan = avgFan/height(bmsData);
global avgStaticPressure; avgStaticPressure = sum(bmsData.x41CS_RF_AH04_HI_STATIC_STPT); avgStaticPressure = avgStaticPressure/height(bmsData);
for y = 1:height(bmsData)
ARG4 = 273.16 / ((bmsData.x41CS_RF_AH04_SUP_TEMP(y) - 32.0) / 1.8 +
273.16); ARG4 = -(10.79586) * (1.0 - ARG4) - 2.1836 * log(ARG4) + 2.219598; ARG4 = 29.9 * (1.0 / exp(2.3026 * ARG4)); ARG4 = bmsData.x41CS_RF_AH04_SUP_HUMID(y) * ARG4 / 100; ARG4 = 0.622 * ARG4 / (29.0 - ARG4); SUP_ENTHALPY(y) = (0.24 + 0.45 * ARG4) *
bmsData.x41CS_RF_AH04_SUP_TEMP(y) + 1061 * ARG4; end
for y = 1:height(bmsData) if bmsData.x41CS_RF_AH04_SUP_HUMID(y) < 0 NEGATIVE_HUMIDITY = 1 end end
waitbar(0.30,wb,'determining allowable relative humidity')
%relHumidity = 60 temp2check = [55,60,65,70,75,80,85,90,95,100,105,110]; allowableRH = [60,51,42,37,31,26,22,19,17,14,12,10]; polyRHcheck = polyfit(temp2check,allowableRH,3); x = linspace(55,110); y = polyval(polyRHcheck,x); figure plot(x,y) title('allowable relative humidity') xlabel('temperature') ylabel('maximum RH')
waitbar(0.40,wb,'temperature economization anlysis')
%temperature economization cpAir = 0.5861; %btu/(kg*F) airDensity = 0.03612; %kg/ft^3 heatingEnergy = 0; coolingEnergy = 0; dehumidifyEnergy = 0; reheatEnergy = 0; tempEnergy = 0; %FORGOT TO ADD DEHUMIDIFICATION CHECK
for y = 1:height(bmsData) oa = abs(bmsData.x41CS_RF_AH04_SUP_TEMP(y) -
bmsData.x41CS_RF_OA_TEMP(y)); ret = abs(bmsData.x41CS_RF_AH04_SUP_TEMP(y) -
bmsData.x41CS_RF_AH04_RET_TEMP(y)); % TEMPECON(y+1) = TEMPECON(y) + 1; if oa-ret < 0 TEMPECON(y) = 1; %outside air heatingEnergy = ((55-
bmsData.x41CS_RF_OA_TEMP(y))*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensi
ty); %btu/min coolingEnergy = ((bmsData.x41CS_RF_OA_TEMP(y)-
55)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity); %btu/min
dehumidifyEnergy = ((bmsData.x41CS_RF_OA_TEMP(y)-
42)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity); %btu/min reheatEnergy = ((55-
42)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity); %btu/min tempEnergy = tempEnergy + (heatingEnergy + coolingEnergy +
dehumidifyEnergy + reheatEnergy)*15; %btu else TEMPECON(y) = 0; %inside air heatingEnergy = ((55-
bmsData.x41CS_RF_AH04_RET_TEMP(y))*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*ai
rDensity); %btu/min coolingEnergy = ((bmsData.x41CS_RF_AH04_RET_TEMP(y)-
55)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity); %btu/min dehumidifyEnergy = ((bmsData.x41CS_RF_AH04_RET_TEMP(y)-
42)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity); %btu/min reheatEnergy = ((55-
42)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity); %btu/min tempEnergy = tempEnergy + (heatingEnergy + coolingEnergy +
dehumidifyEnergy + reheatEnergy)*15; %btu end end %btu $ conversion tempEnergyDollars = tempEnergy*(3/1000000); tempEnergy = tempEnergy/1000000;%convert to million btu output11 = ['energy used during TEMPERATURE Economization: '
num2str(round(tempEnergy)) ' million btu/week = $'
num2str(round(tempEnergyDollars))];
%% %energy usage humidityRatio = zeros(height(bmsData),1); %kilograms water vapor per kilogram
of dry air mySupEnthalpy = zeros(height(bmsData),1); for y = 1:height(bmsData) if TEMPECON(y) == 1 % kg / kmol, molar mass of water vapor % divided by c = 18.0152 / 28.9644; % kg / kmol, molar mass of dry air
P = 101325; RH = bmsData.x41CS_RF_OA_HUMID(y); T = (bmsData.x41CS_RF_OA_TEMP(y)+459.67)*(5/9); temp = 54.842763 - 6763.22 ./ T - 4.210 .* log(T) + 0.000367 .* T ... + tanh( 0.0415 * (T - 218.8) ) ... .* (53.878 - 1331.22 ./ T - 9.44523 .* log(T) + 0.014025 .* T); es = exp(temp); e = RH./100 .* es;
Pd = P - e; humidityRatio(y) = (e./Pd) .* c; %kg/kg humidityRatio(y) = humidityRatio(y)*1000; %g/kg
tempC = (bmsData.x41CS_RF_AH04_SUP_TEMP(y)-32)*(9/5); mySupEnthalpy(y) =
(1010*tempC)+((humidityRatio(y)/1000)*(1840*tempC+2502)); %J/kg
mySupEnthalpy(y) = mySupEnthalpy(y)*0.00043; %BTU/lb end end
%% %BASAT questions
waitbar(0.50,wb,'answering BASAT questions')
%Is reset being used to control the discharge-air set point? energySaved1 = 0; energySaved2 = 0; tempChange = 0; for y = 1:(height(bmsData)-1) if isnan(bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(y)) == 0 &&
isnan(bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(y+1)) == 0 tempChange = tempChange + (bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(y)-
bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(y+1)); end %energyCalc tempDiff1 = ((2*bmsData.x41CS_RF_AH04_HCOIL_TEMP(y))-
bmsData.x41CS_RF_AH04_MIX_TEMP(y)-bmsData.x41CS_RF_AH04_CCOIL_TEMP(y)); energyRate1 =
tempDiff1*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity; %btu/min energySaved1 = energySaved1 + energyRate1*15; %15min intervals (btu/week) if (strncmp(bmsData.Time(y),'00',2)==1 |
strncmp(bmsData.Time(y),'01',2)==1 | strncmp(bmsData.Time(y),'02',2)==1 |
strncmp(bmsData.Time(y),'03',2)==1 | strncmp(bmsData.Time(y),'04',2)==1 |
strncmp(bmsData.Time(y),'05',2)==1 | strncmp(bmsData.Time(y),'06',2)==1) energySaved2 = energySaved2 + energyRate1*15; %15min intervals
(btu/week) end end energySaved2 = energySaved2*(3/1000000); %convert to money if tempChange == 0 output1 = 'WARNING: No Discharge Air Temperature Setbacks!'; output1p1 = [' Potential Energy Savings: $'
num2str(round(energySaved2)) '/week']; else output1 = 'Discharge Air Temperature Setbacks Enabled'; output1p1 = [' Potential Energy Savings: $'
num2str(round(energySaved2)) '/week']; end energySaved1Dollars = energySaved1*(3/1000000); energySaved1 = energySaved1/1000000; % convert to million btu output10 = ['Energy used during ENTHALPY Economization: '
num2str(round(energySaved1)) ' million btu/week = $'
num2str(round(energySaved1Dollars))];
%Is the discharge-air meeting set point, or do deviations occur? tempError = 0; for y = 1:height(bmsData) if isnan(bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(y)) == 0 &&
isnan(bmsData.x41CS_RF_AH04_SUP_TEMP(y)) == 0
tempError = tempError + abs(bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(y)-
bmsData.x41CS_RF_AH04_SUP_TEMP(y)); end end tempError = tempError/height(bmsData); if abs(tempError) > 2; output2 = 'WARNING: Discharge Air Temperature Unable to Meet Setpoint!'; else output2 = 'Discharge Air Temperature Meets Setpoint'; end
%Discharge Temperature too warm or too cold? energySaved3 = 0; tooHot = 0; tooCold = 0; for y = 1:height(bmsData) if bmsData.x41CS_RF_AH04_SUP_TEMP(y) > 60 tooHot = tooHot + 1; end if bmsData.x41CS_RF_AH04_SUP_TEMP(y) < 50 tooCold = tooCold + 1; end energyRate3 = (bmsData.x41CS_RF_AH04_SUP_TEMP(y) -
55)*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity; %btu/min energySaved3 = energySaved3 + energyRate3*15; %15min intervals (btu/week) end energySaved3 = energySaved3*(3/1000000); if tooHot > 0 output3 = 'WARNING: Discharge Air Temperature > 60F'; output3p1 = [' Potential Energy Savings: $'
num2str(round(energySaved3)) ' per week']; end if tooCold > 0 output3 = 'WARNING: Discharge Air Temperature < 50F'; output3p1 = [' Potential Energy Savings: $'
num2str(round(energySaved3)) ' per week']; end if tooHot == 0 && tooCold == 0 output3 = '50F < Discharge Air Temperature < 60F'; output3p1 = [' Potential Energy Savings: $'
num2str(round(energySaved3)) ' per week']; end
%Optimization problem: energyUsage(supTemp,fanSpeed) supTemp = 50; %degrees F supTemp = (supTemp - 32) / 1.8; %degrees C roomTemp = 70; %degrees F roomTemp = (roomTemp - 32) / 1.8; %degrees C CFM = 29700; %CFM cvAir = 0.718; %Kj/kg/C
massFlow = CFM*0.03612/60; %kg/s thermalEnergy = cvAir*massFlow*(roomTemp-supTemp); %kW of chilling power
required for normal operation. operatingTons = thermalEnergy/3.517; %tons of chilling power required for
normal operation.
chillerElectrical = operatingTons*0.55; %kW electrical energy fankW4 = [0,5.6,15.49,18.59,22.19,31.79]; fanSpeed4 = [0,60,78.80,83.80,88.83,100]; for y = 1:length(fanSpeed4) fanCFM(y) = fanSpeed4(y)*CFM/100; end polyFankW4 = polyfit(fankW4,fanCFM,5);
x = linspace(1,32); y = polyval(polyFankW4,x); figure plot(x,y) title('Fan Energy Usage') xlabel('CFM') ylabel('kW') hold on
%y = polyval(polyFankW4,x); fankW = linspace(1,32); for i = 1:length(fankW) supTemp(i) = -
(thermalEnergy/(cvAir*polyval(polyFankW4,fankW(i))*0.03612/60))+roomTemp;
%degrees C supTemp(i) = (supTemp(i)*1.8)+32; %chillkW(i) = end
figure plot(supTemp,fankW) xlabel('sup Temp') ylabel('fan kW')
%Do the discharge-air temperatures remain relatively stable? tempStable = 0; for y = 1:(height(bmsData)-1) if isnan(bmsData.x41CS_RF_AH04_SUP_TEMP(y)) == 0 &&
isnan(bmsData.x41CS_RF_AH04_SUP_TEMP(y+1)) == 0 tempStable = tempStable + abs(bmsData.x41CS_RF_AH04_SUP_TEMP(y)-
bmsData.x41CS_RF_AH04_SUP_TEMP(y+1)); end end if abs(tempStable) > 2; output4 = 'WARNING: Discharge Air Temperature Fluctuates!'; else output4 = 'Discharge Air Temperature Stable'; end
%Is there simultaneous heating and cooling occurring in the AHU? energySaved5 = 0; heatcool = 0;
for y = 1:height(bmsData) if isnan(bmsData.x41CS_RF_OA_HUMID(y)) == 0 &&
isnan(bmsData.x41CS_RF_AH04_SUP_HUMID_STPT(y)) == 0 humidifying = bmsData.x41CS_RF_OA_HUMID(y) -
bmsData.x41CS_RF_AH04_SUP_HUMID_STPT(y); else humidifying = 0; %assume not humidifying end if (bmsData.x41CS_RF_AH04_CCOIL_VLV(y) ~= 0 &&
bmsData.x41CS_RF_AH04_HCOIL_VLV(y) ~= 0 && humidifying <= 0) heatcool = 1; tempDiff5 = ((2*bmsData.x41CS_RF_AH04_HCOIL_TEMP(y))-
bmsData.x41CS_RF_AH04_MIX_TEMP(y)-bmsData.x41CS_RF_AH04_CCOIL_TEMP(y)); energyRate5 =
tempDiff5*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*airDensity; %btu/min potentialEnergyRate5 = (bmsData.x41CS_RF_AH04_MIX_TEMP(y)-
bmsData.x41CS_RF_AH04_SUP_TEMP(y))*cpAir*bmsData.x41CS_RF_AH04_SUP_FLOW(y)*ai
rDensity; %btu/min energySaved5 = energySaved5 + (energyRate5-potentialEnergyRate5)*15;
%15min intervals (btu/week) end end energySaved5 = energySaved5*(3/1000000); if heatcool == 1; output5 = 'WARNING: Simultaneous Heating and Cooling!'; output5p1 = [' Potential Energy Savings: $'
num2str(round(energySaved5)) ' per week']; else output5 = 'Heating and Cooling are Independant'; output5p1 = [' Potential Energy Savings: $'
num2str(round(energySaved5)) ' per week']; end
%Is there a reset-schedule for the duct static pressure? energySaved6 = 0; pressureChange = 0; for y = 1:(height(bmsData)-1) if isnan(bmsData.x41CS_RF_AH04_HI_STATIC_STPT(y)) == 0 &&
isnan(bmsData.x41CS_RF_AH04_HI_STATIC_STPT(y+1)) == 0 pressureChange = pressureChange +
(bmsData.x41CS_RF_AH04_HI_STATIC_STPT(y)-
bmsData.x41CS_RF_AH04_HI_STATIC_STPT(y+1)); if (strncmp(bmsData.Time(y),'00',2)==1 |
strncmp(bmsData.Time(y),'01',2)==1 | strncmp(bmsData.Time(y),'02',2)==1 |
strncmp(bmsData.Time(y),'03',2)==1 | strncmp(bmsData.Time(y),'04',2)==1 |
strncmp(bmsData.Time(y),'05',2)==1 | strncmp(bmsData.Time(y),'06',2)==1) energySaved6 = energySaved6 + bmsData.x41CS_RF_AH04_kW(y)*900;%kJ end end end % energySaved6 = energySaved6*0.947817; %convert to btu % energySaved6 = energySaved6*(3/1000000); %convert to money energySaved6 = energySaved6*0.002777; %convert to kwh energySaved6 = energySaved6*.10; %convert to money
if pressureChange == 0
output6 = 'WARNING: No Static Pressure Setbacks!'; output6p1 = [' Potential Energy Savings: $'
num2str(round(energySaved6)) ' per week']; else output6 = 'Static Pressure Setbacks Enabled'; output6p1 = [' Potential Energy Savings: $'
num2str(round(energySaved6)) ' per week']; end
%Is the supply air static pressure too high? %step one: which data points are VAV dampers? isDamperList = {}; for y = 1:(length(bmsData.Properties.VariableNames)) isDamper = strfind(bmsData.Properties.VariableNames(y),'DMP'); isRoof = strfind(bmsData.Properties.VariableNames(y),'RF'); if (isempty(isDamper{1}) == 0 && isempty(isRoof{1}) ~= 0) %isDamperList = [isDamperList;bmsData.Properties.VariableNames(y)]; isDamperList = [isDamperList y]; end end
openedDampers = {}; closedDampers = {}; failedDampers = {}; damperPositions = int16([]); for variable = isDamperList{1}:isDamperList{end} for y = 1:(height(bmsData)) if isnan(bmsData{y,variable}) == 0 damperPositions = [damperPositions;bmsData{y,variable}]; else if length(failedDampers) == 0 failedDampers = bmsData.Properties.VariableNames(variable);
%damper reads NaN elseif
strcmp(failedDampers{end},bmsData.Properties.VariableNames{variable}) == 0; failedDampers = [failedDampers
bmsData.Properties.VariableNames(variable)]; %damper reads NaN end end if length(damperPositions) >= 1 if damperPositions(end) == 100 %damper is fully open if length(openedDampers) == 0 openedDampers =
bmsData.Properties.VariableNames(variable); elseif
strcmp(openedDampers{end},bmsData.Properties.VariableNames{variable}) == 0 openedDampers = [openedDampers
bmsData.Properties.VariableNames(variable)]; end end if damperPositions(end) == 0 %damper is fully closed if length(closedDampers) == 0 closedDampers =
bmsData.Properties.VariableNames(variable); elseif
strcmp(closedDampers{end},bmsData.Properties.VariableNames{variable}) == 0
closedDampers = [closedDampers
bmsData.Properties.VariableNames(variable)]; end end end
end end
avgDamperPosition = mean(damperPositions); if avgDamperPosition <= 70 output7 = 'WARNING: Static Pressure is TOO HIGH!'; elseif avgDamperPosition >= 80 output7 = 'WARNING: Static Pressure is TOO LOW!'; else output7 = 'Static Pressure Within Acceptable Range'; end
output8 = char(['Dampers at maximum:' openedDampers]); output9 = char(['Dampers at minimum:' closedDampers]);
totalSavings = 52*(energySaved2 + energySaved3 + energySaved5 + energySaved6
+ (energySaved1Dollars-tempEnergyDollars)); output12 = ['Total Potential Savings: $' num2str(round(totalSavings)) ' per
year']; output =
{output1;output1p1;output2;output3;output3p1;output4;output5;output5p1;output
6;output6p1;output7;output8;output9;output10;output11;output12};
h = msgbox(output,'Summary of Retuning Analysis');
%%
% global weeks; % weeks = floor(height(bmsData)/1008);
week = 1;
limitL = (1008*week)-1007; limitH = size(bmsData,1);
waitbar(0.60,wb,'generating graphs')
%% %plot 1 figure hold on p5 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_OA_DMPR(limitL:limitH),'b'); p4 = plot(dates(limitL:limitH),SUP_ENTHALPY(limitL:limitH)); p3 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_RET_ENTHALPY(limitL:limitH),'
r');
p1 =
plot(dates(limitL:limitH),20+20*bmsData.x41CS_RF_AH4_5_ECON(limitL:limitH),'c
'); p2 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_OA_ENTHALPY(limitL:limitH),'g'); % [ax,p3,p6] =
plotyy(dates(limitL:limitH),bmsData.x41CS_RF_AH04_RET_ENTHALPY(limitL:limitH)
,dates(limitL:limitH),bmsData.x41CS_RF_OA_TEMP(limitL:limitH)); % [ax,p4,p5] =
plotyy(ax,dates(limitL:limitH),SUP_ENTHALPY(limitL:limitH),dates(limitL:limit
H),bmsData.x41CS_RF_AH04_OA_DMPR(limitL:limitH)); % [ax,p2,p1] =
plotyy(ax,dates(limitL:limitH),bmsData.x41CS_RF_OA_ENTHALPY(limitL:limitH),da
tes(limitL:limitH),100*bmsData.x41CS_RF_AH4_5_ECON(limitL:limitH)); p6 = plot(dates(limitL:limitH),bmsData.x41CS_RF_OA_TEMP(limitL:limitH)); set(p5,'linewidth',2,'color','g') %oa damper set(p1,'linewidth',2,'color','c') %enth econ set(p3,'color',[.7 0.2 0.2]) set(p6,'linestyle','--','color',[0.5 0 0.5]) set(p2,'color',[0.2 0.8 0.5]) if(strcmp(version('-release'),'2014b') || strcmp(version('-
release'),'2015b')) set(gca,'XTickLabelRotation',-45) end
set(gcf,'name','Enthalpy Economizer','NumberTitle','off') axis([limitL limitH 0 inf])
limitLVec = datevec(dates(limitL)); limitLVec = limitLVec([1:3]); limitHVec = datevec(dates(limitH)+1); limitHVec = limitHVec([1:3]);
tick_locations = limitLVec; days = 1; limitLVec = datevec(dates(limitL)+days); limitLVec = limitLVec([1:3]); while isequal(limitLVec,limitHVec) == 0 tick_locations = [tick_locations; limitLVec]; days = days + 1; limitLVec = datevec(dates(limitL)+days); limitLVec = limitLVec([1:3]); end tick_locations = [tick_locations; limitHVec]; tick_locations2 = double(datenum(tick_locations));
set(gca,'XTick',tick_locations2) datetick('x','dddd mmm dd HH:MM','keepticks') legend([p1,p2,p3,p4,p5,p6],'FREE COOLING','OA ENTHALPY','RET ENTHALPY','SUP
ENTHALPY','OA DAMPER','OA TEMP') legend('location','best')
%% %plot 2
figure
hold on p1 = plot(dates(limitL:limitH),40+60*TEMPECON(limitL:limitH),'c'); p2 = plot(dates(limitL:limitH),bmsData.x41CS_RF_OA_TEMP(limitL:limitH),'g'); p3 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_RET_TEMP(limitL:limitH),'r'); p4 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_SUP_TEMP(limitL:limitH),'b'); %[ax,p2,p1] =
plotyy(dates(limitL:limitH),bmsData.x41CS_RF_OA_TEMP(limitL:limitH),dates(lim
itL:limitH),TEMPECON(limitL:limitH));
set(p1,'linewidth',2) if(strcmp(version('-release'),'2014b') || strcmp(version('-
release'),'2015b')) set(gca,'XTickLabelRotation',-45) end
set(gcf,'name','Temperature Economizer','NumberTitle','off') axis auto
set(gca,'XTick',tick_locations2) datetick('x','dddd mmm dd HH:MM','keepticks') legend([p1,p2,p3,p4],'FREE COOLING','OA TEMP','RET TEMP','SUP TEMP') legend('location','best') %% %plot 3 % figure % hold on % p1 = plot(dates(limitL:limitH),mySupEnthalpy(limitL:limitH)); % p2 = plot(dates(limitL:limitH),humidityRatio(limitL:limitH)); % p3 = plot(dates(limitL:limitH),bmsData.x41CS_RF_OA_HUMID(limitL:limitH)); % if(strcmp(version('-release'),'2014b')) % set(gca,'XTickLabelRotation',-45) %end
% axis auto %
% set(gca,'XTick',tick_locations2) % datetick('x','dddd mmm dd HH:MM','keepticks') % legend([p1,p2,p3],'mySupEnthalpy','humidityRatio','OA HUMID') %
%% %plot 3 % % figure % hold on % p1 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_CCOIL_VLV(limitL:limitH),'g')
;
% p2 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_HCOIL_VLV(limitL:limitH),'r')
; % p3 = plot(dates(limitL:limitH),bmsData.x41CS_RF_OAT(limitL:limitH),'b'); % p4 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_CCOIL_TEMP(limitL:limitH),'c'
); % p5 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_SUP_TEMP(limitL:limitH)); % set(p5,'color',[.7 0.2 0.2]) % if(strcmp(version('-release'),'2014b')) % set(gca,'XTickLabelRotation',-45) %end
% %set(gcf,'name','Cooling','NumberTitle','off') % axis auto % % set(gca,'XTick',tick_locations2) % datetick('x','dddd mmm dd HH:MM','keepticks') % legend([p1,p2,p3,p4,p5],'cool vlv','heat vlv','OAT','ccoil temp','sup
temp')
%% %plot 4
figure hold on p1 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_SUP_TEMP_STPT(limitL:limitH),
'g'); p2 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_SUP_TEMP(limitL:limitH),'r'); p3 = plot(dates(limitL:limitH),bmsData.x41CS_RF_OA_HUMID(limitL:limitH),'b'); p4 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_SUP_HUMID_STPT(limitL:limitH)
,'c'); p5 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_CCOIL_VLV(limitL:limitH)); p6 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_HCOIL_VLV(limitL:limitH)); p7 =
plot(dates(limitL:limitH),bmsData.x41CS_RF_AH04_HI_STATIC_STPT(limitL:limitH)
); set(p5,'color',[.7 0.2 0.2]) if(strcmp(version('-release'),'2014b') || strcmp(version('-
release'),'2015b')) set(gca,'XTickLabelRotation',-45) end
set(gcf,'name','data that may or may not contain faults','NumberTitle','off') axis auto
set(gca,'XTick',tick_locations2) datetick('x','dddd mmm dd HH:MM','keepticks')
legend([p1,p2,p3,p4,p5,p6,p7],'SUP TEMP STPT','SUP TEMP','OA HUMIDITY','SUP
HUMIDITY STPT','CCOIL VLV','HCOIL VLV','PRESSURE STPT') legend('location','best') %% %plot 5
figure hold on for variable = isDamperList{1}:isDamperList{end} if isnan(bmsData{y,variable}) == 0 p1 = plot(dates(limitL:limitH),bmsData{(limitL:limitH),variable}); end end
if(strcmp(version('-release'),'2014b') || strcmp(version('-
release'),'2015b')) set(gca,'XTickLabelRotation',-45) end
set(gcf,'name','Damper Positions','NumberTitle','off') axis auto
set(gca,'XTick',tick_locations2) datetick('x','dddd mmm dd HH:MM','keepticks') title('Damper Positions')
close(wb)