From 6d2be6a7bbfa6626f1331dcfff60f45f34347a33 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 24 May 2026 15:12:15 +0200 Subject: [PATCH 01/18] feat: add clickable BigLadder doc links to Inspector and SimSettings headers Add IddObjectDocUrl.hpp mapping 300+ OS IDD type names to EnergyPlus 25.1 Input/Output Reference URLs. InspectorGadget::layoutText() now renders IDD type headers as clickable hyperlinks in the right-sidebar inspector. Extend CollapsibleInspector to accept an optional URL parameter, and wire 15 section headers in SimSettingsView (plus the Run Period, Sizing Parameters, and Timestep H1 labels) to their respective BigLadder doc anchors. Closes #160 Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/IddObjectDocUrl.hpp | 418 ++++++++++++++++++++ src/model_editor/InspectorGadget.cpp | 15 +- src/openstudio_lib/CollapsibleInspector.cpp | 17 +- src/openstudio_lib/CollapsibleInspector.hpp | 4 +- src/openstudio_lib/SimSettingsView.cpp | 48 ++- 5 files changed, 479 insertions(+), 23 deletions(-) create mode 100644 src/model_editor/IddObjectDocUrl.hpp diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp new file mode 100644 index 000000000..ff3aacc84 --- /dev/null +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -0,0 +1,418 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) OpenStudio Coalition and other contributors. +* See also https://openstudiocoalition.org/about/software_license/ +***********************************************************************************************************************/ + +#ifndef MODELEDITOR_IDDOBJECTDOCURL_HPP +#define MODELEDITOR_IDDOBJECTDOCURL_HPP + +#include +#include + +// Returns the BigLadder EnergyPlus 25.1 Input/Output Reference URL for the given +// OS IDD type name (e.g. "OS:ThermalZone"), or an empty string if none is known. +inline QString iddObjectDocUrl(const QString& iddTypeName) { + static const QString base = QStringLiteral("https://bigladdersoftware.com/epx/docs/25-1/input-output-reference/"); + + // clang-format off + static const QHash urlMap{ + // Simulation Parameters + {"OS:SimulationControl", "group-simulation-parameters.html#simulationcontrol"}, + {"OS:Building", "group-simulation-parameters.html#building"}, + {"OS:Timestep", "group-simulation-parameters.html#timestep"}, + {"OS:RunPeriod", "group-simulation-parameters.html#runperiod"}, + {"OS:ShadowCalculation", "group-simulation-parameters.html#shadowcalculation"}, + {"OS:SurfaceConvectionAlgorithm:Inside", "group-simulation-parameters.html#surfaceconvectionalgorithminside"}, + {"OS:SurfaceConvectionAlgorithm:Outside", "group-simulation-parameters.html#surfaceconvectionalgorithmoutside"}, + {"OS:HeatBalanceAlgorithm", "group-simulation-parameters.html#heatbalancealgorithm"}, + {"OS:ZoneAirHeatBalanceAlgorithm", "group-simulation-parameters.html#zoneairheatbalancealgorithm"}, + {"OS:ZoneAirContaminantBalance", "group-simulation-parameters.html#zoneaircontaminantbalance"}, + + // Location and Climate + {"OS:Site:Location", "group-location-climate-weather-file-access.html#sitelocation"}, + {"OS:Site:GroundTemperature:BuildingSurface", "group-location-climate-weather-file-access.html#sitegroundtemperaturebuildingsurface"}, + {"OS:Site:GroundTemperature:FCfactorMethod", "group-location-climate-weather-file-access.html#sitegroundtemperaturefcfactormethod"}, + {"OS:Site:GroundReflectance", "group-location-climate-weather-file-access.html#sitegroundreflectance"}, + {"OS:Site:WaterMainsTemperature", "group-location-climate-weather-file-access.html#sitewatermainstemperature"}, + {"OS:SizingPeriod:DesignDay", "group-location-climate-weather-file-access.html#sizingperioddesignday"}, + {"OS:DesignDay", "group-location-climate-weather-file-access.html#sizingperioddesignday"}, + + // Schedules + {"OS:ScheduleTypeLimits", "group-schedules.html#scheduletypelimits"}, + {"OS:Schedule:Compact", "group-schedules.html#schedulecompact"}, + {"OS:Schedule:Constant", "group-schedules.html#scheduleconstant"}, + {"OS:Schedule:Day:Hourly", "group-schedules.html#scheduledayhourly"}, + {"OS:Schedule:Day:Interval", "group-schedules.html#scheduledayinterval"}, + {"OS:Schedule:Week:Daily", "group-schedules.html#scheduleweekdaily"}, + {"OS:Schedule:Week:Compact", "group-schedules.html#scheduleweekcompact"}, + {"OS:Schedule:Year", "group-schedules.html#scheduleyear"}, + {"OS:Schedule:Ruleset", "group-schedules.html#scheduleyear"}, + + // Surface Construction Elements + {"OS:Material", "group-surface-construction-elements.html#material"}, + {"OS:Material:NoMass", "group-surface-construction-elements.html#materialnomass"}, + {"OS:Material:AirGap", "group-surface-construction-elements.html#materialaingap"}, + {"OS:Material:InfraredTransparent", "group-surface-construction-elements.html#materialinfraredtransparent"}, + {"OS:Material:RoofVegetation", "group-surface-construction-elements.html#materialroofvegetation"}, + {"OS:WindowMaterial:Glazing", "group-surface-construction-elements.html#windowmaterialglazing"}, + {"OS:WindowMaterial:Gas", "group-surface-construction-elements.html#windowmaterialgas"}, + {"OS:WindowMaterial:GasMixture", "group-surface-construction-elements.html#windowmaterialgasmixture"}, + {"OS:WindowMaterial:SimpleGlazingSystem", "group-surface-construction-elements.html#windowmaterialsimpleglazingsystem"}, + {"OS:WindowMaterial:Blind", "group-surface-construction-elements.html#windowmaterialblind"}, + {"OS:WindowMaterial:Screen", "group-surface-construction-elements.html#windowmaterialscreen"}, + {"OS:WindowMaterial:Shade", "group-surface-construction-elements.html#windowmaterialshade"}, + {"OS:Construction", "group-surface-construction-elements.html#construction"}, + {"OS:Construction:InternalSource", "group-surface-construction-elements.html#constructioninternalsource"}, + {"OS:Construction:WindowDataFile", "group-surface-construction-elements.html#constructionwindowdatafile"}, + {"OS:WindowProperty:FrameAndDivider", "group-surface-construction-elements.html#windowpropertyframeanddivider"}, + + // Thermal Zone Description and Geometry + {"OS:ThermalZone", "group-thermal-zone-description-geometry.html"}, + {"OS:Space", "group-thermal-zone-description-geometry.html"}, + {"OS:SpaceType", "group-thermal-zone-description-geometry.html"}, + {"OS:BuildingStory", "group-thermal-zone-description-geometry.html"}, + {"OS:Surface", "group-thermal-zone-description-geometry.html#buildingsurface-detailed"}, + {"OS:SubSurface", "group-thermal-zone-description-geometry.html#fenestrationsurface-detailed"}, + {"OS:ShadingControl", "group-thermal-zone-description-geometry.html#shadingcontrol"}, + {"OS:InteriorPartitionSurface", "group-thermal-zone-description-geometry.html#interiorpartitionsurface-detailed"}, + {"OS:InteriorPartitionSurfaceGroup", "group-thermal-zone-description-geometry.html"}, + + // Daylighting + {"OS:Daylighting:Control", "group-daylighting.html#daylightingcontrols"}, + {"OS:DaylightingDevice:Shelf", "group-daylighting.html#daylightingdeviceshelf"}, + {"OS:DaylightingDevice:Tubular", "group-daylighting.html#daylightingdevicetubular"}, + {"OS:DaylightingDevice:LightWell", "group-daylighting.html#daylightingdevicelightwell"}, + + // Internal Gains + {"OS:People", "group-internal-gains-people-lights-other.html#people"}, + {"OS:Lights", "group-internal-gains-people-lights-other.html#lights"}, + {"OS:ElectricEquipment", "group-internal-gains-people-lights-other.html#electricequipment"}, + {"OS:GasEquipment", "group-internal-gains-people-lights-other.html#gasequipment"}, + {"OS:HotWaterEquipment", "group-internal-gains-people-lights-other.html#hotwatersupportequipment"}, + {"OS:SteamEquipment", "group-internal-gains-people-lights-other.html#steamequipment"}, + {"OS:OtherEquipment", "group-internal-gains-people-lights-other.html#otherequipment"}, + {"OS:InternalMass", "group-internal-gains-people-lights-other.html#internalmass"}, + + // Exterior Energy Use + {"OS:Exterior:Lights", "group-exterior-energy-use-equipment.html#exteriorlights"}, + {"OS:Exterior:FuelEquipment", "group-exterior-energy-use-equipment.html#exteriorfuelequipment"}, + {"OS:Exterior:WaterEquipment", "group-exterior-energy-use-equipment.html#exteriorwaterequipment"}, + // Older OpenStudio type names + {"OS:ExteriorLights", "group-exterior-energy-use-equipment.html#exteriorlights"}, + {"OS:ExteriorFuelEquipment", "group-exterior-energy-use-equipment.html#exteriorfuelequipment"}, + {"OS:ExteriorWaterEquipment", "group-exterior-energy-use-equipment.html#exteriorwaterequipment"}, + + // Zone Airflow + {"OS:SpaceInfiltration:DesignFlowRate", "group-airflow.html#zoneinfiltrationdesignflowrate"}, + {"OS:SpaceInfiltration:EffectiveLeakageArea", "group-airflow.html#zoneinfiltrationeffectiveleakagearea"}, + {"OS:ZoneVentilation:DesignFlowRate", "group-airflow.html#zoneventilationdesignflowrate"}, + {"OS:ZoneVentilation:WindandStackOpenArea", "group-airflow.html#zoneventilationwindandstackopenarea"}, + {"OS:ZoneMixing", "group-airflow.html#zonemixing"}, + {"OS:ZoneCrossMixing", "group-airflow.html#zonecrossmixing"}, + + // Design Objects / Sizing + {"OS:DesignSpecification:OutdoorAir", "group-design-objects.html#designspecificationoutdoorair"}, + {"OS:DesignSpecification:ZoneAirDistribution", "group-design-objects.html#designspecificationzoneairdistribution"}, + {"OS:Sizing:Zone", "group-design-objects.html#sizingzone"}, + {"OS:Sizing:System", "group-design-objects.html#sizingsystem"}, + {"OS:Sizing:Plant", "group-design-objects.html#sizingplant"}, + {"OS:Sizing:Parameters", "group-design-objects.html#sizingparameters"}, + + // Zone HVAC Controls and Thermostats + {"OS:ThermostatSetpoint:DualSetpoint", "group-zone-controls-thermostats.html#thermostatsetpointdualsetpoint"}, + {"OS:ThermostatSetpoint:SingleHeating", "group-zone-controls-thermostats.html#thermostatsetpointsingleheating"}, + {"OS:ThermostatSetpoint:SingleCooling", "group-zone-controls-thermostats.html#thermostatsetpointsinglecooling"}, + {"OS:ZoneControl:Thermostat", "group-zone-controls-thermostats.html#zonecontrolthermostat"}, + {"OS:ZoneControl:ContaminantController", "group-zone-controls-thermostats.html#zonecontrolcontaminantcontroller"}, + {"OS:ZoneControl:Humidistat", "group-zone-controls-thermostats.html#zonecontrolhumidistat"}, + {"OS:ZoneControl:Thermostat:StagedDualSetpoint", "group-zone-controls-thermostats.html#zonecontrolthermostatstageddualsetpoint"}, + + // Zone HVAC Equipment Connections + {"OS:ZoneHVAC:EquipmentList", "group-zone-equipment.html#zonehvacequipmentlist"}, + {"OS:ZoneHVAC:EquipmentConnections", "group-zone-equipment.html#zonehvacequipmentconnections"}, + + // Zone HVAC Forced Air Units + {"OS:ZoneHVAC:PackagedTerminalAirConditioner", "group-zone-forced-air-units.html#zonehvacpackagedterminalairconditioner"}, + {"OS:ZoneHVAC:PackagedTerminalHeatPump", "group-zone-forced-air-units.html#zonehvacpackagedterminalheatpump"}, + {"OS:ZoneHVAC:WaterToAirHeatPump", "group-zone-forced-air-units.html#zonehvacwatertoairheatpump"}, + {"OS:ZoneHVAC:FourPipeFanCoil", "group-zone-forced-air-units.html#zonehvacfourpipefancoil"}, + {"OS:ZoneHVAC:UnitVentilator", "group-zone-forced-air-units.html#zonehvacunitventilator"}, + {"OS:ZoneHVAC:UnitHeater", "group-zone-forced-air-units.html#zonehvacunitheater"}, + {"OS:ZoneHVAC:IdealLoadsAirSystem", "group-zone-forced-air-units.html#zonehvacidealloadsairsystem"}, + {"OS:ZoneHVAC:EnergyRecoveryVentilator", "group-zone-forced-air-units.html#zonehvacenergyrecoveryventilator"}, + {"OS:ZoneHVAC:Dehumidifier:DX", "group-zone-forced-air-units.html#zonehvacdehumidifierdx"}, + {"OS:ZoneHVAC:EvaporativeCoolerUnit", "group-zone-forced-air-units.html#zonehvacevaporativecoolerunit"}, + {"OS:ZoneHVAC:Baseboard:Convective:Water", "group-radiative-convective-units.html#zonehvacbaseboardconvectivewater"}, + {"OS:ZoneHVAC:Baseboard:Convective:Electric", "group-radiative-convective-units.html#zonehvacbaseboardconvectiveelectric"}, + {"OS:ZoneHVAC:TerminalUnit:VariableRefrigerantFlow", "group-zone-forced-air-units.html#zonehvacterminalunitvariablerefrigerantflow"}, + + // Zone HVAC Radiative / Cooling Panels + {"OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water", "group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, + {"OS:ZoneHVAC:Baseboard:RadiantConvective:Water", "group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, + {"OS:ZoneHVAC:Baseboard:RadiantConvective:Electric","group-radiative-convective-units.html#zonehvacbaseboardradiantconvectiveelectric"}, + {"OS:ZoneHVAC:HighTemperatureRadiant", "group-radiative-convective-units.html#zonehvachightemperatureradiant"}, + {"OS:ZoneHVAC:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflow"}, + {"OS:ZoneHVAC:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, + {"OS:ZoneHVAC:LowTemperatureRadiant:Electric", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantelectric"}, + + // Air Terminals + {"OS:AirTerminal:SingleDuct:VAV:Reheat", "group-air-distribution-equipment.html#airterminalsingleductvavreheat"}, + {"OS:AirTerminal:SingleDuct:VAV:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductvavnoreheat"}, + {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat", "group-air-distribution-equipment.html#airterminalsingleductvavheatandcoolreheat"}, + {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductvavheatandcoolnoreheat"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:Reheat", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumereheat"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductuncontrolled"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:CooledBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumecooledbeam"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, + {"OS:AirTerminal:SingleDuct:ParallelPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductparallelpiu"}, + {"OS:AirTerminal:SingleDuct:SeriesPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductseriespiu"}, + {"OS:AirTerminal:SingleDuct:InletSideMixer", "group-air-distribution-equipment.html#airterminalsingleductinletsidemixer"}, + {"OS:AirTerminal:DualDuct:VAV", "group-air-distribution-equipment.html#airterminaldualductvav"}, + {"OS:AirTerminal:DualDuct:VAV:OutdoorAir", "group-air-distribution-equipment.html#airterminaldualductvavoutdoorair"}, + {"OS:AirTerminal:DualDuct:ConstantVolume", "group-air-distribution-equipment.html#airterminaldualductconstantvolume"}, + {"OS:AirTerminal:FourPipeInduction", "group-air-distribution-equipment.html#airterminalfourpipeinduction"}, + + // Fans + {"OS:Fan:ConstantVolume", "group-fans.html#fanconstantvolume"}, + {"OS:Fan:VariableVolume", "group-fans.html#fanvariablevolume"}, + {"OS:Fan:OnOff", "group-fans.html#fanonoff"}, + {"OS:Fan:ZoneExhaust", "group-fans.html#fanzoneexhaust"}, + {"OS:Fan:SystemModel", "group-fans.html#fansystemmodel"}, + + // Coils - Cooling + {"OS:Coil:Cooling:DX:SingleSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxsinglespeed"}, + {"OS:Coil:Cooling:DX:TwoSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxtwospeed"}, + {"OS:Coil:Cooling:DX:MultiSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, + {"OS:Coil:Cooling:DX:VariableSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxvariablespeed"}, + {"OS:Coil:Cooling:DX:VariableRefrigerantFlow", "group-heating-and-cooling-coils.html#coilcoolingdxvariablerefrigerantflow"}, + {"OS:Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl", "group-heating-and-cooling-coils.html#coilcoolingdxvariablerefrigerantflowfluidtemperaturecontrol"}, + {"OS:Coil:Cooling:Water", "group-heating-and-cooling-coils.html#coilcoolingwater"}, + {"OS:Coil:Cooling:Water:DetailedGeometry", "group-heating-and-cooling-coils.html#coilcoolingwaterdetailedgeometry"}, + {"OS:Coil:Cooling:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpequationfit"}, + {"OS:Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpvariablespeedequationfit"}, + {"OS:Coil:Cooling:FourPipeBeam", "group-heating-and-cooling-coils.html#coilcoolingfourpipebeam"}, + + // Coils - Heating + {"OS:Coil:Heating:Gas", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, + {"OS:Coil:Heating:Fuel", "group-heating-and-cooling-coils.html#coilheatingfuel"}, + {"OS:Coil:Heating:Electric", "group-heating-and-cooling-coils.html#coilheatingelectric"}, + {"OS:Coil:Heating:Water", "group-heating-and-cooling-coils.html#coilheatingwater"}, + {"OS:Coil:Heating:DX:SingleSpeed", "group-heating-and-cooling-coils.html#coilheatingdxsinglespeed"}, + {"OS:Coil:Heating:DX:MultiSpeed", "group-heating-and-cooling-coils.html#coilheatingdxmultispeed"}, + {"OS:Coil:Heating:DX:VariableSpeed", "group-heating-and-cooling-coils.html#coilheatingdxvariablespeed"}, + {"OS:Coil:Heating:DX:VariableRefrigerantFlow", "group-heating-and-cooling-coils.html#coilheatingdxvariablerefrigerantflow"}, + {"OS:Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl", "group-heating-and-cooling-coils.html#coilheatingdxvariablerefrigerantflowfluidtemperaturecontrol"}, + {"OS:Coil:Heating:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpequationfit"}, + {"OS:Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpvariablespeedequationfit"}, + {"OS:Coil:Heating:Desuperheater", "group-heating-and-cooling-coils.html#coilheatingdesuperheater"}, + {"OS:Coil:Heating:FourPipeBeam", "group-heating-and-cooling-coils.html#coilheatingfourpipebeam"}, + {"OS:Coil:WaterHeating:AirToWaterHeatPump:Pumped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, + {"OS:Coil:WaterHeating:AirToWaterHeatPump:Wrapped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumpwrapped"}, + {"OS:Coil:WaterHeating:Desuperheater", "group-heating-and-cooling-coils.html#coilwaterheatingdesuperheater"}, + + // Evaporative Coolers + {"OS:EvaporativeCooler:Direct:ResearchSpecial", "group-evaporative-coolers.html#evaporativecoolerdirectresearchspecial"}, + {"OS:EvaporativeCooler:Indirect:ResearchSpecial", "group-evaporative-coolers.html#evaporativecoolerindirectresearchspecial"}, + {"OS:EvaporativeCooler:Direct:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerdirectceldeckpad"}, + {"OS:EvaporativeCooler:Indirect:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerindirectceldeckpad"}, + {"OS:EvaporativeCooler:Indirect:WetCoil", "group-evaporative-coolers.html#evaporativecoolerindirectwetcoil"}, + + // Humidifiers + {"OS:Humidifier:Steam:Electric", "group-humidifiers-and-dehumidifiers.html#humidifiersteamelectric"}, + {"OS:Humidifier:Steam:Gas", "group-humidifiers-and-dehumidifiers.html#humidifiersteamgas"}, + + // Unitary Equipment + {"OS:AirLoopHVAC:UnitaryHeatPump:AirToAir", "group-unitary-equipment.html#airloophvacunitaryheatpumpairtoair"}, + {"OS:AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed", "group-unitary-equipment.html#airloophvacunitaryheatpumpairtoairmultispeed"}, + {"OS:AirLoopHVAC:UnitarySystem", "group-unitary-equipment.html#airloophvacunitarysystem"}, + {"OS:AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", "group-unitary-equipment.html#airloophvacunitaryheatcoolvavchangeoverbypass"}, + + // Variable Refrigerant Flow + {"OS:AirConditioner:VariableRefrigerantFlow", "group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflow"}, + {"OS:AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl", "group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflowfluidtemperaturecontrol"}, + {"OS:AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR", "group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflowfluidtemperaturecontrolhr"}, + + // Air Distribution / AirLoop + {"OS:AirLoopHVAC", "group-air-distribution.html#group-air-distribution"}, + {"OS:AirLoopHVAC:OutdoorAirSystem", "group-air-distribution.html#airloophvacoutdoorairsystem"}, + {"OS:OutdoorAir:Mixer", "group-airflow.html#outdoorairmixer"}, + {"OS:Controller:OutdoorAir", "group-controllers.html#controlleroutdoorair"}, + {"OS:Controller:MechanicalVentilation", "group-controllers.html#controllermechanicalventilation"}, + {"OS:ZoneHVAC:EnergyRecoveryVentilator:Controller", "group-controllers.html#zonehvacenergyrecoveryventilatorcontroller"}, + {"OS:AirLoopHVAC:ZoneMixer", "group-airflow.html#airloophvaczonemixer"}, + {"OS:AirLoopHVAC:ZoneSplitter", "group-airflow.html#airloophvaczonesplitter"}, + {"OS:AirLoopHVAC:ReturnPlenum", "group-airflow.html#airloophvacreturnplenum"}, + {"OS:AirLoopHVAC:SupplyPlenum", "group-airflow.html#airloophvacsupplyplenum"}, + + // Setpoint Managers + {"OS:SetpointManager:Scheduled", "group-setpoint-managers.html#setpointmanagerscheduled"}, + {"OS:SetpointManager:Scheduled:DualSetpoint", "group-setpoint-managers.html#setpointmanagerscheduleddualsetpoint"}, + {"OS:SetpointManager:MixedAir", "group-setpoint-managers.html#setpointmanagermixedair"}, + {"OS:SetpointManager:OutdoorAirReset", "group-setpoint-managers.html#setpointmanageroutdoorarreset"}, + {"OS:SetpointManager:SingleZone:Reheat", "group-setpoint-managers.html#setpointmanagersinglezonereheat"}, + {"OS:SetpointManager:SingleZone:Heating", "group-setpoint-managers.html#setpointmanagersinglezoneheating"}, + {"OS:SetpointManager:SingleZone:Cooling", "group-setpoint-managers.html#setpointmanagersinglezonecooling"}, + {"OS:SetpointManager:Warmest", "group-setpoint-managers.html#setpointmanagerwarmest"}, + {"OS:SetpointManager:Coldest", "group-setpoint-managers.html#setpointmanagercoldest"}, + {"OS:SetpointManager:FollowOutdoorAirTemperature", "group-setpoint-managers.html#setpointmanagerfollowoutdoorairtemperature"}, + {"OS:SetpointManager:FollowGroundTemperature", "group-setpoint-managers.html#setpointmanagerfollowgroundtemperature"}, + {"OS:SetpointManager:CondenserEnteringReset", "group-setpoint-managers.html#setpointmanagercondenserenteringreset"}, + {"OS:SetpointManager:WarmestTemperatureFlow", "group-setpoint-managers.html#setpointmanagerwarmesttemperatureflow"}, + {"OS:SetpointManager:OutdoorAirPretreat", "group-setpoint-managers.html#setpointmanageroutdoorairpretreat"}, + {"OS:SetpointManager:MultiZone:Heating:Average", "group-setpoint-managers.html#setpointmanagermultizoneheataverage"}, + {"OS:SetpointManager:MultiZone:Cooling:Average", "group-setpoint-managers.html#setpointmanagermultizonecoolaverage"}, + + // Pumps + {"OS:Pump:VariableSpeed", "group-pumps.html#pumpvariablespeed"}, + {"OS:Pump:ConstantSpeed", "group-pumps.html#pumpconstantspeed"}, + {"OS:HeaderedPumps:VariableSpeed", "group-pumps.html#headeredpumpsvariablespeed"}, + {"OS:HeaderedPumps:ConstantSpeed", "group-pumps.html#headeredpumpsconstantspeed"}, + + // Solar Collectors + {"OS:SolarCollector:FlatPlate:Water", "group-solar-collectors.html#solarcollectorflatplatewater"}, + {"OS:SolarCollector:IntegralCollectorStorage", "group-solar-collectors.html#solarcollectorintegralcollectorstorage"}, + {"OS:SolarCollector:UnglazedTranspired", "group-solar-collectors.html#solarcollectorunglazedtranspired"}, + {"OS:SolarCollector:FlatPlate:PhotovoltaicThermal", "group-solar-collectors.html#solarcollectorflatplatephotovoltaicthermal"}, + + // Plant Heating and Cooling Equipment + {"OS:Boiler:HotWater", "group-plant-equipment.html#boilerhotwater"}, + {"OS:Boiler:Steam", "group-plant-equipment.html#boilersteam"}, + {"OS:Chiller:Electric:EIR", "group-plant-equipment.html#chillerelectriceir"}, + {"OS:Chiller:Electric:ReformulatedEIR", "group-plant-equipment.html#chillerelectricreformulatedeir"}, + {"OS:Chiller:Absorption:Indirect", "group-plant-equipment.html#chillerabsorptionindirect"}, + {"OS:Chiller:Absorption:Direct", "group-plant-equipment.html#chillerabsorptiondirect"}, + {"OS:ChillerHeater:Absorption:DirectFired", "group-plant-equipment.html#chillerheaterabsorptiondirectfired"}, + {"OS:DistrictCooling", "group-plant-equipment.html#districtcooling"}, + {"OS:DistrictHeating", "group-plant-equipment.html#districtheating"}, + {"OS:DistrictHeating:Water", "group-plant-equipment.html#districtheating"}, + {"OS:HeatPump:PlantLoop:EIR:Cooling", "group-plant-equipment.html#heatpumpplantloopeircooling"}, + {"OS:HeatPump:PlantLoop:EIR:Heating", "group-plant-equipment.html#heatpumpplantloopeirheating"}, + {"OS:HeatPump:WaterToWater:EquationFit:Cooling", "group-plant-equipment.html#heatpumpwatertowaterequationfitcooling"}, + {"OS:HeatPump:WaterToWater:EquationFit:Heating", "group-plant-equipment.html#heatpumpwatertowaterequationfitheating"}, + {"OS:HeatPump:AirToWater:FuelFired:Cooling", "group-plant-equipment.html#plhp_fuelfired"}, + {"OS:HeatPump:AirToWater:FuelFired:Heating", "group-plant-equipment.html#plhp_fuelfired"}, + {"OS:HeatPump:AirToWater", "group-plant-equipment.html#plhp_air_to_water"}, + {"OS:HeatPump:AirToWater:Cooling", "group-plant-equipment.html#plhp_air_to_water"}, + {"OS:HeatPump:AirToWater:Heating", "group-plant-equipment.html#plhp_air_to_water"}, + {"OS:CentralHeatPumpSystem", "group-plant-equipment.html#centralheatpumpsystem"}, + {"OS:ChillerHeaterPerformance:Electric:EIR", "group-plant-equipment.html#chillerheaterperformancelectriceir"}, + + // Cooling Towers and Fluid Coolers + {"OS:CoolingTower:SingleSpeed", "group-condenser-equipment.html#coolingtowersinglespeed"}, + {"OS:CoolingTower:TwoSpeed", "group-condenser-equipment.html#coolingtowertwospeed"}, + {"OS:CoolingTower:VariableSpeed:Merkel", "group-condenser-equipment.html#coolingtowervariablespeedmerkel"}, + {"OS:EvaporativeFluidCooler:SingleSpeed", "group-condenser-equipment.html#evaporativefluidcoolersinglespeed"}, + {"OS:EvaporativeFluidCooler:TwoSpeed", "group-condenser-equipment.html#evaporativefluidcoolertwospeed"}, + {"OS:FluidCooler:SingleSpeed", "group-condenser-equipment.html#fluidcoolersinglespeed"}, + {"OS:FluidCooler:TwoSpeed", "group-condenser-equipment.html#fluidcoolertwospeed"}, + + // Heat Recovery + {"OS:HeatExchanger:AirToAir:SensibleAndLatent", "group-heat-recovery.html#heatexchangerairtoairsensibleandlatent"}, + {"OS:HeatExchanger:FluidToFluid", "group-heat-recovery.html#heatexchangerfluidtofluid"}, + {"OS:HeatExchanger:Desiccant:BalancedFlow", "group-heat-recovery.html#heatexchangerdesiccantbalancedflow"}, + + // Condenser Equipment and Ground Heat Exchangers + {"OS:GroundHeatExchanger:Vertical", "group-condenser-equipment.html#groundheatexchangervertical"}, + {"OS:GroundHeatExchanger:HorizontalTrench", "group-condenser-equipment.html#groundheatexchangerhorizontaltrench"}, + {"OS:GroundHeatExchanger:Slinky", "group-condenser-equipment.html#groundheatexchangerslinky"}, + + // Water Heaters and Thermal Storage + {"OS:WaterHeater:Mixed", "group-water-heaters.html#waterheatermixed"}, + {"OS:WaterHeater:Stratified", "group-water-heaters.html#waterheaterstratified"}, + {"OS:WaterHeater:HeatPump", "group-water-heaters.html#waterheaterheatpump"}, + {"OS:WaterHeater:HeatPump:PumpedCondenser", "group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, + {"OS:WaterHeater:HeatPump:WrappedCondenser", "group-water-heaters.html#waterheaterheatpumpwrappedcondenser"}, + {"OS:WaterHeater:Sizing", "group-water-heaters.html#waterheatersizing"}, + {"OS:ThermalStorage:Ice:Detailed", "group-water-heaters.html#thermalstorageicedetailed"}, + {"OS:ThermalStorage:ChilledWater:Stratified", "group-water-heaters.html#thermalstoragechilledwaterstratified"}, + + // Water Systems + {"OS:WaterUse:Equipment", "group-water-systems.html#wateruseequipment"}, + {"OS:WaterUse:Connections", "group-water-systems.html#wateruseconnections"}, + + // Refrigeration + {"OS:Refrigeration:AirChiller", "group-refrigeration.html#refrigerationairchiller"}, + {"OS:Refrigeration:Case", "group-refrigeration.html#refrigerationcase"}, + {"OS:Refrigeration:Compressor", "group-refrigeration.html#refrigerationcompressor"}, + {"OS:Refrigeration:CompressorRack", "group-refrigeration.html#refrigerationcompressorrack"}, + {"OS:Refrigeration:Condenser:AirCooled", "group-refrigeration.html#refrigerationcondenseraircooled"}, + {"OS:Refrigeration:Condenser:Cascade", "group-refrigeration.html#refrigerationcondensercascade"}, + {"OS:Refrigeration:Condenser:EvaporativeCooled", "group-refrigeration.html#refrigerationcondenserevaporativecooled"}, + {"OS:Refrigeration:Condenser:WaterCooled", "group-refrigeration.html#refrigerationcondenserwatercooled"}, + {"OS:Refrigeration:DefrostCycleParameters", "group-refrigeration.html#refrigerationwalkin"}, + {"OS:Refrigeration:GasCooler:AirCooled", "group-refrigeration.html#refrigerationgascooleraircooled"}, + {"OS:Refrigeration:SecondarySystem", "group-refrigeration.html#refrigerationsecondarysystem"}, + {"OS:Refrigeration:Subcooler:LiquidSuction", "group-refrigeration.html#refrigerationsubcooler"}, + {"OS:Refrigeration:Subcooler:Mechanical", "group-refrigeration.html#refrigerationsubcooler"}, + {"OS:Refrigeration:System", "group-refrigeration.html#refrigerationsystem"}, + {"OS:Refrigeration:TranscriticalSystem", "group-refrigeration.html#refrigerationtranscriticalsystem"}, + {"OS:Refrigeration:WalkIn", "group-refrigeration.html#refrigerationwalkin"}, + {"OS:Refrigeration:WalkIn:ZoneBoundary", "group-refrigeration.html#refrigerationwalkin"}, + + // Node / Branch Management + {"OS:Pipe:Adiabatic", "group-node-branch-management.html#pipeadiabatic"}, + + // Plant / Condenser Control + {"OS:PlantLoop", "group-plant-condenser-control.html#plantloop"}, + {"OS:CondenserLoop", "group-plant-condenser-control.html#condenserloop"}, + {"OS:PlantEquipmentList", "group-plant-condenser-control.html#plantequipmentlist"}, + {"OS:PlantEquipmentOperation:CoolingLoad", "group-plant-condenser-control.html#plantequipmentoperationcoolingload"}, + {"OS:PlantEquipmentOperation:HeatingLoad", "group-plant-condenser-control.html#plantequipmentoperationheatingload"}, + {"OS:PlantEquipmentOperation:ComponentSetpoint", "group-plant-condenser-control.html#plantequipmentoperationcomponentsetpoint"}, + {"OS:PlantEquipmentOperation:OutdoorDryBulb", "group-plant-condenser-control.html#plantequipmentoperationoutdoordrybulb"}, + {"OS:PlantEquipmentOperation:OutdoorWetBulb", "group-plant-condenser-control.html#plantequipmentoperationoutdoorwetbulb"}, + {"OS:PlantEquipmentOperation:ThermalEnergyStorage", "group-plant-condenser-control.html#plantequipmentoperationthermalenergystorage"}, + {"OS:PlantEquipmentOperation:Uncontrolled", "group-plant-condenser-control.html#plantequipmentoperationuncontrolled"}, + {"OS:AvailabilityManagerAssignmentList", "group-system-availability-managers.html#availabilitymanagerassignmentlist"}, + {"OS:AvailabilityManager:Scheduled", "group-system-availability-managers.html#availabilitymanagerscheduled"}, + {"OS:AvailabilityManager:ScheduledOn", "group-system-availability-managers.html#availabilitymanagerscheduledon"}, + {"OS:AvailabilityManager:ScheduledOff", "group-system-availability-managers.html#availabilitymanagerscheduledoff"}, + {"OS:AvailabilityManager:NightCycle", "group-system-availability-managers.html#availabilitymanagernightcycle"}, + {"OS:AvailabilityManager:DifferentialThermostat", "group-system-availability-managers.html#availabilitymanagerdifferentialthermostat"}, + {"OS:AvailabilityManager:OptimumStart", "group-system-availability-managers.html#availabilitymanageroptimumstart"}, + {"OS:AvailabilityManager:NightVentilation", "group-system-availability-managers.html#availabilitymanagernightventilation"}, + {"OS:AvailabilityManager:HybridVentilation", "group-system-availability-managers.html#availabilitymanagerhybridventilation"}, + {"OS:AvailabilityManager:LowTemperatureTurnOn", "group-system-availability-managers.html#availabilitymanagerlowtemperatureturnon"}, + {"OS:AvailabilityManager:HighTemperatureTurnOff", "group-system-availability-managers.html#availabilitymanagerhightemperatureturnoff"}, + {"OS:AvailabilityManager:LowTemperatureTurnOff", "group-system-availability-managers.html#availabilitymanagerlowtemperatureturnoff"}, + {"OS:AvailabilityManager:HighTemperatureTurnOn", "group-system-availability-managers.html#availabilitymanagerhightemperatureturnon"}, + + // Energy Management System + {"OS:EnergyManagementSystem:Sensor", "group-energy-management-system-ems.html#energymanagementsystemsensor"}, + {"OS:EnergyManagementSystem:Actuator", "group-energy-management-system-ems.html#energymanagementsystemactuator"}, + {"OS:EnergyManagementSystem:Program", "group-energy-management-system-ems.html#energymanagementsystemprogram"}, + {"OS:EnergyManagementSystem:ProgramCallingManager", "group-energy-management-system-ems.html#energymanagementsystemprogramcallingmanager"}, + {"OS:EnergyManagementSystem:GlobalVariable", "group-energy-management-system-ems.html#energymanagementsystemglobalvariable"}, + {"OS:EnergyManagementSystem:OutputVariable", "group-energy-management-system-ems.html#energymanagementsystemoutputvariable"}, + {"OS:EnergyManagementSystem:TrendVariable", "group-energy-management-system-ems.html#energymanagementsystemtrendvariable"}, + {"OS:EnergyManagementSystem:InternalVariable", "group-energy-management-system-ems.html#energymanagementsysteminternalvariable"}, + {"OS:EnergyManagementSystem:ConstructionIndexVariable", "group-energy-management-system-ems.html#energymanagementsystemconstructionindexvariable"}, + + // Performance Curves + {"OS:Curve:Linear", "group-performance-curves.html#curvelinear"}, + {"OS:Curve:Quadratic", "group-performance-curves.html#curvequadratic"}, + {"OS:Curve:Cubic", "group-performance-curves.html#curvecubic"}, + {"OS:Curve:Quartic", "group-performance-curves.html#curvequartic"}, + {"OS:Curve:Exponent", "group-performance-curves.html#curveexponent"}, + {"OS:Curve:Bicubic", "group-performance-curves.html#curvebicubic"}, + {"OS:Curve:Biquadratic", "group-performance-curves.html#curvebiquadratic"}, + {"OS:Curve:QuadraticLinear", "group-performance-curves.html#curvequadraticlinear"}, + {"OS:Curve:CubicLinear", "group-performance-curves.html#curvecubiclinear"}, + {"OS:Curve:Triquadratic", "group-performance-curves.html#curvetriquadratic"}, + {"OS:Curve:FanPressureRise", "group-performance-curves.html#curvefanpressurerise"}, + {"OS:Curve:ExponentialDecay", "group-performance-curves.html#curveexponentialdecay"}, + {"OS:Curve:Sigmoid", "group-performance-curves.html#curvesigmoid"}, + {"OS:Table:IndependentVariable", "group-performance-tables.html#tableindependentvariable"}, + {"OS:Table:IndependentVariableList", "group-performance-tables.html#tableindependentvariablelist"}, + {"OS:Table:Lookup", "group-performance-tables.html#tablelookup"}, + }; + // clang-format on + + auto it = urlMap.constFind(iddTypeName); + if (it != urlMap.constEnd()) { + return base + it.value(); + } + return QString(); +} + +#endif // MODELEDITOR_IDDOBJECTDOCURL_HPP diff --git a/src/model_editor/InspectorGadget.cpp b/src/model_editor/InspectorGadget.cpp index 4d8ff150a..56e04ce85 100644 --- a/src/model_editor/InspectorGadget.cpp +++ b/src/model_editor/InspectorGadget.cpp @@ -6,6 +6,7 @@ #include "InspectorGadget.hpp" #include "BridgeClasses.hpp" +#include "IddObjectDocUrl.hpp" #include "IGLineEdit.hpp" #include "IGSpinBoxes.hpp" @@ -491,9 +492,21 @@ void InspectorGadget::layoutText(QVBoxLayout* layout, QWidget* parent, openstudi if (level == AccessPolicy::LOCKED) { // string stripped(val); // std::replace(stripped.begin(), stripped.end(), '_', ' '); // replace all '_' to ' ' - auto* label = new QLabel(QString(val.c_str()), parent); + auto* label = new QLabel(parent); label->setObjectName("IGHeader"); label->setStyleSheet("font: bold"); + + const QString typeName = QString::fromStdString(val); + const QString docUrl = iddObjectDocUrl(typeName); + if (!docUrl.isEmpty()) { + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + label->setText( + QStringLiteral(R"(%2)").arg(docUrl, typeName.toHtmlEscaped())); + } else { + label->setText(typeName); + } + // Qt::Alignment a = Qt::AlignHCenter; hbox->addWidget(label); diff --git a/src/openstudio_lib/CollapsibleInspector.cpp b/src/openstudio_lib/CollapsibleInspector.cpp index 91a3e6146..b8ab69a45 100644 --- a/src/openstudio_lib/CollapsibleInspector.cpp +++ b/src/openstudio_lib/CollapsibleInspector.cpp @@ -20,6 +20,11 @@ CollapsibleInspector::CollapsibleInspector(QString text, QWidget* inspector, QWi createLayout(); } +CollapsibleInspector::CollapsibleInspector(QString text, QString url, QWidget* inspector, QWidget* parent) + : QWidget(parent), m_header(new CollapsibleInspectorHeader(std::move(text), std::move(url))), m_inspector(inspector) { + createLayout(); +} + void CollapsibleInspector::createLayout() { setContentsMargins(0, 0, 0, 0); @@ -46,7 +51,8 @@ void CollapsibleInspector::on_headerToggled(bool checked) { //////////////////////////////////////////////////////////////////////////////// -CollapsibleInspectorHeader::CollapsibleInspectorHeader(QString text, QWidget* parent) : QAbstractButton(parent), m_text(std::move(text)) { +CollapsibleInspectorHeader::CollapsibleInspectorHeader(QString text, QString url, QWidget* parent) + : QAbstractButton(parent), m_text(std::move(text)), m_url(std::move(url)) { createLayout(); } @@ -67,9 +73,16 @@ void CollapsibleInspectorHeader::createLayout() { mainHLayout->addWidget(m_arrowLabel, 0, Qt::AlignLeft); // Name - auto* textLabel = new QLabel(m_text); + auto* textLabel = new QLabel(); textLabel->setWordWrap(false); textLabel->setObjectName("H2"); + if (!m_url.isEmpty()) { + textLabel->setTextFormat(Qt::RichText); + textLabel->setOpenExternalLinks(true); + textLabel->setText(QStringLiteral(R"(%2)").arg(m_url, m_text.toHtmlEscaped())); + } else { + textLabel->setText(m_text); + } mainHLayout->addWidget(textLabel, 0, Qt::AlignLeft); // Stretch diff --git a/src/openstudio_lib/CollapsibleInspector.hpp b/src/openstudio_lib/CollapsibleInspector.hpp index 71cce79e0..855e59639 100644 --- a/src/openstudio_lib/CollapsibleInspector.hpp +++ b/src/openstudio_lib/CollapsibleInspector.hpp @@ -22,6 +22,7 @@ class CollapsibleInspector : public QWidget public: CollapsibleInspector(QString text, QWidget* inspector, QWidget* parent = nullptr); + CollapsibleInspector(QString text, QString url, QWidget* inspector, QWidget* parent = nullptr); virtual ~CollapsibleInspector() {} @@ -42,7 +43,7 @@ class CollapsibleInspectorHeader : public QAbstractButton Q_OBJECT public: - explicit CollapsibleInspectorHeader(QString text, QWidget* parent = nullptr); + explicit CollapsibleInspectorHeader(QString text, QString url = {}, QWidget* parent = nullptr); void setChecked(bool isChecked); @@ -57,6 +58,7 @@ class CollapsibleInspectorHeader : public QAbstractButton void setImage(bool isChecked); QString m_text; + QString m_url; QLabel* m_arrowLabel; diff --git a/src/openstudio_lib/SimSettingsView.cpp b/src/openstudio_lib/SimSettingsView.cpp index 2ccf1d369..4acac647c 100644 --- a/src/openstudio_lib/SimSettingsView.cpp +++ b/src/openstudio_lib/SimSettingsView.cpp @@ -239,7 +239,9 @@ void SimSettingsView::createWidgets() { //******************* OS:Timestep ******************* mainLayout->addWidget(createTimestepWidget()); - collapsibleInspector = new CollapsibleInspector(tr("Advanced RunPeriod Parameters"), createRunPeriodAdvancedWidget()); + static const QString iorf = QStringLiteral("https://bigladdersoftware.com/epx/docs/25-1/input-output-reference/"); + + collapsibleInspector = new CollapsibleInspector(tr("Advanced RunPeriod Parameters"), iorf + "group-location-climate-weather-file-access.html#runperiod", createRunPeriodAdvancedWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:RadianceParameters ******************* @@ -247,7 +249,7 @@ void SimSettingsView::createWidgets() { mainLayout->addWidget(collapsibleInspector); //******************* OS:SimulationControl ******************* - collapsibleInspector = new CollapsibleInspector(tr("Simulation Control"), createSimulationControlWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Simulation Control"), iorf + "group-simulation-parameters.html#simulationcontrol", createSimulationControlWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ProgramControl ******************* @@ -255,56 +257,55 @@ void SimSettingsView::createWidgets() { mainLayout->addWidget(collapsibleInspector); //******************* OS:OutputControl:ReportingTolerances ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Control Reporting Tolerances"), createOutputControlReportingTolerancesWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Output Control Reporting Tolerances"), iorf + "input-for-output.html#outputcontrolreportingtolerances", createOutputControlReportingTolerancesWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ConvergenceLimits ******************* - collapsibleInspector = new CollapsibleInspector(tr("Convergence Limits"), createConvergenceLimitsWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Convergence Limits"), iorf + "group-simulation-parameters.html#convergencelimits", createConvergenceLimitsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ShadowCalculation ******************* - collapsibleInspector = new CollapsibleInspector(tr("Shadow Calculation"), createShadowCalculationWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Shadow Calculation"), iorf + "group-simulation-parameters.html#shadowcalculation", createShadowCalculationWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:SurfaceConvectionAlgorithm:Inside ******************* - collapsibleInspector = new CollapsibleInspector(tr("Inside Surface Convection Algorithm"), createSurfaceConvectionAlgorithmInsideWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Inside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithminside", createSurfaceConvectionAlgorithmInsideWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:SurfaceConvectionAlgorithm:Outside ******************* - collapsibleInspector = new CollapsibleInspector(tr("Outside Surface Convection Algorithm"), createSurfaceConvectionAlgorithmOutsideWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Outside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithmoutside", createSurfaceConvectionAlgorithmOutsideWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:HeatBalanceAlgorithm ******************* - collapsibleInspector = new CollapsibleInspector(tr("Heat Balance Algorithm"), createHeatBalanceAlgorithmWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#heatbalancealgorithm", createHeatBalanceAlgorithmWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirHeatBalanceAlgorithm ******************* - collapsibleInspector = new CollapsibleInspector(tr("Zone Air Heat Balance Algorithm"), createZoneAirHeatBalanceAlgorithmWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Zone Air Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#zoneairheatbalancealgorithm", createZoneAirHeatBalanceAlgorithmWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirContaminantBalance ******************* - collapsibleInspector = new CollapsibleInspector(tr("Zone Air Contaminant Balance"), createZoneAirContaminantBalanceWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Zone Air Contaminant Balance"), iorf + "group-simulation-parameters.html#zoneaircontaminantbalance", createZoneAirContaminantBalanceWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneCapacitanceMultiplier:ResearchSpecial ******************* - collapsibleInspector = - new CollapsibleInspector(tr("Zone Capacitance Multiple Research Special"), createZoneCapacitanceMultipleResearchSpecialWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Zone Capacitance Multiple Research Special"), iorf + "group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial", createZoneCapacitanceMultipleResearchSpecialWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:JSON ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output JSON"), createOutputJSONWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Output JSON"), iorf + "input-for-output.html#outputjson", createOutputJSONWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:Table:SummaryReports ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Table Summary Reports"), createOutputTableSummaryReportsWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Output Table Summary Reports"), iorf + "output-table-summaryreports.html#outputtablesummaryreports", createOutputTableSummaryReportsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:Diagnostics ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Diagnostics"), createOutputDiagnosticsWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Output Diagnostics"), iorf + "group-simulation-parameters.html#outputdiagnostics", createOutputDiagnosticsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:OutputControl:ResilienceSummaries ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Control Resilience Summaries"), createOutputControlResilienceSummariesWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Output Control Resilience Summaries"), iorf + "input-for-output.html#OutputControlResilienceSummaries", createOutputControlResilienceSummariesWidget()); mainLayout->addWidget(collapsibleInspector); mainLayout->addStretch(); @@ -325,8 +326,11 @@ QWidget* SimSettingsView::createRunPeriodWidget() { QHBoxLayout* hLayout = nullptr; - label = new QLabel(tr("Run Period")); + label = new QLabel(); label->setObjectName("H1"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + label->setText(QStringLiteral(R"(%1)").arg(tr("Run Period"))); mainVLayout->addWidget(label); mainVLayout->addLayout(mainHLayout); @@ -602,8 +606,11 @@ QWidget* SimSettingsView::createSizingParametersWidget() { QLabel* label = nullptr; - label = new QLabel(tr("Sizing Parameters")); + label = new QLabel(); label->setObjectName("H1"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + label->setText(QStringLiteral(R"(%1)").arg(tr("Sizing Parameters"))); mainLayout->addWidget(label); auto* gridLayout = new QGridLayout(); @@ -652,8 +659,11 @@ QWidget* SimSettingsView::createTimestepWidget() { QLabel* label = nullptr; - label = new QLabel(tr("Timestep")); + label = new QLabel(); label->setObjectName("H1"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + label->setText(QStringLiteral(R"(%1)").arg(tr("Timestep"))); mainLayout->addWidget(label); auto* gridLayout = new QGridLayout(); From 38e13fc7faac5e4c87fde93d7af350d6f603f219 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 11:07:01 +0200 Subject: [PATCH 02/18] fix: address PR #876 review comments - Define ENERGYPLUS_VERSION_MAJOR/MINOR and BIGLADDERSOFTWARE_DOC_BASE_URL in FindOpenStudioSDK.cmake (single source of truth for the BigLadder URL base); pass to C++ via target_compile_definitions in model_editor and openstudio_lib; remove hardcoded URL strings from IddObjectDocUrl.hpp and SimSettingsView.cpp - Rename layoutText header overload to layoutHeaderText, drop unused level/ index parameters per macumber's cleaned-up version - Add setToolTip(docUrl) to all clickable doc links so the URL is visible on hover before clicking (InspectorGadget header, CollapsibleInspector section headers, SimSettings H1 labels) Co-Authored-By: Claude Sonnet 4.6 --- FindOpenStudioSDK.cmake | 4 ++ src/model_editor/CMakeLists.txt | 3 ++ src/model_editor/IddObjectDocUrl.hpp | 7 +-- src/model_editor/InspectorGadget.cpp | 56 ++++++++------------- src/model_editor/InspectorGadget.hpp | 3 +- src/openstudio_lib/CMakeLists.txt | 3 ++ src/openstudio_lib/CollapsibleInspector.cpp | 1 + src/openstudio_lib/SimSettingsView.cpp | 20 ++++++-- 8 files changed, 54 insertions(+), 43 deletions(-) diff --git a/FindOpenStudioSDK.cmake b/FindOpenStudioSDK.cmake index a838253a9..9712cc5ae 100644 --- a/FindOpenStudioSDK.cmake +++ b/FindOpenStudioSDK.cmake @@ -8,6 +8,10 @@ set(OPENSTUDIO_VERSION_PRERELEASE "") # Enter SHA, always, eg "+79857912c4" set(OPENSTUDIO_VERSION_SHA "+241b8abb4d") +set(ENERGYPLUS_VERSION_MAJOR 25) +set(ENERGYPLUS_VERSION_MINOR 1) +set(BIGLADDERSOFTWARE_DOC_BASE_URL "https://bigladdersoftware.com/epx/docs/${ENERGYPLUS_VERSION_MAJOR}-${ENERGYPLUS_VERSION_MINOR}/input-output-reference/") + # Paths where the cmake-downloaded archives will be put set(OPENSTUDIO_ARCHIVE_DIR "${PROJECT_BINARY_DIR}/OpenStudio-${OPENSTUDIO_VERSION}") diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index 63aca23c1..c8ee35816 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -103,6 +103,9 @@ else() target_compile_definitions(${target_name} PUBLIC model_editor_EXPORTS) endif() +target_compile_definitions(${target_name} PRIVATE + "BIGLADDERSOFTWARE_DOC_BASE_URL=\"${BIGLADDERSOFTWARE_DOC_BASE_URL}\"") + set(${target_name}_test_src test/ModelEditorFixture.hpp test/ModelEditorFixture.cpp diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index ff3aacc84..91bf84339 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -9,10 +9,11 @@ #include #include -// Returns the BigLadder EnergyPlus 25.1 Input/Output Reference URL for the given -// OS IDD type name (e.g. "OS:ThermalZone"), or an empty string if none is known. +// Returns the BigLadder EnergyPlus I/O Reference URL for the given OS IDD type name +// (e.g. "OS:ThermalZone"), or an empty string if none is known. +// Base URL version is controlled by ENERGYPLUS_VERSION_MAJOR/MINOR in FindOpenStudioSDK.cmake. inline QString iddObjectDocUrl(const QString& iddTypeName) { - static const QString base = QStringLiteral("https://bigladdersoftware.com/epx/docs/25-1/input-output-reference/"); + static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); // clang-format off static const QHash urlMap{ diff --git a/src/model_editor/InspectorGadget.cpp b/src/model_editor/InspectorGadget.cpp index 56e04ce85..5bb4c6084 100644 --- a/src/model_editor/InspectorGadget.cpp +++ b/src/model_editor/InspectorGadget.cpp @@ -290,7 +290,7 @@ void InspectorGadget::layoutItems(QVBoxLayout* masterLayout, QWidget* parent, bo hlayout->setContentsMargins(0, 0, 0, 0); masterLayout->addLayout(hlayout); hlayout->addLayout(layout); - layoutText(layout, parent, AccessPolicy::LOCKED, iddObj.type().valueDescription(), -1, comment); + layoutHeaderText(layout, parent, iddObj.type().valueDescription(), comment); const AccessPolicy* pAccessPolicy = AccessPolicyStore::Instance().getPolicy(iddObj.type()); @@ -479,8 +479,7 @@ void InspectorGadget::parseItem(QVBoxLayout* layout, QWidget* parent, openstudio } } -void InspectorGadget::layoutText(QVBoxLayout* layout, QWidget* parent, openstudio::model::AccessPolicy::ACCESS_LEVEL level, const std::string& val, - int index, const std::string& comment) { +void InspectorGadget::layoutHeaderText(QVBoxLayout* layout, QWidget* parent, const std::string& val, const std::string& comment) { auto* frame = new QFrame(parent); frame->setContentsMargins(0, 0, 0, 0); auto* hbox = new QHBoxLayout(); @@ -489,42 +488,31 @@ void InspectorGadget::layoutText(QVBoxLayout* layout, QWidget* parent, openstudi hbox->setSpacing(0); hbox->setContentsMargins(0, 0, 0, 0); - if (level == AccessPolicy::LOCKED) { - // string stripped(val); - // std::replace(stripped.begin(), stripped.end(), '_', ' '); // replace all '_' to ' ' - auto* label = new QLabel(parent); - label->setObjectName("IGHeader"); - label->setStyleSheet("font: bold"); - - const QString typeName = QString::fromStdString(val); - const QString docUrl = iddObjectDocUrl(typeName); - if (!docUrl.isEmpty()) { - label->setTextFormat(Qt::RichText); - label->setOpenExternalLinks(true); - label->setText( - QStringLiteral(R"(%2)").arg(docUrl, typeName.toHtmlEscaped())); - } else { - label->setText(typeName); - } - - // Qt::Alignment a = Qt::AlignHCenter; - hbox->addWidget(label); - - hbox->addStretch(); + // string stripped(val); + // std::replace(stripped.begin(), stripped.end(), '_', ' '); // replace all '_' to ' ' + auto* label = new QLabel(parent); + label->setObjectName("IGHeader"); + label->setStyleSheet("font: bold"); + + const QString typeName = QString::fromStdString(val); + const QString docUrl = iddObjectDocUrl(typeName); + if (!docUrl.isEmpty()) { + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + label->setToolTip(docUrl); + label->setText( + QStringLiteral(R"(%2)").arg(docUrl, typeName.toHtmlEscaped())); } else { - //QLineEdit* text = new QLineEdit( QString(val.c_str()), parent ); - auto* text = new IGLineEdit(QString(val.c_str()), this, parent); - hbox->addWidget(text); - text->setProperty(s_indexSlotName, index); + label->setText(typeName); + } - //connect(text, &IGLineEdit::textEdited, this, &InspectorGadget::IGvalueChanged, Qt::QueuedConnection); + // Qt::Alignment a = Qt::AlignHCenter; + hbox->addWidget(label); - connect(text, &IGLineEdit::editingFinished, text, &IGLineEdit::editDone); - connect(text, &IGLineEdit::newValue, this, &InspectorGadget::IGvalueChanged); - } + hbox->addStretch(); auto* commentText = new QLineEdit(QString(comment.c_str()), parent); - commentText->setProperty(s_indexSlotName, index); + commentText->setProperty(s_indexSlotName, -1); connect(commentText, &QLineEdit::textEdited, this, &InspectorGadget::IGcommentChanged); if (!m_showComments) { commentText->hide(); diff --git a/src/model_editor/InspectorGadget.hpp b/src/model_editor/InspectorGadget.hpp index 3dcfb8953..4f5446625 100644 --- a/src/model_editor/InspectorGadget.hpp +++ b/src/model_editor/InspectorGadget.hpp @@ -248,8 +248,7 @@ class MODELEDITOR_API InspectorGadget void parseItem(QVBoxLayout* layout, QWidget* parent, openstudio::IddField& field, const std::string& name, const std::string& curVal, openstudio::model::AccessPolicy::ACCESS_LEVEL level, int index, const std::string& comment, bool exists); - void layoutText(QVBoxLayout* layout, QWidget* parent, openstudio::model::AccessPolicy::ACCESS_LEVEL level, const std::string& val, int index, - const std::string& comment); + void layoutHeaderText(QVBoxLayout* layout, QWidget* parent, const std::string& val, const std::string& comment); void layoutText(QVBoxLayout* layout, QWidget* parent, openstudio::IddField& field, openstudio::model::AccessPolicy::ACCESS_LEVEL level, const std::string& name, const std::string& curVal, int index, const std::string& comment, bool exists, bool number, diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 28977df89..143c5bbb4 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -778,6 +778,9 @@ if (NINJA) target_compile_definitions(${target_name} PRIVATE NINJA=1) endif() +target_compile_definitions(${target_name} PRIVATE + "BIGLADDERSOFTWARE_DOC_BASE_URL=\"${BIGLADDERSOFTWARE_DOC_BASE_URL}\"") + set(${target_name}_depends openstudio_modeleditor openstudio::openstudiolib diff --git a/src/openstudio_lib/CollapsibleInspector.cpp b/src/openstudio_lib/CollapsibleInspector.cpp index b8ab69a45..a7a14c470 100644 --- a/src/openstudio_lib/CollapsibleInspector.cpp +++ b/src/openstudio_lib/CollapsibleInspector.cpp @@ -79,6 +79,7 @@ void CollapsibleInspectorHeader::createLayout() { if (!m_url.isEmpty()) { textLabel->setTextFormat(Qt::RichText); textLabel->setOpenExternalLinks(true); + textLabel->setToolTip(m_url); textLabel->setText(QStringLiteral(R"(%2)").arg(m_url, m_text.toHtmlEscaped())); } else { textLabel->setText(m_text); diff --git a/src/openstudio_lib/SimSettingsView.cpp b/src/openstudio_lib/SimSettingsView.cpp index 4acac647c..9c5fcbc40 100644 --- a/src/openstudio_lib/SimSettingsView.cpp +++ b/src/openstudio_lib/SimSettingsView.cpp @@ -239,7 +239,7 @@ void SimSettingsView::createWidgets() { //******************* OS:Timestep ******************* mainLayout->addWidget(createTimestepWidget()); - static const QString iorf = QStringLiteral("https://bigladdersoftware.com/epx/docs/25-1/input-output-reference/"); + static const QString iorf = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); collapsibleInspector = new CollapsibleInspector(tr("Advanced RunPeriod Parameters"), iorf + "group-location-climate-weather-file-access.html#runperiod", createRunPeriodAdvancedWidget()); mainLayout->addWidget(collapsibleInspector); @@ -330,7 +330,11 @@ QWidget* SimSettingsView::createRunPeriodWidget() { label->setObjectName("H1"); label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); - label->setText(QStringLiteral(R"(%1)").arg(tr("Run Period"))); + { + static const QString url = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-location-climate-weather-file-access.html#runperiod"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)").arg(url, tr("Run Period"))); + } mainVLayout->addWidget(label); mainVLayout->addLayout(mainHLayout); @@ -610,7 +614,11 @@ QWidget* SimSettingsView::createSizingParametersWidget() { label->setObjectName("H1"); label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); - label->setText(QStringLiteral(R"(%1)").arg(tr("Sizing Parameters"))); + { + static const QString url = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-design-objects.html#sizingparameters"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)").arg(url, tr("Sizing Parameters"))); + } mainLayout->addWidget(label); auto* gridLayout = new QGridLayout(); @@ -663,7 +671,11 @@ QWidget* SimSettingsView::createTimestepWidget() { label->setObjectName("H1"); label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); - label->setText(QStringLiteral(R"(%1)").arg(tr("Timestep"))); + { + static const QString url = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-simulation-parameters.html#timestep"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)").arg(url, tr("Timestep"))); + } mainLayout->addWidget(label); auto* gridLayout = new QGridLayout(); From 770431226f5911fc32878702f60fa5afa807e438 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 13:06:45 +0200 Subject: [PATCH 03/18] feat: add 11 missing IDD type URL mappings - OS:Schedule:Day - OS:Coil:Cooling:DX:TwoStageWithHumidityControlMode - OS:Coil:Cooling:DX:MultiSpeed:StageData - OS:Coil:Cooling:Water:Panel:Radiant - OS:Coil:Heating:Gas:MultiStage + :StageData - OS:Coil:Heating:LowTemperatureRadiant:ConstantFlow + :VariableFlow - OS:Coil:Heating:Water:Baseboard:Radiant - OS:Coil:WaterHeating:AirToWaterHeatPump - OS:SetpointManager:FollowSystemNodeTemperature Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/IddObjectDocUrl.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 91bf84339..3aae4f016 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -42,6 +42,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:ScheduleTypeLimits", "group-schedules.html#scheduletypelimits"}, {"OS:Schedule:Compact", "group-schedules.html#schedulecompact"}, {"OS:Schedule:Constant", "group-schedules.html#scheduleconstant"}, + {"OS:Schedule:Day", "group-schedules.html#day-schedules"}, {"OS:Schedule:Day:Hourly", "group-schedules.html#scheduledayhourly"}, {"OS:Schedule:Day:Interval", "group-schedules.html#scheduledayinterval"}, {"OS:Schedule:Week:Daily", "group-schedules.html#scheduleweekdaily"}, @@ -192,6 +193,9 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Coil:Cooling:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpequationfit"}, {"OS:Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpvariablespeedequationfit"}, {"OS:Coil:Cooling:FourPipeBeam", "group-heating-and-cooling-coils.html#coilcoolingfourpipebeam"}, + {"OS:Coil:Cooling:DX:TwoStageWithHumidityControlMode", "group-heating-and-cooling-coils.html#coilcoolingdxtwostagewithhumiditycontrolmode"}, + {"OS:Coil:Cooling:DX:MultiSpeed:StageData", "group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, + {"OS:Coil:Cooling:Water:Panel:Radiant", "group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, // Coils - Heating {"OS:Coil:Heating:Gas", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, @@ -207,6 +211,12 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpvariablespeedequationfit"}, {"OS:Coil:Heating:Desuperheater", "group-heating-and-cooling-coils.html#coilheatingdesuperheater"}, {"OS:Coil:Heating:FourPipeBeam", "group-heating-and-cooling-coils.html#coilheatingfourpipebeam"}, + {"OS:Coil:Heating:Gas:MultiStage", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, + {"OS:Coil:Heating:Gas:MultiStage:StageData", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, + {"OS:Coil:Heating:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, + {"OS:Coil:Heating:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflowdesign"}, + {"OS:Coil:Heating:Water:Baseboard:Radiant", "group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, + {"OS:Coil:WaterHeating:AirToWaterHeatPump", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, {"OS:Coil:WaterHeating:AirToWaterHeatPump:Pumped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, {"OS:Coil:WaterHeating:AirToWaterHeatPump:Wrapped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumpwrapped"}, {"OS:Coil:WaterHeating:Desuperheater", "group-heating-and-cooling-coils.html#coilwaterheatingdesuperheater"}, @@ -262,6 +272,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:SetpointManager:OutdoorAirPretreat", "group-setpoint-managers.html#setpointmanageroutdoorairpretreat"}, {"OS:SetpointManager:MultiZone:Heating:Average", "group-setpoint-managers.html#setpointmanagermultizoneheataverage"}, {"OS:SetpointManager:MultiZone:Cooling:Average", "group-setpoint-managers.html#setpointmanagermultizonecoolaverage"}, + {"OS:SetpointManager:FollowSystemNodeTemperature", "group-setpoint-managers.html#setpointmanagerfollowsystemnodetemperature"}, // Pumps {"OS:Pump:VariableSpeed", "group-pumps.html#pumpvariablespeed"}, From 4b4f355d45b5f5ec8823eb1311029ed9c9aed8bc Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 18:04:11 +0200 Subject: [PATCH 04/18] feat: add 37 more IDD type URL mappings Adds BigLadder doc URL mappings for: LowTemperatureRadiant coils, CoilPerformance:DX:Cooling, Coil:Heating:Water:Baseboard, 10 setpoint managers (MultiZone/SingleZone humidity, SingleZone stage, SystemNodeReset), SolarCollectorPerformance x2, Chiller:Absorption, CentralHeatPumpSystem:Module, PlantComponent:TemperatureSource/UserDefined, CoolingTower:VariableSpeed, CoolingTowerPerformance x2, Pipe:Indoor/Outdoor/Duct, TemperingValve, LoadProfile:Plant, Fan:ComponentModel, Site:GroundTemperature:Undisturbed:KusudaAchenbach, SwimmingPool:Indoor, AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction, and 5 new curve types. Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/IddObjectDocUrl.hpp | 47 +++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 3aae4f016..3d202a2fa 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -30,7 +30,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:ZoneAirContaminantBalance", "group-simulation-parameters.html#zoneaircontaminantbalance"}, // Location and Climate - {"OS:Site:Location", "group-location-climate-weather-file-access.html#sitelocation"}, + {"OS:Site:Location", "group-location-climate-weather-file-access.html#sitelocation"}, + {"OS:Site:GroundTemperature:Undisturbed:KusudaAchenbach", "group-location-climate-weather-file-access.html#sitegroundtemperatureundisturbedkusudaachenbach"}, {"OS:Site:GroundTemperature:BuildingSurface", "group-location-climate-weather-file-access.html#sitegroundtemperaturebuildingsurface"}, {"OS:Site:GroundTemperature:FCfactorMethod", "group-location-climate-weather-file-access.html#sitegroundtemperaturefcfactormethod"}, {"OS:Site:GroundReflectance", "group-location-climate-weather-file-access.html#sitegroundreflectance"}, @@ -94,6 +95,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:SteamEquipment", "group-internal-gains-people-lights-other.html#steamequipment"}, {"OS:OtherEquipment", "group-internal-gains-people-lights-other.html#otherequipment"}, {"OS:InternalMass", "group-internal-gains-people-lights-other.html#internalmass"}, + {"OS:SwimmingPool:Indoor", "group-internal-gains-people-lights-other.html#swimmingpoolindoor"}, // Exterior Energy Use {"OS:Exterior:Lights", "group-exterior-energy-use-equipment.html#exteriorlights"}, @@ -172,7 +174,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:AirTerminal:DualDuct:VAV", "group-air-distribution-equipment.html#airterminaldualductvav"}, {"OS:AirTerminal:DualDuct:VAV:OutdoorAir", "group-air-distribution-equipment.html#airterminaldualductvavoutdoorair"}, {"OS:AirTerminal:DualDuct:ConstantVolume", "group-air-distribution-equipment.html#airterminaldualductconstantvolume"}, - {"OS:AirTerminal:FourPipeInduction", "group-air-distribution-equipment.html#airterminalfourpipeinduction"}, + {"OS:AirTerminal:FourPipeInduction", "group-air-distribution-equipment.html#airterminalfourpipeinduction"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipeinduction"}, // Fans {"OS:Fan:ConstantVolume", "group-fans.html#fanconstantvolume"}, @@ -180,6 +183,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Fan:OnOff", "group-fans.html#fanonoff"}, {"OS:Fan:ZoneExhaust", "group-fans.html#fanzoneexhaust"}, {"OS:Fan:SystemModel", "group-fans.html#fansystemmodel"}, + {"OS:Fan:ComponentModel", "group-fans.html#fancomponentmodel"}, // Coils - Cooling {"OS:Coil:Cooling:DX:SingleSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxsinglespeed"}, @@ -196,6 +200,9 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Coil:Cooling:DX:TwoStageWithHumidityControlMode", "group-heating-and-cooling-coils.html#coilcoolingdxtwostagewithhumiditycontrolmode"}, {"OS:Coil:Cooling:DX:MultiSpeed:StageData", "group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, {"OS:Coil:Cooling:Water:Panel:Radiant", "group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, + {"OS:Coil:Cooling:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, + {"OS:Coil:Cooling:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflow"}, + {"OS:CoilPerformance:DX:Cooling", "group-heating-and-cooling-coils.html#coilperformancedxcooling"}, // Coils - Heating {"OS:Coil:Heating:Gas", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, @@ -215,6 +222,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Coil:Heating:Gas:MultiStage:StageData", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, {"OS:Coil:Heating:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, {"OS:Coil:Heating:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflowdesign"}, + {"OS:Coil:Heating:Water:Baseboard", "group-radiative-convective-units.html#zonehvacbaseboardconvectivewater"}, {"OS:Coil:Heating:Water:Baseboard:Radiant", "group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, {"OS:Coil:WaterHeating:AirToWaterHeatPump", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, {"OS:Coil:WaterHeating:AirToWaterHeatPump:Pumped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, @@ -272,7 +280,17 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:SetpointManager:OutdoorAirPretreat", "group-setpoint-managers.html#setpointmanageroutdoorairpretreat"}, {"OS:SetpointManager:MultiZone:Heating:Average", "group-setpoint-managers.html#setpointmanagermultizoneheataverage"}, {"OS:SetpointManager:MultiZone:Cooling:Average", "group-setpoint-managers.html#setpointmanagermultizonecoolaverage"}, - {"OS:SetpointManager:FollowSystemNodeTemperature", "group-setpoint-managers.html#setpointmanagerfollowsystemnodetemperature"}, + {"OS:SetpointManager:FollowSystemNodeTemperature", "group-setpoint-managers.html#setpointmanagerfollowsystemnodetemperature"}, + {"OS:SetpointManager:MultiZone:Humidity:Maximum", "group-setpoint-managers.html#setpointmanagermultizonehumiditymaximum"}, + {"OS:SetpointManager:MultiZone:Humidity:Minimum", "group-setpoint-managers.html#setpointmanagermultizonehumidityminimum"}, + {"OS:SetpointManager:MultiZone:MaximumHumidity:Average", "group-setpoint-managers.html#setpointmanagermultizonemaximumhumidityaverage"}, + {"OS:SetpointManager:MultiZone:MinimumHumidity:Average", "group-setpoint-managers.html#setpointmanagermultizoneminimumhumidityaverage"}, + {"OS:SetpointManager:SingleZone:Humidity:Maximum", "group-setpoint-managers.html#setpointmanagersinglezonehumiditymaximum"}, + {"OS:SetpointManager:SingleZone:Humidity:Minimum", "group-setpoint-managers.html#setpointmanagersinglezonehumidityminimum"}, + {"OS:SetpointManager:SingleZone:OneStageCooling", "group-setpoint-managers.html#setpointmanagersinglezoneonestagecooling"}, + {"OS:SetpointManager:SingleZone:OneStageHeating", "group-setpoint-managers.html#setpointmanagersinglezoneonestageheating"}, + {"OS:SetpointManager:SystemNodeReset:Humidity", "group-setpoint-managers.html#setpointmanagersystemnoderesethumidity"}, + {"OS:SetpointManager:SystemNodeReset:Temperature", "group-setpoint-managers.html#setpointmanagersystemnoderesettemperature"}, // Pumps {"OS:Pump:VariableSpeed", "group-pumps.html#pumpvariablespeed"}, @@ -285,12 +303,15 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:SolarCollector:IntegralCollectorStorage", "group-solar-collectors.html#solarcollectorintegralcollectorstorage"}, {"OS:SolarCollector:UnglazedTranspired", "group-solar-collectors.html#solarcollectorunglazedtranspired"}, {"OS:SolarCollector:FlatPlate:PhotovoltaicThermal", "group-solar-collectors.html#solarcollectorflatplatephotovoltaicthermal"}, + {"OS:SolarCollectorPerformance:FlatPlate", "group-solar-collectors.html#solarcollectorperformanceflatplate"}, + {"OS:SolarCollectorPerformance:IntegralCollectorStorage", "group-solar-collectors.html#solarcollectorperformanceintegralcollectorstorage"}, // Plant Heating and Cooling Equipment {"OS:Boiler:HotWater", "group-plant-equipment.html#boilerhotwater"}, {"OS:Boiler:Steam", "group-plant-equipment.html#boilersteam"}, {"OS:Chiller:Electric:EIR", "group-plant-equipment.html#chillerelectriceir"}, {"OS:Chiller:Electric:ReformulatedEIR", "group-plant-equipment.html#chillerelectricreformulatedeir"}, + {"OS:Chiller:Absorption", "group-plant-equipment.html#chillerabsorption"}, {"OS:Chiller:Absorption:Indirect", "group-plant-equipment.html#chillerabsorptionindirect"}, {"OS:Chiller:Absorption:Direct", "group-plant-equipment.html#chillerabsorptiondirect"}, {"OS:ChillerHeater:Absorption:DirectFired", "group-plant-equipment.html#chillerheaterabsorptiondirectfired"}, @@ -307,12 +328,18 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:HeatPump:AirToWater:Cooling", "group-plant-equipment.html#plhp_air_to_water"}, {"OS:HeatPump:AirToWater:Heating", "group-plant-equipment.html#plhp_air_to_water"}, {"OS:CentralHeatPumpSystem", "group-plant-equipment.html#centralheatpumpsystem"}, + {"OS:CentralHeatPumpSystem:Module", "group-plant-equipment.html#centralheatpumpsystem"}, {"OS:ChillerHeaterPerformance:Electric:EIR", "group-plant-equipment.html#chillerheaterperformancelectriceir"}, + {"OS:PlantComponent:TemperatureSource", "group-plant-equipment.html#plantcomponenttemperaturesource"}, + {"OS:PlantComponent:UserDefined", "group-user-defined-hvac-and-plant-component.html#plantcomponentuserdefined"}, // Cooling Towers and Fluid Coolers {"OS:CoolingTower:SingleSpeed", "group-condenser-equipment.html#coolingtowersinglespeed"}, {"OS:CoolingTower:TwoSpeed", "group-condenser-equipment.html#coolingtowertwospeed"}, + {"OS:CoolingTower:VariableSpeed", "group-condenser-equipment.html#coolingtowervariablespeed"}, {"OS:CoolingTower:VariableSpeed:Merkel", "group-condenser-equipment.html#coolingtowervariablespeedmerkel"}, + {"OS:CoolingTowerPerformance:CoolTools", "group-condenser-equipment.html#coolingtowerperformancecooltools"}, + {"OS:CoolingTowerPerformance:YorkCalc", "group-condenser-equipment.html#coolingtowerperformanceyorkcalc"}, {"OS:EvaporativeFluidCooler:SingleSpeed", "group-condenser-equipment.html#evaporativefluidcoolersinglespeed"}, {"OS:EvaporativeFluidCooler:TwoSpeed", "group-condenser-equipment.html#evaporativefluidcoolertwospeed"}, {"OS:FluidCooler:SingleSpeed", "group-condenser-equipment.html#fluidcoolersinglespeed"}, @@ -363,6 +390,9 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { // Node / Branch Management {"OS:Pipe:Adiabatic", "group-node-branch-management.html#pipeadiabatic"}, + {"OS:Pipe:Indoor", "group-node-branch-management.html#pipeindoor"}, + {"OS:Pipe:Outdoor", "group-node-branch-management.html#pipeoutdoor"}, + {"OS:Duct", "group-node-branch-management.html#duct"}, // Plant / Condenser Control {"OS:PlantLoop", "group-plant-condenser-control.html#plantloop"}, @@ -375,6 +405,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:PlantEquipmentOperation:OutdoorWetBulb", "group-plant-condenser-control.html#plantequipmentoperationoutdoorwetbulb"}, {"OS:PlantEquipmentOperation:ThermalEnergyStorage", "group-plant-condenser-control.html#plantequipmentoperationthermalenergystorage"}, {"OS:PlantEquipmentOperation:Uncontrolled", "group-plant-condenser-control.html#plantequipmentoperationuncontrolled"}, + {"OS:TemperingValve", "group-plant-condenser-flow-control.html#temperingvalve"}, + {"OS:LoadProfile:Plant", "group-non-zone-equipment.html#loadprofileplant"}, {"OS:AvailabilityManagerAssignmentList", "group-system-availability-managers.html#availabilitymanagerassignmentlist"}, {"OS:AvailabilityManager:Scheduled", "group-system-availability-managers.html#availabilitymanagerscheduled"}, {"OS:AvailabilityManager:ScheduledOn", "group-system-availability-managers.html#availabilitymanagerscheduledon"}, @@ -412,8 +444,13 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Curve:CubicLinear", "group-performance-curves.html#curvecubiclinear"}, {"OS:Curve:Triquadratic", "group-performance-curves.html#curvetriquadratic"}, {"OS:Curve:FanPressureRise", "group-performance-curves.html#curvefanpressurerise"}, - {"OS:Curve:ExponentialDecay", "group-performance-curves.html#curveexponentialdecay"}, - {"OS:Curve:Sigmoid", "group-performance-curves.html#curvesigmoid"}, + {"OS:Curve:ExponentialDecay", "group-performance-curves.html#curveexponentialdecay"}, + {"OS:Curve:ExponentialSkewNormal", "group-performance-curves.html#curveexponentialskewnormal"}, + {"OS:Curve:Sigmoid", "group-performance-curves.html#curvesigmoid"}, + {"OS:Curve:QuadLinear", "group-performance-curves.html#curvequadlinear"}, + {"OS:Curve:QuintLinear", "group-performance-curves.html#curvequintlinear"}, + {"OS:Curve:RectangularHyperbola1", "group-performance-curves.html#curverectangularhyperbola1"}, + {"OS:Curve:RectangularHyperbola2", "group-performance-curves.html#curverectangularhyperbola2"}, {"OS:Table:IndependentVariable", "group-performance-tables.html#tableindependentvariable"}, {"OS:Table:IndependentVariableList", "group-performance-tables.html#tableindependentvariablelist"}, {"OS:Table:Lookup", "group-performance-tables.html#tablelookup"}, From 74162405ac7e7228e46d037cf4d6ce91488f4540 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 20:45:55 +0200 Subject: [PATCH 05/18] feat: add clickable doc links to sidebar category headers Extends OSCollapsibleItemHeader to optionally render its text as a clickable BigLadder hyperlink. Adds a URL-aware constructor to ModelObjectTypeListView. Applies links to four left-sidebar panels: Loads, Constructions (subtab), Materials (subtab), and Other Schedules. Co-Authored-By: Claude Sonnet 4.6 --- src/openstudio_lib/ConstructionsView.cpp | 35 ++++++----- src/openstudio_lib/ConstructionsView.hpp | 5 +- src/openstudio_lib/LoadsView.cpp | 41 +++++++------ src/openstudio_lib/LoadsView.hpp | 5 +- src/openstudio_lib/MaterialsView.cpp | 58 ++++++++++--------- src/openstudio_lib/MaterialsView.hpp | 5 +- .../ModelObjectTypeListView.cpp | 14 ++++- .../ModelObjectTypeListView.hpp | 9 ++- .../OSCollapsibleItemHeader.cpp | 17 +++++- .../OSCollapsibleItemHeader.hpp | 5 +- src/openstudio_lib/ScheduleOthersView.cpp | 16 +++-- src/openstudio_lib/ScheduleOthersView.hpp | 5 +- 12 files changed, 139 insertions(+), 76 deletions(-) diff --git a/src/openstudio_lib/ConstructionsView.cpp b/src/openstudio_lib/ConstructionsView.cpp index 950e4a9ef..6e374e43e 100644 --- a/src/openstudio_lib/ConstructionsView.cpp +++ b/src/openstudio_lib/ConstructionsView.cpp @@ -19,28 +19,33 @@ #include #include +#include +#include namespace openstudio { ConstructionsView::ConstructionsView(bool isIP, const openstudio::model::Model& model, QWidget* parent) - : ModelSubTabView(new ModelObjectTypeListView(ConstructionsView::modelObjectTypesAndNames(), model, true, OSItemType::ListItem, false, parent), - new ConstructionsInspectorView(isIP, model, parent), false, parent) { + : ModelSubTabView( + new ModelObjectTypeListView(ConstructionsView::modelObjectTypesNamesAndUrls(), model, true, OSItemType::ListItem, false, parent), + new ConstructionsInspectorView(isIP, model, parent), false, parent) { connect(this, &ConstructionsView::toggleUnitsClicked, modelObjectInspectorView(), &ModelObjectInspectorView::toggleUnitsClicked); } -std::vector> ConstructionsView::modelObjectTypesAndNames() { - std::vector> result; - result.push_back(std::make_pair(IddObjectType::OS_Construction, tr("Constructions"))); - result.push_back(std::make_pair(IddObjectType::OS_Construction_AirBoundary, tr("Air Boundary Constructions"))); - result.push_back(std::make_pair(IddObjectType::OS_Construction_InternalSource, tr("Internal Source Constructions"))); - result.push_back( - std::make_pair(IddObjectType::OS_Construction_CfactorUndergroundWall, tr("C-factor Underground Wall Constructions"))); - result.push_back( - std::make_pair(IddObjectType::OS_Construction_FfactorGroundFloor, tr("F-factor Ground Floor Constructions"))); - // Not currently supported - //result.push_back(std::make_pair(IddObjectType::OS_Construction_WindowDataFile, "Window Data File Constructions")); - - return result; +std::vector> ConstructionsView::modelObjectTypesNamesAndUrls() { + static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString sce = base + QStringLiteral("group-surface-construction-elements.html"); + + using T = std::tuple; + return { + T{IddObjectType::OS_Construction, tr("Constructions"), sce + "#construction-000"}, + T{IddObjectType::OS_Construction_AirBoundary, tr("Air Boundary Constructions"), sce + "#constructionairboundary"}, + T{IddObjectType::OS_Construction_InternalSource, tr("Internal Source Constructions"), sce + "#constructioninternalsource"}, + T{IddObjectType::OS_Construction_CfactorUndergroundWall, tr("C-factor Underground Wall Constructions"), + sce + "#constructioncfactorundergroundwall"}, + T{IddObjectType::OS_Construction_FfactorGroundFloor, tr("F-factor Ground Floor Constructions"), sce + "#constructionffactorgroundfloor"}, + // Not currently supported + // T{IddObjectType::OS_Construction_WindowDataFile, tr("Window Data File Constructions"), {}}, + }; } ConstructionsInspectorView::ConstructionsInspectorView(bool isIP, const model::Model& model, QWidget* parent) diff --git a/src/openstudio_lib/ConstructionsView.hpp b/src/openstudio_lib/ConstructionsView.hpp index 0867f73b4..ccc303d5f 100644 --- a/src/openstudio_lib/ConstructionsView.hpp +++ b/src/openstudio_lib/ConstructionsView.hpp @@ -11,6 +11,9 @@ #include +#include +#include + namespace openstudio { class ConstructionsView : public ModelSubTabView @@ -23,7 +26,7 @@ class ConstructionsView : public ModelSubTabView virtual ~ConstructionsView() {} private: - static std::vector> modelObjectTypesAndNames(); + static std::vector> modelObjectTypesNamesAndUrls(); }; class ConstructionsInspectorView : public ModelObjectInspectorView diff --git a/src/openstudio_lib/LoadsView.cpp b/src/openstudio_lib/LoadsView.cpp index 5c1d1c363..5be536145 100644 --- a/src/openstudio_lib/LoadsView.cpp +++ b/src/openstudio_lib/LoadsView.cpp @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -28,32 +29,38 @@ #include #include #include +#include #include namespace openstudio { LoadsView::LoadsView(bool isIP, const openstudio::model::Model& model, QWidget* parent) - : ModelSubTabView(new ModelObjectTypeListView(LoadsView::modelObjectTypesAndNames(), model, true, OSItemType::CollapsibleListHeader, false, parent), - new LoadsInspectorView(isIP, model, parent), false, parent) { + : ModelSubTabView( + new ModelObjectTypeListView(LoadsView::modelObjectTypesNamesAndUrls(), model, true, OSItemType::CollapsibleListHeader, false, parent), + new LoadsInspectorView(isIP, model, parent), false, parent) { connect(this, &LoadsView::toggleUnitsClicked, modelObjectInspectorView(), &ModelObjectInspectorView::toggleUnitsClicked); } -std::vector> LoadsView::modelObjectTypesAndNames() { - std::vector> result; - - result.push_back(std::make_pair(IddObjectType::OS_People_Definition, tr("People Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_Lights_Definition, tr("Lights Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_Luminaire_Definition, tr("Luminaire Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_ElectricEquipment_Definition, tr("Electric Equipment Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_GasEquipment_Definition, tr("Gas Equipment Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_SteamEquipment_Definition, tr("Steam Equipment Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_OtherEquipment_Definition, tr("Other Equipment Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_InternalMass_Definition, tr("Internal Mass Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_WaterUse_Equipment_Definition, tr("Water Use Equipment Definitions"))); - result.push_back(std::make_pair(IddObjectType::OS_HotWaterEquipment_Definition, tr("Hot Water Equipment Definitions"))); - - return result; +std::vector> LoadsView::modelObjectTypesNamesAndUrls() { + static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString iag = base + QStringLiteral("group-internal-gains-people-lights-other.html"); + static const QString tzg = base + QStringLiteral("group-thermal-zone-description-geometry.html"); + static const QString wsg = base + QStringLiteral("group-water-systems.html"); + + using T = std::tuple; + return { + T{IddObjectType::OS_People_Definition, tr("People Definitions"), iag + "#people"}, + T{IddObjectType::OS_Lights_Definition, tr("Lights Definitions"), iag + "#lights-000"}, + T{IddObjectType::OS_Luminaire_Definition, tr("Luminaire Definitions"), {}}, + T{IddObjectType::OS_ElectricEquipment_Definition, tr("Electric Equipment Definitions"), iag + "#electricequipment"}, + T{IddObjectType::OS_GasEquipment_Definition, tr("Gas Equipment Definitions"), iag + "#gasequipment"}, + T{IddObjectType::OS_SteamEquipment_Definition, tr("Steam Equipment Definitions"), iag + "#steamequipment"}, + T{IddObjectType::OS_OtherEquipment_Definition, tr("Other Equipment Definitions"), iag + "#otherequipment"}, + T{IddObjectType::OS_InternalMass_Definition, tr("Internal Mass Definitions"), tzg + "#internalmass"}, + T{IddObjectType::OS_WaterUse_Equipment_Definition, tr("Water Use Equipment Definitions"), wsg + "#wateruseequipment"}, + T{IddObjectType::OS_HotWaterEquipment_Definition, tr("Hot Water Equipment Definitions"), iag + "#hotwaterequipment"}, + }; } void LoadsView::toggleUnits(bool displayIP) {} diff --git a/src/openstudio_lib/LoadsView.hpp b/src/openstudio_lib/LoadsView.hpp index ff8ef736d..9b379a122 100644 --- a/src/openstudio_lib/LoadsView.hpp +++ b/src/openstudio_lib/LoadsView.hpp @@ -13,6 +13,9 @@ #include +#include +#include + class QStackedWidget; namespace openstudio { @@ -27,7 +30,7 @@ class LoadsView : public ModelSubTabView virtual ~LoadsView() {} private: - static std::vector> modelObjectTypesAndNames(); + static std::vector> modelObjectTypesNamesAndUrls(); public slots: diff --git a/src/openstudio_lib/MaterialsView.cpp b/src/openstudio_lib/MaterialsView.cpp index 214bc9d61..936ccca01 100644 --- a/src/openstudio_lib/MaterialsView.cpp +++ b/src/openstudio_lib/MaterialsView.cpp @@ -29,44 +29,46 @@ #include #include +#include +#include namespace openstudio { MaterialsView::MaterialsView(bool isIP, const openstudio::model::Model& model, const QString& tabLabel, bool hasSubTabs, QWidget* parent) : ModelSubTabView( - new ModelObjectTypeListView(MaterialsView::modelObjectTypesAndNames(), model, true, OSItemType::CollapsibleListHeader, false, parent), + new ModelObjectTypeListView(MaterialsView::modelObjectTypesNamesAndUrls(), model, true, OSItemType::CollapsibleListHeader, false, parent), new MaterialsInspectorView(isIP, model, parent), false, parent) { // ModelObjectTypeListView will call reportItems for each IddObjectType, this results in inspector being build for each IddObjecType then thrown away connect(this, &MaterialsView::toggleUnitsClicked, modelObjectInspectorView(), &ModelObjectInspectorView::toggleUnitsClicked); } -std::vector> MaterialsView::modelObjectTypesAndNames() { - std::vector> result; - result.push_back(std::make_pair(IddObjectType::OS_Material, tr("Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_Material_NoMass, tr("No Mass Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_Material_AirGap, tr("Air Gap Materials"))); - - result.push_back( - std::make_pair(IddObjectType::OS_WindowMaterial_SimpleGlazingSystem, tr("Simple Glazing System Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_Glazing, tr("Glazing Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_Gas, tr("Gas Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_GasMixture, tr("Gas Mixture Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_Blind, tr("Blind Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_DaylightRedirectionDevice, - tr("Daylight Redirection Device Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_Screen, tr("Screen Window Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_Shade, tr("Shade Window Materials"))); - - // Oddballs to be listed at the bottom of the list - result.push_back(std::make_pair(IddObjectType::OS_Material_InfraredTransparent, tr("Infrared Transparent Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_Material_RoofVegetation, tr("Roof Vegetation Materials"))); - result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_Glazing_RefractionExtinctionMethod, - tr("Refraction Extinction Method Glazing Window Materials"))); - - // TODO: commented out until ThermochromicGlazing is properly wrapped - // result.push_back(std::make_pair(IddObjectType::OS_WindowMaterial_GlazingGroup_Thermochromic, "Glazing Group Thermochromic Window Materials")); - - return result; +std::vector> MaterialsView::modelObjectTypesNamesAndUrls() { + static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString sce = base + QStringLiteral("group-surface-construction-elements.html"); + + using T = std::tuple; + return { + T{IddObjectType::OS_Material, tr("Materials"), sce + "#material"}, + T{IddObjectType::OS_Material_NoMass, tr("No Mass Materials"), sce + "#materialnomass"}, + T{IddObjectType::OS_Material_AirGap, tr("Air Gap Materials"), sce + "#materialairgap"}, + T{IddObjectType::OS_WindowMaterial_SimpleGlazingSystem, tr("Simple Glazing System Window Materials"), + sce + "#windowmaterialsimpleglazingsystem"}, + T{IddObjectType::OS_WindowMaterial_Glazing, tr("Glazing Window Materials"), sce + "#windowmaterialglazing"}, + T{IddObjectType::OS_WindowMaterial_Gas, tr("Gas Window Materials"), sce + "#windowmaterialgas"}, + T{IddObjectType::OS_WindowMaterial_GasMixture, tr("Gas Mixture Window Materials"), sce + "#windowmaterialgasmixture"}, + T{IddObjectType::OS_WindowMaterial_Blind, tr("Blind Window Materials"), sce + "#windowmaterialblind"}, + T{IddObjectType::OS_WindowMaterial_DaylightRedirectionDevice, tr("Daylight Redirection Device Window Materials"), + sce + "#windowmaterialblind"}, + T{IddObjectType::OS_WindowMaterial_Screen, tr("Screen Window Materials"), sce + "#windowmaterialscreen"}, + T{IddObjectType::OS_WindowMaterial_Shade, tr("Shade Window Materials"), sce + "#windowmaterialshade"}, + // Oddballs at the bottom + T{IddObjectType::OS_Material_InfraredTransparent, tr("Infrared Transparent Materials"), sce + "#materialinfraredtransparent"}, + T{IddObjectType::OS_Material_RoofVegetation, tr("Roof Vegetation Materials"), sce + "#materialroofvegetation"}, + T{IddObjectType::OS_WindowMaterial_Glazing_RefractionExtinctionMethod, tr("Refraction Extinction Method Glazing Window Materials"), + sce + "#windowmaterialglazingrefractionextinctionmethod"}, + // TODO: commented out until ThermochromicGlazing is properly wrapped + // T{IddObjectType::OS_WindowMaterial_GlazingGroup_Thermochromic, tr("Glazing Group Thermochromic Window Materials"), sce + "#windowmaterialglazinggroupthermochromic"}, + }; } MaterialsInspectorView::MaterialsInspectorView(bool isIP, const model::Model& model, QWidget* parent) diff --git a/src/openstudio_lib/MaterialsView.hpp b/src/openstudio_lib/MaterialsView.hpp index be04cfd70..87e8b7cce 100644 --- a/src/openstudio_lib/MaterialsView.hpp +++ b/src/openstudio_lib/MaterialsView.hpp @@ -11,6 +11,9 @@ #include +#include +#include + class QStackedWidget; namespace openstudio { @@ -25,7 +28,7 @@ class MaterialsView : public ModelSubTabView virtual ~MaterialsView() {} private: - static std::vector> modelObjectTypesAndNames(); + static std::vector> modelObjectTypesNamesAndUrls(); }; class MaterialsInspectorView : public ModelObjectInspectorView diff --git a/src/openstudio_lib/ModelObjectTypeListView.cpp b/src/openstudio_lib/ModelObjectTypeListView.cpp index 982a4b2a7..75fd8d811 100644 --- a/src/openstudio_lib/ModelObjectTypeListView.cpp +++ b/src/openstudio_lib/ModelObjectTypeListView.cpp @@ -38,8 +38,18 @@ ModelObjectTypeListView::ModelObjectTypeListView(const std::vector>& modelObjectTypesNamesAndUrls, + const model::Model& model, bool addScrollArea, OSItemType headerType, bool isLibrary, + QWidget* parent) + : OSCollapsibleItemList(addScrollArea, parent), m_model(model), m_headerType(headerType), m_isLibrary(isLibrary) { + for (auto it = modelObjectTypesNamesAndUrls.rbegin(); it != modelObjectTypesNamesAndUrls.rend(); ++it) { + addModelObjectType(std::get<0>(*it), std::get<1>(*it), std::get<2>(*it)); + } + selectFirstCollapsibleItem(); +} + +void ModelObjectTypeListView::addModelObjectType(const IddObjectType& iddObjectType, const QString& name, const QString& url) { + auto* collapsibleItemHeader = new OSCollapsibleItemHeader(name, OSItemId("", "", false), m_headerType, url); auto* modelObjectListView = new ModelObjectListView(iddObjectType, m_model, false, m_isLibrary); auto* modelObjectTypeItem = new ModelObjectTypeItem(collapsibleItemHeader, modelObjectListView); diff --git a/src/openstudio_lib/ModelObjectTypeListView.hpp b/src/openstudio_lib/ModelObjectTypeListView.hpp index 89caa50dd..43137eac1 100644 --- a/src/openstudio_lib/ModelObjectTypeListView.hpp +++ b/src/openstudio_lib/ModelObjectTypeListView.hpp @@ -14,6 +14,10 @@ #include +#include + +#include + class QVBoxLayout; class QHBoxLayout; @@ -30,9 +34,12 @@ class ModelObjectTypeListView : public OSCollapsibleItemList ModelObjectTypeListView(const std::vector>& modelObjectTypesAndNames, const model::Model& model, bool addScrollArea, OSItemType headerType, bool isLibrary, QWidget* parent = nullptr); + ModelObjectTypeListView(const std::vector>& modelObjectTypesNamesAndUrls, + const model::Model& model, bool addScrollArea, OSItemType headerType, bool isLibrary, QWidget* parent = nullptr); + virtual ~ModelObjectTypeListView() {} - void addModelObjectType(const IddObjectType& iddObjectType, const QString& name); + void addModelObjectType(const IddObjectType& iddObjectType, const QString& name, const QString& url = {}); void addModelObjectCategoryPlaceholder(const QString& name); diff --git a/src/openstudio_lib/OSCollapsibleItemHeader.cpp b/src/openstudio_lib/OSCollapsibleItemHeader.cpp index 26d336e28..68f876135 100644 --- a/src/openstudio_lib/OSCollapsibleItemHeader.cpp +++ b/src/openstudio_lib/OSCollapsibleItemHeader.cpp @@ -18,7 +18,8 @@ namespace openstudio { -OSCollapsibleItemHeader::OSCollapsibleItemHeader(const QString& text, const OSItemId& itemId, OSItemType type, QWidget* parent) +OSCollapsibleItemHeader::OSCollapsibleItemHeader(const QString& text, const OSItemId& itemId, OSItemType type, const QString& url, + QWidget* parent) : QWidget(parent), m_mouseDown(false) { setFixedHeight(50); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); @@ -35,9 +36,19 @@ OSCollapsibleItemHeader::OSCollapsibleItemHeader(const QString& text, const OSIt // Label - m_textLabel = new QLabel(text); + m_plainText = text; + m_textLabel = new QLabel(); m_textLabel->setWordWrap(true); m_textLabel->setObjectName("H2"); + if (!url.isEmpty()) { + m_textLabel->setTextFormat(Qt::RichText); + m_textLabel->setOpenExternalLinks(true); + m_textLabel->setToolTip(url); + m_textLabel->setText( + QStringLiteral(R"(%2)").arg(url, m_plainText.toHtmlEscaped())); + } else { + m_textLabel->setText(m_plainText); + } mainHLayout->addWidget(m_textLabel, 10); mainHLayout->addStretch(); @@ -57,7 +68,7 @@ QSize OSCollapsibleItemHeader::sizeHint() const { } QString OSCollapsibleItemHeader::text() const { - return m_textLabel->text(); + return m_plainText; } bool OSCollapsibleItemHeader::expanded() const { diff --git a/src/openstudio_lib/OSCollapsibleItemHeader.hpp b/src/openstudio_lib/OSCollapsibleItemHeader.hpp index e97499ac8..69cee217a 100644 --- a/src/openstudio_lib/OSCollapsibleItemHeader.hpp +++ b/src/openstudio_lib/OSCollapsibleItemHeader.hpp @@ -8,6 +8,8 @@ #include "OSItem.hpp" +#include + class QLabel; class QVBoxLayout; class QPaintEvent; @@ -21,7 +23,7 @@ class OSCollapsibleItemHeader : public QWidget public: OSCollapsibleItemHeader(const QString& text, const OSItemId& itemId, OSItemType type = OSItemType::CollapsibleListHeader, - QWidget* parent = nullptr); + const QString& url = {}, QWidget* parent = nullptr); virtual ~OSCollapsibleItemHeader() = default; @@ -49,6 +51,7 @@ class OSCollapsibleItemHeader : public QWidget QLabel* m_arrowLabel; QLabel* m_textLabel; + QString m_plainText; bool m_expanded; bool m_selected; diff --git a/src/openstudio_lib/ScheduleOthersView.cpp b/src/openstudio_lib/ScheduleOthersView.cpp index b2264172f..8a7aa06b6 100644 --- a/src/openstudio_lib/ScheduleOthersView.cpp +++ b/src/openstudio_lib/ScheduleOthersView.cpp @@ -16,19 +16,25 @@ #include #include +#include +#include namespace openstudio { ScheduleOthersView::ScheduleOthersView(const openstudio::model::Model& model, QWidget* parent) : ModelSubTabView( - new ModelObjectTypeListView(ScheduleOthersView::modelObjectTypesAndNames(), model, true, OSItemType::CollapsibleListHeader, false, parent), + new ModelObjectTypeListView(ScheduleOthersView::modelObjectTypesNamesAndUrls(), model, true, OSItemType::CollapsibleListHeader, false, parent), new ScheduleOthersInspectorView(model, parent), false, parent) {} -std::vector> ScheduleOthersView::modelObjectTypesAndNames() { +std::vector> ScheduleOthersView::modelObjectTypesNamesAndUrls() { + static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString sch = base + QStringLiteral("group-schedules.html"); + + using T = std::tuple; return { - {IddObjectType::OS_Schedule_Constant, tr("Schedule Constant")}, - {IddObjectType::OS_Schedule_Compact, tr("Schedule Compact")}, - {IddObjectType::OS_Schedule_File, tr("Schedule File")}, + T{IddObjectType::OS_Schedule_Constant, tr("Schedule Constant"), sch + "#scheduleconstant"}, + T{IddObjectType::OS_Schedule_Compact, tr("Schedule Compact"), sch + "#schedulecompact"}, + T{IddObjectType::OS_Schedule_File, tr("Schedule File"), sch + "#schedulefile"}, }; } diff --git a/src/openstudio_lib/ScheduleOthersView.hpp b/src/openstudio_lib/ScheduleOthersView.hpp index 7a6c95b72..b8712e031 100644 --- a/src/openstudio_lib/ScheduleOthersView.hpp +++ b/src/openstudio_lib/ScheduleOthersView.hpp @@ -11,6 +11,9 @@ #include +#include +#include + class QStackedWidget; namespace openstudio { @@ -25,7 +28,7 @@ class ScheduleOthersView : public ModelSubTabView virtual ~ScheduleOthersView() = default; private: - static std::vector> modelObjectTypesAndNames(); + static std::vector> modelObjectTypesNamesAndUrls(); }; class ScheduleOthersInspectorView : public ModelObjectInspectorView From 869fc127b4bfb7076c06da74f0a8719e56e274e9 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 21:45:18 +0200 Subject: [PATCH 06/18] feat: add doc links to Site, Facility, and Life Cycle Costs tabs - Site / Weather File & Design Days: Weather File, Design Days, and Daylight Savings Time headers link to BigLadder I/O Reference - Site / Ground Temperatures: all five sidebar entries link to their respective Site:GroundTemperature:* and Site:WaterMainsTemperature docs - Site / Life Cycle Cost: Life Cycle Cost Parameters and NIST Fuel Escalation Rates headers link to LifeCycleCost docs - Facility tab: North Axis label links to Building object docs Co-Authored-By: Claude Sonnet 4.6 --- src/openstudio_lib/BuildingInspectorView.cpp | 10 ++++++- src/openstudio_lib/GroundTemperatureView.cpp | 31 +++++++++++++++----- src/openstudio_lib/GroundTemperatureView.hpp | 3 +- src/openstudio_lib/LifeCycleCostsTabView.cpp | 21 +++++++++++-- src/openstudio_lib/LocationTabView.cpp | 21 +++++++++++-- src/openstudio_lib/YearSettingsWidget.cpp | 11 ++++++- 6 files changed, 83 insertions(+), 14 deletions(-) diff --git a/src/openstudio_lib/BuildingInspectorView.cpp b/src/openstudio_lib/BuildingInspectorView.cpp index 797d8d6b9..ed31995c5 100644 --- a/src/openstudio_lib/BuildingInspectorView.cpp +++ b/src/openstudio_lib/BuildingInspectorView.cpp @@ -41,6 +41,7 @@ #include #include #include +#include namespace openstudio { @@ -437,8 +438,15 @@ BuildingInspectorView::BuildingInspectorView(bool isIP, bool displayAdditionalPr vLayout = new QVBoxLayout(); label = new QLabel(); - label->setText(tr("North Axis: ")); label->setStyleSheet("QLabel { font: bold; }"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + { + static const QString url = + QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-simulation-parameters.html#building"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)").arg(url, tr("North Axis: "))); + } vLayout->addWidget(label); m_northAxisEdit = new OSQuantityEdit2("deg", "deg", "deg", m_isIP); diff --git a/src/openstudio_lib/GroundTemperatureView.cpp b/src/openstudio_lib/GroundTemperatureView.cpp index 4ce5d28ba..f1e42dfe0 100644 --- a/src/openstudio_lib/GroundTemperatureView.cpp +++ b/src/openstudio_lib/GroundTemperatureView.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,7 @@ namespace openstudio { // GroundTemperatureEntry // ───────────────────────────────────────────────────────── -GroundTemperatureEntry::GroundTemperatureEntry(const QString& label, QWidget* parent) : QWidget(parent) { +GroundTemperatureEntry::GroundTemperatureEntry(const QString& label, const QString& url, QWidget* parent) : QWidget(parent) { setFixedHeight(50); setObjectName("GroundTemperatureEntry"); setProperty("style", "0"); @@ -48,9 +49,18 @@ GroundTemperatureEntry::GroundTemperatureEntry(const QString& label, QWidget* pa layout->setContentsMargins(9, 0, 9, 0); setLayout(layout); - m_label = new QLabel(label); + m_label = new QLabel(); m_label->setObjectName("H2"); m_label->setWordWrap(true); + if (!url.isEmpty()) { + m_label->setTextFormat(Qt::RichText); + m_label->setOpenExternalLinks(true); + m_label->setToolTip(url); + m_label->setText( + QStringLiteral(R"(%2)").arg(url, label.toHtmlEscaped())); + } else { + m_label->setText(label); + } layout->addWidget(m_label); } @@ -90,11 +100,18 @@ GroundTemperatureListView::GroundTemperatureListView(QWidget* parent) : QWidget( layout->setSpacing(0); setLayout(layout); - m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), this); - m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), this); - m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), this); - m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), this); - m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), this); + static const QString lcwBase = + QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-location-climate-weather-file-access.html"); + m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), + lcwBase + "#sitegroundtemperaturebuildingsurface", this); + m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), + lcwBase + "#sitegroundtemperatureshallow", this); + m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), + lcwBase + "#sitegroundtemperaturedeep", this); + m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), + lcwBase + "#sitegroundtemperaturefcfactormethod", this); + m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), + lcwBase + "#sitewatermainstemperature", this); connect(m_bsEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onBuildingSurfaceClicked); connect(m_shEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onShallowClicked); diff --git a/src/openstudio_lib/GroundTemperatureView.hpp b/src/openstudio_lib/GroundTemperatureView.hpp index 94c30fa25..a8e426d24 100644 --- a/src/openstudio_lib/GroundTemperatureView.hpp +++ b/src/openstudio_lib/GroundTemperatureView.hpp @@ -12,6 +12,7 @@ #include #include +#include class QLabel; class QPushButton; @@ -36,7 +37,7 @@ class GroundTemperatureEntry : public QWidget Q_OBJECT public: - explicit GroundTemperatureEntry(const QString& label, QWidget* parent = nullptr); + explicit GroundTemperatureEntry(const QString& label, const QString& url = {}, QWidget* parent = nullptr); void setSelected(bool selected); diff --git a/src/openstudio_lib/LifeCycleCostsTabView.cpp b/src/openstudio_lib/LifeCycleCostsTabView.cpp index 4583f2118..5bd3341a0 100644 --- a/src/openstudio_lib/LifeCycleCostsTabView.cpp +++ b/src/openstudio_lib/LifeCycleCostsTabView.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #define OS_EDIT_WIDTH 150 @@ -58,8 +59,16 @@ void LifeCycleCostsView::createWidgets() { vLayout->setSpacing(10); label = new QLabel(); - label->setText(tr("Life Cycle Cost Parameters")); label->setObjectName("H2"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + { + static const QString url = + QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "lifecyclecost-parameters.html#lifecyclecostparameters"); + label->setToolTip(url); + label->setText( + QStringLiteral(R"(%2)").arg(url, tr("Life Cycle Cost Parameters"))); + } vLayout->addWidget(label); label = new QLabel(); @@ -142,8 +151,16 @@ void LifeCycleCostsView::createWidgets() { vLayout->setSpacing(5); label = new QLabel(); - label->setText(tr("Use National Institute of Standards and Technology (NIST) Fuel Escalation Rates")); label->setObjectName("H2"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + { + static const QString url = + QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "lifecyclecost-usepriceescalation.html#lifecyclecostusepriceescalation"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)") + .arg(url, tr("Use National Institute of Standards and Technology (NIST) Fuel Escalation Rates"))); + } vLayout->addWidget(label); m_nistGroup = new QButtonGroup(this); diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index ce6cdb460..79402d0c8 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -209,8 +209,17 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& mainHLine->setFrameShadow(QFrame::Sunken); // ***** Weather File ***** - auto* label = new QLabel(tr("Weather File")); + auto* label = new QLabel(); label->setObjectName("H2"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + { + static const QString url = QStringLiteral( + BIGLADDERSOFTWARE_DOC_BASE_URL + "group-location-climate-weather-file-access.html#group----location----climate----weather-file-access"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)").arg(url, tr("Weather File"))); + } m_weatherFileBtn = new QPushButton(this); m_weatherFileBtn->setFlat(true); @@ -456,8 +465,16 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& scrollLayout->addWidget(mainHLine); // ***** Design Days ***** - label = new QLabel(tr("Design Days")); + label = new QLabel(); label->setObjectName("H2"); + label->setTextFormat(Qt::RichText); + label->setOpenExternalLinks(true); + { + static const QString url = + QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-location-climate-weather-file-access.html#sizingperioddesignday"); + label->setToolTip(url); + label->setText(QStringLiteral(R"(%2)").arg(url, tr("Design Days"))); + } auto* btn = new QPushButton(tr("Import From DDY"), this); btn->setFlat(true); diff --git a/src/openstudio_lib/YearSettingsWidget.cpp b/src/openstudio_lib/YearSettingsWidget.cpp index fe838aa47..a2d761e69 100644 --- a/src/openstudio_lib/YearSettingsWidget.cpp +++ b/src/openstudio_lib/YearSettingsWidget.cpp @@ -102,8 +102,17 @@ YearSettingsWidget::YearSettingsWidget(const model::Model& model, QWidget* paren dstHLayout1->setContentsMargins(0, 0, 0, 0); dstHLayout1->setSpacing(10); - auto* dstLabel = new QLabel(tr("Daylight Savings Time:")); + auto* dstLabel = new QLabel(); dstLabel->setObjectName("H2"); + dstLabel->setTextFormat(Qt::RichText); + dstLabel->setOpenExternalLinks(true); + { + static const QString url = QStringLiteral( + BIGLADDERSOFTWARE_DOC_BASE_URL + "group-location-climate-weather-file-access.html#field-daylight-saving-time-indicator"); + dstLabel->setToolTip(url); + dstLabel->setText(QStringLiteral(R"(%2)").arg(url, tr("Daylight Savings Time:"))); + } dstHLayout1->addWidget(dstLabel); m_dstOnOffButton = new OSSwitch2(); From 241fe39f3a8b556b5b062d38a453bfb454ffa0a2 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 22:01:07 +0200 Subject: [PATCH 07/18] refactor: replace BIGLADDERSOFTWARE_DOC_BASE_URL macro with accessor function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per PR review feedback: instead of passing the URL via target_compile_definitions, add bigladdersoftwareDocBaseUrl() to OpenStudioApplicationPathHelpers following the existing .cxx.in pattern. The URL is configured from BIGLADDERSOFTWARE_DOC_BASE_URL in FindOpenStudioSDK.cmake — visible alongside EnergyPlus version bumps each release. All call sites updated to use QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()). Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/CMakeLists.txt | 3 --- src/model_editor/IddObjectDocUrl.hpp | 4 +++- src/openstudio_lib/BuildingInspectorView.cpp | 3 ++- src/openstudio_lib/CMakeLists.txt | 3 --- src/openstudio_lib/ConstructionsView.cpp | 3 ++- src/openstudio_lib/GroundTemperatureView.cpp | 3 ++- src/openstudio_lib/LifeCycleCostsTabView.cpp | 5 +++-- src/openstudio_lib/LoadsView.cpp | 3 ++- src/openstudio_lib/LocationTabView.cpp | 8 ++++---- src/openstudio_lib/MaterialsView.cpp | 3 ++- src/openstudio_lib/ScheduleOthersView.cpp | 3 ++- src/openstudio_lib/SimSettingsView.cpp | 9 +++++---- src/openstudio_lib/YearSettingsWidget.cpp | 6 +++--- src/utilities/OpenStudioApplicationPathHelpers.cxx.in | 4 ++++ src/utilities/OpenStudioApplicationPathHelpers.hpp | 3 +++ 15 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/model_editor/CMakeLists.txt b/src/model_editor/CMakeLists.txt index c8ee35816..63aca23c1 100644 --- a/src/model_editor/CMakeLists.txt +++ b/src/model_editor/CMakeLists.txt @@ -103,9 +103,6 @@ else() target_compile_definitions(${target_name} PUBLIC model_editor_EXPORTS) endif() -target_compile_definitions(${target_name} PRIVATE - "BIGLADDERSOFTWARE_DOC_BASE_URL=\"${BIGLADDERSOFTWARE_DOC_BASE_URL}\"") - set(${target_name}_test_src test/ModelEditorFixture.hpp test/ModelEditorFixture.cpp diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 3d202a2fa..8189c4804 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -9,11 +9,13 @@ #include #include +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" + // Returns the BigLadder EnergyPlus I/O Reference URL for the given OS IDD type name // (e.g. "OS:ThermalZone"), or an empty string if none is known. // Base URL version is controlled by ENERGYPLUS_VERSION_MAJOR/MINOR in FindOpenStudioSDK.cmake. inline QString iddObjectDocUrl(const QString& iddTypeName) { - static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); // clang-format off static const QHash urlMap{ diff --git a/src/openstudio_lib/BuildingInspectorView.cpp b/src/openstudio_lib/BuildingInspectorView.cpp index ed31995c5..101da0233 100644 --- a/src/openstudio_lib/BuildingInspectorView.cpp +++ b/src/openstudio_lib/BuildingInspectorView.cpp @@ -4,6 +4,7 @@ ***********************************************************************************************************************/ #include "BuildingInspectorView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSIntegerEdit.hpp" @@ -443,7 +444,7 @@ BuildingInspectorView::BuildingInspectorView(bool isIP, bool displayAdditionalPr label->setOpenExternalLinks(true); { static const QString url = - QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-simulation-parameters.html#building"); + QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-simulation-parameters.html#building"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("North Axis: "))); } diff --git a/src/openstudio_lib/CMakeLists.txt b/src/openstudio_lib/CMakeLists.txt index 143c5bbb4..28977df89 100644 --- a/src/openstudio_lib/CMakeLists.txt +++ b/src/openstudio_lib/CMakeLists.txt @@ -778,9 +778,6 @@ if (NINJA) target_compile_definitions(${target_name} PRIVATE NINJA=1) endif() -target_compile_definitions(${target_name} PRIVATE - "BIGLADDERSOFTWARE_DOC_BASE_URL=\"${BIGLADDERSOFTWARE_DOC_BASE_URL}\"") - set(${target_name}_depends openstudio_modeleditor openstudio::openstudiolib diff --git a/src/openstudio_lib/ConstructionsView.cpp b/src/openstudio_lib/ConstructionsView.cpp index 6e374e43e..d28cc3143 100644 --- a/src/openstudio_lib/ConstructionsView.cpp +++ b/src/openstudio_lib/ConstructionsView.cpp @@ -12,6 +12,7 @@ #include "ConstructionInternalSourceInspectorView.hpp" #include "ConstructionWindowDataFileInspectorView.hpp" #include "ModelObjectTypeListView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include @@ -32,7 +33,7 @@ ConstructionsView::ConstructionsView(bool isIP, const openstudio::model::Model& } std::vector> ConstructionsView::modelObjectTypesNamesAndUrls() { - static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); static const QString sce = base + QStringLiteral("group-surface-construction-elements.html"); using T = std::tuple; diff --git a/src/openstudio_lib/GroundTemperatureView.cpp b/src/openstudio_lib/GroundTemperatureView.cpp index f1e42dfe0..82b3b7540 100644 --- a/src/openstudio_lib/GroundTemperatureView.cpp +++ b/src/openstudio_lib/GroundTemperatureView.cpp @@ -4,6 +4,7 @@ ***********************************************************************************************************************/ #include "GroundTemperatureView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" @@ -101,7 +102,7 @@ GroundTemperatureListView::GroundTemperatureListView(QWidget* parent) : QWidget( setLayout(layout); static const QString lcwBase = - QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-location-climate-weather-file-access.html"); + QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html"; m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), lcwBase + "#sitegroundtemperaturebuildingsurface", this); m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), diff --git a/src/openstudio_lib/LifeCycleCostsTabView.cpp b/src/openstudio_lib/LifeCycleCostsTabView.cpp index 5bd3341a0..54f96cb36 100644 --- a/src/openstudio_lib/LifeCycleCostsTabView.cpp +++ b/src/openstudio_lib/LifeCycleCostsTabView.cpp @@ -4,6 +4,7 @@ ***********************************************************************************************************************/ #include "LifeCycleCostsTabView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" @@ -64,7 +65,7 @@ void LifeCycleCostsView::createWidgets() { label->setOpenExternalLinks(true); { static const QString url = - QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "lifecyclecost-parameters.html#lifecyclecostparameters"); + QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "lifecyclecost-parameters.html#lifecyclecostparameters"; label->setToolTip(url); label->setText( QStringLiteral(R"(%2)").arg(url, tr("Life Cycle Cost Parameters"))); @@ -156,7 +157,7 @@ void LifeCycleCostsView::createWidgets() { label->setOpenExternalLinks(true); { static const QString url = - QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "lifecyclecost-usepriceescalation.html#lifecyclecostusepriceescalation"); + QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "lifecyclecost-usepriceescalation.html#lifecyclecostusepriceescalation"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)") .arg(url, tr("Use National Institute of Standards and Technology (NIST) Fuel Escalation Rates"))); diff --git a/src/openstudio_lib/LoadsView.cpp b/src/openstudio_lib/LoadsView.cpp index 5be536145..2f43b7cfa 100644 --- a/src/openstudio_lib/LoadsView.cpp +++ b/src/openstudio_lib/LoadsView.cpp @@ -5,6 +5,7 @@ #include "LoadsView.hpp" #include "ModelObjectTypeListView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "PeopleInspectorView.hpp" #include "InternalMassInspectorView.hpp" #include "LightsInspectorView.hpp" @@ -43,7 +44,7 @@ LoadsView::LoadsView(bool isIP, const openstudio::model::Model& model, QWidget* } std::vector> LoadsView::modelObjectTypesNamesAndUrls() { - static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); static const QString iag = base + QStringLiteral("group-internal-gains-people-lights-other.html"); static const QString tzg = base + QStringLiteral("group-thermal-zone-description-geometry.html"); static const QString wsg = base + QStringLiteral("group-water-systems.html"); diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index 79402d0c8..23e0070d5 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -4,6 +4,7 @@ ***********************************************************************************************************************/ #include "LocationTabView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "DesignDayGridView.hpp" #include "ModelObjectListView.hpp" @@ -214,9 +215,8 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QStringLiteral( - BIGLADDERSOFTWARE_DOC_BASE_URL - "group-location-climate-weather-file-access.html#group----location----climate----weather-file-access"); + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + + "group-location-climate-weather-file-access.html#group----location----climate----weather-file-access"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Weather File"))); } @@ -471,7 +471,7 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& label->setOpenExternalLinks(true); { static const QString url = - QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-location-climate-weather-file-access.html#sizingperioddesignday"); + QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html#sizingperioddesignday"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Design Days"))); } diff --git a/src/openstudio_lib/MaterialsView.cpp b/src/openstudio_lib/MaterialsView.cpp index 936ccca01..d69f41f6e 100644 --- a/src/openstudio_lib/MaterialsView.cpp +++ b/src/openstudio_lib/MaterialsView.cpp @@ -11,6 +11,7 @@ #include "MaterialNoMassInspectorView.hpp" #include "MaterialRoofVegetationInspectorView.hpp" #include "ModelObjectTypeListView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "WindowMaterialBlindInspectorView.hpp" #include "WindowMaterialDaylightRedirectionDeviceInspectorView.hpp" #include "WindowMaterialGasInspectorView.hpp" @@ -43,7 +44,7 @@ MaterialsView::MaterialsView(bool isIP, const openstudio::model::Model& model, c } std::vector> MaterialsView::modelObjectTypesNamesAndUrls() { - static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); static const QString sce = base + QStringLiteral("group-surface-construction-elements.html"); using T = std::tuple; diff --git a/src/openstudio_lib/ScheduleOthersView.cpp b/src/openstudio_lib/ScheduleOthersView.cpp index 8a7aa06b6..1038e4c85 100644 --- a/src/openstudio_lib/ScheduleOthersView.cpp +++ b/src/openstudio_lib/ScheduleOthersView.cpp @@ -5,6 +5,7 @@ #include "ScheduleOthersView.hpp" #include "ModelObjectTypeListView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "ScheduleConstantInspectorView.hpp" #include "ScheduleCompactInspectorView.hpp" @@ -27,7 +28,7 @@ ScheduleOthersView::ScheduleOthersView(const openstudio::model::Model& model, QW new ScheduleOthersInspectorView(model, parent), false, parent) {} std::vector> ScheduleOthersView::modelObjectTypesNamesAndUrls() { - static const QString base = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); static const QString sch = base + QStringLiteral("group-schedules.html"); using T = std::tuple; diff --git a/src/openstudio_lib/SimSettingsView.cpp b/src/openstudio_lib/SimSettingsView.cpp index 9c5fcbc40..03e4984e3 100644 --- a/src/openstudio_lib/SimSettingsView.cpp +++ b/src/openstudio_lib/SimSettingsView.cpp @@ -7,6 +7,7 @@ #include "CollapsibleInspector.hpp" #include "ModelObjectTypeListView.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "OSAppBase.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "OSDocument.hpp" @@ -239,7 +240,7 @@ void SimSettingsView::createWidgets() { //******************* OS:Timestep ******************* mainLayout->addWidget(createTimestepWidget()); - static const QString iorf = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL); + static const QString iorf = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); collapsibleInspector = new CollapsibleInspector(tr("Advanced RunPeriod Parameters"), iorf + "group-location-climate-weather-file-access.html#runperiod", createRunPeriodAdvancedWidget()); mainLayout->addWidget(collapsibleInspector); @@ -331,7 +332,7 @@ QWidget* SimSettingsView::createRunPeriodWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-location-climate-weather-file-access.html#runperiod"); + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html#runperiod"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Run Period"))); } @@ -615,7 +616,7 @@ QWidget* SimSettingsView::createSizingParametersWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-design-objects.html#sizingparameters"); + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-design-objects.html#sizingparameters"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Sizing Parameters"))); } @@ -672,7 +673,7 @@ QWidget* SimSettingsView::createTimestepWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QStringLiteral(BIGLADDERSOFTWARE_DOC_BASE_URL "group-simulation-parameters.html#timestep"); + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-simulation-parameters.html#timestep"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Timestep"))); } diff --git a/src/openstudio_lib/YearSettingsWidget.cpp b/src/openstudio_lib/YearSettingsWidget.cpp index a2d761e69..2ef235034 100644 --- a/src/openstudio_lib/YearSettingsWidget.cpp +++ b/src/openstudio_lib/YearSettingsWidget.cpp @@ -4,6 +4,7 @@ ***********************************************************************************************************************/ #include "YearSettingsWidget.hpp" +#include "../utilities/OpenStudioApplicationPathHelpers.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" @@ -107,9 +108,8 @@ YearSettingsWidget::YearSettingsWidget(const model::Model& model, QWidget* paren dstLabel->setTextFormat(Qt::RichText); dstLabel->setOpenExternalLinks(true); { - static const QString url = QStringLiteral( - BIGLADDERSOFTWARE_DOC_BASE_URL - "group-location-climate-weather-file-access.html#field-daylight-saving-time-indicator"); + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + + "group-location-climate-weather-file-access.html#field-daylight-saving-time-indicator"; dstLabel->setToolTip(url); dstLabel->setText(QStringLiteral(R"(%2)").arg(url, tr("Daylight Savings Time:"))); } diff --git a/src/utilities/OpenStudioApplicationPathHelpers.cxx.in b/src/utilities/OpenStudioApplicationPathHelpers.cxx.in index ff82e797d..b4631ea6d 100644 --- a/src/utilities/OpenStudioApplicationPathHelpers.cxx.in +++ b/src/utilities/OpenStudioApplicationPathHelpers.cxx.in @@ -205,6 +205,10 @@ bool isOpenStudioApplicationModuleRunningFromBuildDirectory() { return pathBeginsWith(buildDir, runDir); } +std::string bigladdersoftwareDocBaseUrl() { + return "${BIGLADDERSOFTWARE_DOC_BASE_URL}"; +} + openstudio::path getOpenStudioCoreCLI() { openstudio::path cliPath; diff --git a/src/utilities/OpenStudioApplicationPathHelpers.hpp b/src/utilities/OpenStudioApplicationPathHelpers.hpp index 1a334ffc6..5a99366bd 100644 --- a/src/utilities/OpenStudioApplicationPathHelpers.hpp +++ b/src/utilities/OpenStudioApplicationPathHelpers.hpp @@ -60,6 +60,9 @@ OSAPP_UTILITIES_API bool isOpenStudioApplicationModuleRunningFromBuildDirectory( /// \returns The path to the OpenStudio Command Line Interface if it exists. OSAPP_UTILITIES_API openstudio::path getOpenStudioCoreCLI(); +/// \returns The base URL for the BigLadder EnergyPlus I/O Reference (versioned, trailing slash included) +OSAPP_UTILITIES_API std::string bigladdersoftwareDocBaseUrl(); + } // namespace openstudio #endif //OSAPP_UTILITIES_APPLICATIONPATHHELPERS_HPP From 464183025de7c4deb47bc5d6b3e8b5c4aa37a16c Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 22:20:08 +0200 Subject: [PATCH 08/18] chore: add check_doc_urls.py script to verify BigLadder doc link anchors Scans IddObjectDocUrl.hpp and all .cpp files that reference bigladdersoftwareDocBaseUrl(), fetches each unique BigLadder page once, and verifies that every anchor ID referenced actually exists in the page HTML. Exits 0 if all OK, 1 if any anchors are missing or pages fail to load. Usage: python scripts/check_doc_urls.py [--repo-root PATH] [--delay SEC] Co-Authored-By: Claude Sonnet 4.6 --- scripts/check_doc_urls.py | 196 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 scripts/check_doc_urls.py diff --git a/scripts/check_doc_urls.py b/scripts/check_doc_urls.py new file mode 100644 index 000000000..74ab1e17a --- /dev/null +++ b/scripts/check_doc_urls.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python3 +""" +check_doc_urls.py - Verify BigLadder EnergyPlus I/O Reference URLs in OpenStudioApp source. + +Scans source files for doc URL strings, fetches each unique page once, checks that +every anchor referenced actually exists in the page HTML, and reports failures. + +Usage: + python scripts/check_doc_urls.py [--repo-root PATH] + +Exit codes: + 0 All URLs valid + 1 One or more broken/missing anchors found + 2 Usage / dependency error +""" + +import argparse +import re +import sys +import time +from collections import defaultdict +from html.parser import HTMLParser +from pathlib import Path +from urllib.request import urlopen +from urllib.error import URLError + +# --------------------------------------------------------------------------- +# Files to scan and the regex patterns that extract URL fragments from them +# --------------------------------------------------------------------------- + +# Matches values in the IddObjectDocUrl.hpp urlMap: +# {"OS:Something", "group-foo.html#anchor"}, +IDDOBJECTDOCURL_PATTERN = re.compile( + r'"OS:[^"]+"\s*,\s*"([^"]+\.html(?:#[^"]*)?)"' +) + +# Matches QString URL constructions in .cpp files: +# QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "page.html#anchor" +# or the old QStringLiteral(BASE "page.html#anchor") form +CPP_URL_FRAGMENT_PATTERN = re.compile( + r'(?:bigladdersoftwareDocBaseUrl\(\)\s*\+\s*"([^"]+\.html(?:#[^"]*)?)"' + r'|QStringLiteral\(BIGLADDERSOFTWARE_DOC_BASE_URL\s*"([^"]+\.html(?:#[^"]*)?)"' + r'|\+\s*"(group-[^"]+\.html(?:#[^"]*)?)"' + r'|\+\s*"(lifecyclecost-[^"]+\.html(?:#[^"]*)?)")' +) + +SOURCE_FILES = [ + "src/model_editor/IddObjectDocUrl.hpp", + "src/openstudio_lib/SimSettingsView.cpp", + "src/openstudio_lib/LoadsView.cpp", + "src/openstudio_lib/ConstructionsView.cpp", + "src/openstudio_lib/MaterialsView.cpp", + "src/openstudio_lib/ScheduleOthersView.cpp", + "src/openstudio_lib/LocationTabView.cpp", + "src/openstudio_lib/YearSettingsWidget.cpp", + "src/openstudio_lib/GroundTemperatureView.cpp", + "src/openstudio_lib/LifeCycleCostsTabView.cpp", + "src/openstudio_lib/BuildingInspectorView.cpp", +] + +BIGLADDERSOFTWARE_BASE = "https://bigladdersoftware.com/epx/docs/25-1/input-output-reference/" + + +# --------------------------------------------------------------------------- +# HTML parser that collects all id= attributes +# --------------------------------------------------------------------------- + +class AnchorCollector(HTMLParser): + def __init__(self): + super().__init__() + self.ids = set() + + def handle_starttag(self, tag, attrs): + for name, value in attrs: + if name == "id" and value: + self.ids.add(value) + + +# --------------------------------------------------------------------------- +# URL extraction +# --------------------------------------------------------------------------- + +def extract_fragments(repo_root: Path): + """ + Returns a dict: page_url -> list of (anchor_or_None, source_file, line_no) + """ + results = defaultdict(list) + + for rel_path in SOURCE_FILES: + src = repo_root / rel_path + if not src.exists(): + print(f" WARNING: {rel_path} not found, skipping", file=sys.stderr) + continue + + text = src.read_text(encoding="utf-8") + + if rel_path.endswith("IddObjectDocUrl.hpp"): + pattern = IDDOBJECTDOCURL_PATTERN + else: + pattern = CPP_URL_FRAGMENT_PATTERN + + for lineno, line in enumerate(text.splitlines(), 1): + for m in pattern.finditer(line): + fragment = next((g for g in m.groups() if g), None) + if not fragment: + continue + if "#" in fragment: + page_part, anchor = fragment.split("#", 1) + else: + page_part, anchor = fragment, None + page_url = BIGLADDERSOFTWARE_BASE + page_part + results[page_url].append((anchor, rel_path, lineno)) + + return results + + +# --------------------------------------------------------------------------- +# Page fetching with simple cache +# --------------------------------------------------------------------------- + +def fetch_anchors(url: str, delay: float = 0.5) -> set | None: + """Fetch a page and return the set of id= values, or None on error.""" + try: + time.sleep(delay) + with urlopen(url, timeout=15) as resp: + html = resp.read().decode("utf-8", errors="replace") + parser = AnchorCollector() + parser.feed(html) + return parser.ids + except URLError as e: + print(f" ERROR fetching {url}: {e}", file=sys.stderr) + return None + + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--repo-root", + default=".", + help="Path to the OpenStudioApplication repo root (default: current directory)", + ) + parser.add_argument( + "--delay", + type=float, + default=0.5, + help="Seconds to wait between page fetches (default: 0.5)", + ) + args = parser.parse_args() + + repo_root = Path(args.repo_root).resolve() + print(f"Scanning repo: {repo_root}") + + fragments = extract_fragments(repo_root) + if not fragments: + print("No URLs found — check SOURCE_FILES list.", file=sys.stderr) + sys.exit(2) + + print(f"\nFound {sum(len(v) for v in fragments.values())} URL references across {len(fragments)} unique pages.\n") + + failures = [] + page_cache = {} + + for page_url in sorted(fragments): + print(f"Checking: {page_url}") + if page_url not in page_cache: + page_cache[page_url] = fetch_anchors(page_url, delay=args.delay) + + page_ids = page_cache[page_url] + + for anchor, src_file, lineno in fragments[page_url]: + if page_ids is None: + failures.append((src_file, lineno, page_url, anchor, "page fetch failed")) + elif anchor and anchor not in page_ids: + failures.append((src_file, lineno, page_url, anchor, "anchor not found in page")) + else: + status = "OK" if anchor else "OK (no anchor)" + print(f" {status}: #{anchor or ''}") + + print() + if failures: + print(f"FAILURES ({len(failures)}):") + for src_file, lineno, page_url, anchor, reason in failures: + print(f" {src_file}:{lineno} #{anchor} -> {reason}") + print(f" {page_url}#{anchor or ''}") + sys.exit(1) + else: + print("All URLs OK.") + sys.exit(0) + + +if __name__ == "__main__": + main() From dda4e2819b6ed1545c3981d2ad493dca7c63669e Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Sun, 31 May 2026 23:12:38 +0200 Subject: [PATCH 09/18] fix: correct 31 broken/wrong-page doc URL anchors in IddObjectDocUrl.hpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Identified by scripts/check_doc_urls.py which fetches BigLadder pages and verifies anchor IDs exist in the HTML. Fixes include: - Wrong page: RunPeriod, InternalMass, PlantLoop/CondenserLoop, AvailabilityManagerAssignmentList, HeatExchanger:FluidToFluid, OutdoorAir:Mixer, ZoneMixer/Splitter/ReturnPlenum/SupplyPlenum - Typos: materialaingap→materialairgap, celdeckpad→celdekpad (×2), outdoorarreset→outdoorairreset, multizoneheat/coolaverage→heating/coolingaverage - Sphinx suffixes: lights→lights-000, construction→construction-000, daylightingcontrols→daylightingcontrols-000 - Hyphen removal: buildingsurface-detailed→buildingsurfacedetailed, fenestrationsurface-detailed→fenestrationsurfacedetailed - Renames: Uncontrolled→ConstantVolume:NoReheat, Fuel→Gas-000, ShadingControl→WindowPropertyShadingControl, WaterHeaterHeatPump→WaterHeaterHeatPumpPumpedCondenser, GroundHeatExchanger:Vertical→GroundHeatExchangerSystem - FourPipeBeam coils moved to air-distribution-equipment page 7 anchors remain unverifiable (page too long for fetch tool): HeatPump:PlantLoop:EIR:Cooling/Heating, PLHP:AirToWater (×3), WindowProperty:FrameAndDivider, InteriorPartitionSurface:Detailed. Also updates check_doc_urls.py docstring with rationale for choosing Python script over GTest, and updates OpenStudioApplicationPathHelpers with bigladdersoftwareDocBaseUrl() accessor function. Co-Authored-By: Claude Sonnet 4.6 --- scripts/check_doc_urls.py | 18 ++++++- src/model_editor/IddObjectDocUrl.hpp | 70 +++++++++++++------------- src/openstudio_lib/LocationTabView.cpp | 2 +- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/scripts/check_doc_urls.py b/scripts/check_doc_urls.py index 74ab1e17a..c574c076c 100644 --- a/scripts/check_doc_urls.py +++ b/scripts/check_doc_urls.py @@ -6,12 +6,28 @@ every anchor referenced actually exists in the page HTML, and reports failures. Usage: - python scripts/check_doc_urls.py [--repo-root PATH] + python scripts/check_doc_urls.py [--repo-root PATH] [--delay SEC] Exit codes: 0 All URLs valid 1 One or more broken/missing anchors found 2 Usage / dependency error + +Why a Python script rather than a GTest network test +----------------------------------------------------- +BigLadder returns HTTP 200 for *any* URL on an existing page, regardless of whether +the anchor exists. A plain HTTP HEAD or GET check would silently pass even when an +anchor has been renamed or removed. Verifying anchor IDs requires fetching the full +page HTML and scanning for id="..." attributes — straightforward in Python with +html.parser, but awkward in C++/Qt without a full HTML parser dependency. + +GTest network tests were also considered but ruled out because: + - They are slow and flaky in CI (network dependency). + - QNetworkAccessManager requires a running event loop and async handling. + - GTest provides no natural mechanism to fetch-and-parse HTML for anchor checks. + +This script runs standalone (no build step), can be invoked as a pre-commit hook or +CI job, and completes in roughly one second per unique page fetched. """ import argparse diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 8189c4804..01dc100d5 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -23,7 +23,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:SimulationControl", "group-simulation-parameters.html#simulationcontrol"}, {"OS:Building", "group-simulation-parameters.html#building"}, {"OS:Timestep", "group-simulation-parameters.html#timestep"}, - {"OS:RunPeriod", "group-simulation-parameters.html#runperiod"}, + {"OS:RunPeriod", "group-location-climate-weather-file-access.html#runperiod"}, {"OS:ShadowCalculation", "group-simulation-parameters.html#shadowcalculation"}, {"OS:SurfaceConvectionAlgorithm:Inside", "group-simulation-parameters.html#surfaceconvectionalgorithminside"}, {"OS:SurfaceConvectionAlgorithm:Outside", "group-simulation-parameters.html#surfaceconvectionalgorithmoutside"}, @@ -56,7 +56,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { // Surface Construction Elements {"OS:Material", "group-surface-construction-elements.html#material"}, {"OS:Material:NoMass", "group-surface-construction-elements.html#materialnomass"}, - {"OS:Material:AirGap", "group-surface-construction-elements.html#materialaingap"}, + {"OS:Material:AirGap", "group-surface-construction-elements.html#materialairgap"}, {"OS:Material:InfraredTransparent", "group-surface-construction-elements.html#materialinfraredtransparent"}, {"OS:Material:RoofVegetation", "group-surface-construction-elements.html#materialroofvegetation"}, {"OS:WindowMaterial:Glazing", "group-surface-construction-elements.html#windowmaterialglazing"}, @@ -66,7 +66,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:WindowMaterial:Blind", "group-surface-construction-elements.html#windowmaterialblind"}, {"OS:WindowMaterial:Screen", "group-surface-construction-elements.html#windowmaterialscreen"}, {"OS:WindowMaterial:Shade", "group-surface-construction-elements.html#windowmaterialshade"}, - {"OS:Construction", "group-surface-construction-elements.html#construction"}, + {"OS:Construction", "group-surface-construction-elements.html#construction-000"}, {"OS:Construction:InternalSource", "group-surface-construction-elements.html#constructioninternalsource"}, {"OS:Construction:WindowDataFile", "group-surface-construction-elements.html#constructionwindowdatafile"}, {"OS:WindowProperty:FrameAndDivider", "group-surface-construction-elements.html#windowpropertyframeanddivider"}, @@ -76,27 +76,27 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Space", "group-thermal-zone-description-geometry.html"}, {"OS:SpaceType", "group-thermal-zone-description-geometry.html"}, {"OS:BuildingStory", "group-thermal-zone-description-geometry.html"}, - {"OS:Surface", "group-thermal-zone-description-geometry.html#buildingsurface-detailed"}, - {"OS:SubSurface", "group-thermal-zone-description-geometry.html#fenestrationsurface-detailed"}, - {"OS:ShadingControl", "group-thermal-zone-description-geometry.html#shadingcontrol"}, + {"OS:Surface", "group-thermal-zone-description-geometry.html#buildingsurfacedetailed"}, + {"OS:SubSurface", "group-thermal-zone-description-geometry.html#fenestrationsurfacedetailed"}, + {"OS:ShadingControl", "group-thermal-zone-description-geometry.html#windowpropertyshadingcontrol"}, {"OS:InteriorPartitionSurface", "group-thermal-zone-description-geometry.html#interiorpartitionsurface-detailed"}, {"OS:InteriorPartitionSurfaceGroup", "group-thermal-zone-description-geometry.html"}, // Daylighting - {"OS:Daylighting:Control", "group-daylighting.html#daylightingcontrols"}, + {"OS:Daylighting:Control", "group-daylighting.html#daylightingcontrols-000"}, {"OS:DaylightingDevice:Shelf", "group-daylighting.html#daylightingdeviceshelf"}, {"OS:DaylightingDevice:Tubular", "group-daylighting.html#daylightingdevicetubular"}, {"OS:DaylightingDevice:LightWell", "group-daylighting.html#daylightingdevicelightwell"}, // Internal Gains {"OS:People", "group-internal-gains-people-lights-other.html#people"}, - {"OS:Lights", "group-internal-gains-people-lights-other.html#lights"}, + {"OS:Lights", "group-internal-gains-people-lights-other.html#lights-000"}, {"OS:ElectricEquipment", "group-internal-gains-people-lights-other.html#electricequipment"}, {"OS:GasEquipment", "group-internal-gains-people-lights-other.html#gasequipment"}, - {"OS:HotWaterEquipment", "group-internal-gains-people-lights-other.html#hotwatersupportequipment"}, + {"OS:HotWaterEquipment", "group-internal-gains-people-lights-other.html#hotwaterequipment"}, {"OS:SteamEquipment", "group-internal-gains-people-lights-other.html#steamequipment"}, {"OS:OtherEquipment", "group-internal-gains-people-lights-other.html#otherequipment"}, - {"OS:InternalMass", "group-internal-gains-people-lights-other.html#internalmass"}, + {"OS:InternalMass", "group-thermal-zone-description-geometry.html#internalmass"}, {"OS:SwimmingPool:Indoor", "group-internal-gains-people-lights-other.html#swimmingpoolindoor"}, // Exterior Energy Use @@ -167,16 +167,16 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat", "group-air-distribution-equipment.html#airterminalsingleductvavheatandcoolreheat"}, {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductvavheatandcoolnoreheat"}, {"OS:AirTerminal:SingleDuct:ConstantVolume:Reheat", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumereheat"}, - {"OS:AirTerminal:SingleDuct:ConstantVolume:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductuncontrolled"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumenoreheat"}, {"OS:AirTerminal:SingleDuct:ConstantVolume:CooledBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumecooledbeam"}, {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, - {"OS:AirTerminal:SingleDuct:ParallelPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductparallelpiu"}, - {"OS:AirTerminal:SingleDuct:SeriesPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductseriespiu"}, - {"OS:AirTerminal:SingleDuct:InletSideMixer", "group-air-distribution-equipment.html#airterminalsingleductinletsidemixer"}, + {"OS:AirTerminal:SingleDuct:ParallelPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductparallelpiureheat"}, + {"OS:AirTerminal:SingleDuct:SeriesPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductseriespiureheat"}, + {"OS:AirTerminal:SingleDuct:InletSideMixer", "group-air-distribution-equipment.html#airterminalsingleductmixer"}, {"OS:AirTerminal:DualDuct:VAV", "group-air-distribution-equipment.html#airterminaldualductvav"}, {"OS:AirTerminal:DualDuct:VAV:OutdoorAir", "group-air-distribution-equipment.html#airterminaldualductvavoutdoorair"}, {"OS:AirTerminal:DualDuct:ConstantVolume", "group-air-distribution-equipment.html#airterminaldualductconstantvolume"}, - {"OS:AirTerminal:FourPipeInduction", "group-air-distribution-equipment.html#airterminalfourpipeinduction"}, + {"OS:AirTerminal:FourPipeInduction", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipeinduction"}, {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipeinduction"}, // Fans @@ -198,7 +198,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Coil:Cooling:Water:DetailedGeometry", "group-heating-and-cooling-coils.html#coilcoolingwaterdetailedgeometry"}, {"OS:Coil:Cooling:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpequationfit"}, {"OS:Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpvariablespeedequationfit"}, - {"OS:Coil:Cooling:FourPipeBeam", "group-heating-and-cooling-coils.html#coilcoolingfourpipebeam"}, + {"OS:Coil:Cooling:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, {"OS:Coil:Cooling:DX:TwoStageWithHumidityControlMode", "group-heating-and-cooling-coils.html#coilcoolingdxtwostagewithhumiditycontrolmode"}, {"OS:Coil:Cooling:DX:MultiSpeed:StageData", "group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, {"OS:Coil:Cooling:Water:Panel:Radiant", "group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, @@ -208,7 +208,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { // Coils - Heating {"OS:Coil:Heating:Gas", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, - {"OS:Coil:Heating:Fuel", "group-heating-and-cooling-coils.html#coilheatingfuel"}, + {"OS:Coil:Heating:Fuel", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, {"OS:Coil:Heating:Electric", "group-heating-and-cooling-coils.html#coilheatingelectric"}, {"OS:Coil:Heating:Water", "group-heating-and-cooling-coils.html#coilheatingwater"}, {"OS:Coil:Heating:DX:SingleSpeed", "group-heating-and-cooling-coils.html#coilheatingdxsinglespeed"}, @@ -219,7 +219,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Coil:Heating:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpequationfit"}, {"OS:Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpvariablespeedequationfit"}, {"OS:Coil:Heating:Desuperheater", "group-heating-and-cooling-coils.html#coilheatingdesuperheater"}, - {"OS:Coil:Heating:FourPipeBeam", "group-heating-and-cooling-coils.html#coilheatingfourpipebeam"}, + {"OS:Coil:Heating:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, {"OS:Coil:Heating:Gas:MultiStage", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, {"OS:Coil:Heating:Gas:MultiStage:StageData", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, {"OS:Coil:Heating:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, @@ -234,8 +234,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { // Evaporative Coolers {"OS:EvaporativeCooler:Direct:ResearchSpecial", "group-evaporative-coolers.html#evaporativecoolerdirectresearchspecial"}, {"OS:EvaporativeCooler:Indirect:ResearchSpecial", "group-evaporative-coolers.html#evaporativecoolerindirectresearchspecial"}, - {"OS:EvaporativeCooler:Direct:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerdirectceldeckpad"}, - {"OS:EvaporativeCooler:Indirect:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerindirectceldeckpad"}, + {"OS:EvaporativeCooler:Direct:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerdirectceldekpad"}, + {"OS:EvaporativeCooler:Indirect:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerindirectceldekpad"}, {"OS:EvaporativeCooler:Indirect:WetCoil", "group-evaporative-coolers.html#evaporativecoolerindirectwetcoil"}, // Humidifiers @@ -256,20 +256,20 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { // Air Distribution / AirLoop {"OS:AirLoopHVAC", "group-air-distribution.html#group-air-distribution"}, {"OS:AirLoopHVAC:OutdoorAirSystem", "group-air-distribution.html#airloophvacoutdoorairsystem"}, - {"OS:OutdoorAir:Mixer", "group-airflow.html#outdoorairmixer"}, + {"OS:OutdoorAir:Mixer", "group-air-distribution.html#outdoorairmixer"}, {"OS:Controller:OutdoorAir", "group-controllers.html#controlleroutdoorair"}, {"OS:Controller:MechanicalVentilation", "group-controllers.html#controllermechanicalventilation"}, {"OS:ZoneHVAC:EnergyRecoveryVentilator:Controller", "group-controllers.html#zonehvacenergyrecoveryventilatorcontroller"}, - {"OS:AirLoopHVAC:ZoneMixer", "group-airflow.html#airloophvaczonemixer"}, - {"OS:AirLoopHVAC:ZoneSplitter", "group-airflow.html#airloophvaczonesplitter"}, - {"OS:AirLoopHVAC:ReturnPlenum", "group-airflow.html#airloophvacreturnplenum"}, - {"OS:AirLoopHVAC:SupplyPlenum", "group-airflow.html#airloophvacsupplyplenum"}, + {"OS:AirLoopHVAC:ZoneMixer", "group-air-path.html#airloophvaczonemixer"}, + {"OS:AirLoopHVAC:ZoneSplitter", "group-air-path.html#airloophvaczonesplitter"}, + {"OS:AirLoopHVAC:ReturnPlenum", "group-air-path.html#airloophvacreturnplenum"}, + {"OS:AirLoopHVAC:SupplyPlenum", "group-air-path.html#airloophvacsupplyplenum"}, // Setpoint Managers {"OS:SetpointManager:Scheduled", "group-setpoint-managers.html#setpointmanagerscheduled"}, {"OS:SetpointManager:Scheduled:DualSetpoint", "group-setpoint-managers.html#setpointmanagerscheduleddualsetpoint"}, {"OS:SetpointManager:MixedAir", "group-setpoint-managers.html#setpointmanagermixedair"}, - {"OS:SetpointManager:OutdoorAirReset", "group-setpoint-managers.html#setpointmanageroutdoorarreset"}, + {"OS:SetpointManager:OutdoorAirReset", "group-setpoint-managers.html#setpointmanageroutdoorairreset"}, {"OS:SetpointManager:SingleZone:Reheat", "group-setpoint-managers.html#setpointmanagersinglezonereheat"}, {"OS:SetpointManager:SingleZone:Heating", "group-setpoint-managers.html#setpointmanagersinglezoneheating"}, {"OS:SetpointManager:SingleZone:Cooling", "group-setpoint-managers.html#setpointmanagersinglezonecooling"}, @@ -280,8 +280,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:SetpointManager:CondenserEnteringReset", "group-setpoint-managers.html#setpointmanagercondenserenteringreset"}, {"OS:SetpointManager:WarmestTemperatureFlow", "group-setpoint-managers.html#setpointmanagerwarmesttemperatureflow"}, {"OS:SetpointManager:OutdoorAirPretreat", "group-setpoint-managers.html#setpointmanageroutdoorairpretreat"}, - {"OS:SetpointManager:MultiZone:Heating:Average", "group-setpoint-managers.html#setpointmanagermultizoneheataverage"}, - {"OS:SetpointManager:MultiZone:Cooling:Average", "group-setpoint-managers.html#setpointmanagermultizonecoolaverage"}, + {"OS:SetpointManager:MultiZone:Heating:Average", "group-setpoint-managers.html#setpointmanagermultizoneheatingaverage"}, + {"OS:SetpointManager:MultiZone:Cooling:Average", "group-setpoint-managers.html#setpointmanagermultizonecoolingaverage"}, {"OS:SetpointManager:FollowSystemNodeTemperature", "group-setpoint-managers.html#setpointmanagerfollowsystemnodetemperature"}, {"OS:SetpointManager:MultiZone:Humidity:Maximum", "group-setpoint-managers.html#setpointmanagermultizonehumiditymaximum"}, {"OS:SetpointManager:MultiZone:Humidity:Minimum", "group-setpoint-managers.html#setpointmanagermultizonehumidityminimum"}, @@ -315,7 +315,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Chiller:Electric:ReformulatedEIR", "group-plant-equipment.html#chillerelectricreformulatedeir"}, {"OS:Chiller:Absorption", "group-plant-equipment.html#chillerabsorption"}, {"OS:Chiller:Absorption:Indirect", "group-plant-equipment.html#chillerabsorptionindirect"}, - {"OS:Chiller:Absorption:Direct", "group-plant-equipment.html#chillerabsorptiondirect"}, + {"OS:Chiller:Absorption:Direct", "group-plant-equipment.html#chillerabsorption"}, {"OS:ChillerHeater:Absorption:DirectFired", "group-plant-equipment.html#chillerheaterabsorptiondirectfired"}, {"OS:DistrictCooling", "group-plant-equipment.html#districtcooling"}, {"OS:DistrictHeating", "group-plant-equipment.html#districtheating"}, @@ -349,18 +349,18 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { // Heat Recovery {"OS:HeatExchanger:AirToAir:SensibleAndLatent", "group-heat-recovery.html#heatexchangerairtoairsensibleandlatent"}, - {"OS:HeatExchanger:FluidToFluid", "group-heat-recovery.html#heatexchangerfluidtofluid"}, + {"OS:HeatExchanger:FluidToFluid", "group-condenser-equipment.html#heatexchangerfluidtofluid"}, {"OS:HeatExchanger:Desiccant:BalancedFlow", "group-heat-recovery.html#heatexchangerdesiccantbalancedflow"}, // Condenser Equipment and Ground Heat Exchangers - {"OS:GroundHeatExchanger:Vertical", "group-condenser-equipment.html#groundheatexchangervertical"}, + {"OS:GroundHeatExchanger:Vertical", "group-condenser-equipment.html#groundheatexchangersystem"}, {"OS:GroundHeatExchanger:HorizontalTrench", "group-condenser-equipment.html#groundheatexchangerhorizontaltrench"}, {"OS:GroundHeatExchanger:Slinky", "group-condenser-equipment.html#groundheatexchangerslinky"}, // Water Heaters and Thermal Storage {"OS:WaterHeater:Mixed", "group-water-heaters.html#waterheatermixed"}, {"OS:WaterHeater:Stratified", "group-water-heaters.html#waterheaterstratified"}, - {"OS:WaterHeater:HeatPump", "group-water-heaters.html#waterheaterheatpump"}, + {"OS:WaterHeater:HeatPump", "group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, {"OS:WaterHeater:HeatPump:PumpedCondenser", "group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, {"OS:WaterHeater:HeatPump:WrappedCondenser", "group-water-heaters.html#waterheaterheatpumpwrappedcondenser"}, {"OS:WaterHeater:Sizing", "group-water-heaters.html#waterheatersizing"}, @@ -397,8 +397,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Duct", "group-node-branch-management.html#duct"}, // Plant / Condenser Control - {"OS:PlantLoop", "group-plant-condenser-control.html#plantloop"}, - {"OS:CondenserLoop", "group-plant-condenser-control.html#condenserloop"}, + {"OS:PlantLoop", "group-plant-condenser-loops.html#plantloop"}, + {"OS:CondenserLoop", "group-plant-condenser-loops.html#condenserloop"}, {"OS:PlantEquipmentList", "group-plant-condenser-control.html#plantequipmentlist"}, {"OS:PlantEquipmentOperation:CoolingLoad", "group-plant-condenser-control.html#plantequipmentoperationcoolingload"}, {"OS:PlantEquipmentOperation:HeatingLoad", "group-plant-condenser-control.html#plantequipmentoperationheatingload"}, @@ -409,7 +409,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:PlantEquipmentOperation:Uncontrolled", "group-plant-condenser-control.html#plantequipmentoperationuncontrolled"}, {"OS:TemperingValve", "group-plant-condenser-flow-control.html#temperingvalve"}, {"OS:LoadProfile:Plant", "group-non-zone-equipment.html#loadprofileplant"}, - {"OS:AvailabilityManagerAssignmentList", "group-system-availability-managers.html#availabilitymanagerassignmentlist"}, + {"OS:AvailabilityManagerAssignmentList", "group-air-distribution.html#availabilitymanagerassignmentlist"}, {"OS:AvailabilityManager:Scheduled", "group-system-availability-managers.html#availabilitymanagerscheduled"}, {"OS:AvailabilityManager:ScheduledOn", "group-system-availability-managers.html#availabilitymanagerscheduledon"}, {"OS:AvailabilityManager:ScheduledOff", "group-system-availability-managers.html#availabilitymanagerscheduledoff"}, diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index 23e0070d5..58d403330 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -216,7 +216,7 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& label->setOpenExternalLinks(true); { static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) - + "group-location-climate-weather-file-access.html#group----location----climate----weather-file-access"; + + "group-location-climate-weather-file-access.html"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Weather File"))); } From a1bcc574f82acc88c587b598a1bbf0dd27cc207e Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Mon, 1 Jun 2026 08:22:01 +0200 Subject: [PATCH 10/18] fix: resolve final 7 broken anchors in IddObjectDocUrl.hpp - WindowProperty:FrameAndDivider: correct page (thermal-zone not surface-construction) - InteriorPartitionSurface: remove (no EnergyPlus object, not user-facing in GUI) - HeatPump:PlantLoop:EIR:Cooling/Heating: correct anchors (#plhp_eir_cooling/heating) - HeatPump:AirToWater / :Cooling / :Heating: remove (no EnergyPlus object) All 384 URL references now pass check_doc_urls.py verification. Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/IddObjectDocUrl.hpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 01dc100d5..679e5234a 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -69,7 +69,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Construction", "group-surface-construction-elements.html#construction-000"}, {"OS:Construction:InternalSource", "group-surface-construction-elements.html#constructioninternalsource"}, {"OS:Construction:WindowDataFile", "group-surface-construction-elements.html#constructionwindowdatafile"}, - {"OS:WindowProperty:FrameAndDivider", "group-surface-construction-elements.html#windowpropertyframeanddivider"}, + {"OS:WindowProperty:FrameAndDivider", "group-thermal-zone-description-geometry.html#windowpropertyframeanddivider"}, // Thermal Zone Description and Geometry {"OS:ThermalZone", "group-thermal-zone-description-geometry.html"}, @@ -79,7 +79,6 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Surface", "group-thermal-zone-description-geometry.html#buildingsurfacedetailed"}, {"OS:SubSurface", "group-thermal-zone-description-geometry.html#fenestrationsurfacedetailed"}, {"OS:ShadingControl", "group-thermal-zone-description-geometry.html#windowpropertyshadingcontrol"}, - {"OS:InteriorPartitionSurface", "group-thermal-zone-description-geometry.html#interiorpartitionsurface-detailed"}, {"OS:InteriorPartitionSurfaceGroup", "group-thermal-zone-description-geometry.html"}, // Daylighting @@ -320,15 +319,12 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:DistrictCooling", "group-plant-equipment.html#districtcooling"}, {"OS:DistrictHeating", "group-plant-equipment.html#districtheating"}, {"OS:DistrictHeating:Water", "group-plant-equipment.html#districtheating"}, - {"OS:HeatPump:PlantLoop:EIR:Cooling", "group-plant-equipment.html#heatpumpplantloopeircooling"}, - {"OS:HeatPump:PlantLoop:EIR:Heating", "group-plant-equipment.html#heatpumpplantloopeirheating"}, + {"OS:HeatPump:PlantLoop:EIR:Cooling", "group-plant-equipment.html#plhp_eir_cooling"}, + {"OS:HeatPump:PlantLoop:EIR:Heating", "group-plant-equipment.html#plhp_eir_heating"}, {"OS:HeatPump:WaterToWater:EquationFit:Cooling", "group-plant-equipment.html#heatpumpwatertowaterequationfitcooling"}, {"OS:HeatPump:WaterToWater:EquationFit:Heating", "group-plant-equipment.html#heatpumpwatertowaterequationfitheating"}, {"OS:HeatPump:AirToWater:FuelFired:Cooling", "group-plant-equipment.html#plhp_fuelfired"}, {"OS:HeatPump:AirToWater:FuelFired:Heating", "group-plant-equipment.html#plhp_fuelfired"}, - {"OS:HeatPump:AirToWater", "group-plant-equipment.html#plhp_air_to_water"}, - {"OS:HeatPump:AirToWater:Cooling", "group-plant-equipment.html#plhp_air_to_water"}, - {"OS:HeatPump:AirToWater:Heating", "group-plant-equipment.html#plhp_air_to_water"}, {"OS:CentralHeatPumpSystem", "group-plant-equipment.html#centralheatpumpsystem"}, {"OS:CentralHeatPumpSystem:Module", "group-plant-equipment.html#centralheatpumpsystem"}, {"OS:ChillerHeaterPerformance:Electric:EIR", "group-plant-equipment.html#chillerheaterperformancelectriceir"}, From 6ab361c5d1be62e5bee4b92b4194fced00657ed7 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Mon, 1 Jun 2026 08:54:09 +0200 Subject: [PATCH 11/18] style: apply clang-format to PR-touched files Run clang-format -style=file on all C++ files changed relative to develop, to satisfy the Clang Format CI check. Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/InspectorGadget.cpp | 3 +- src/openstudio_lib/BuildingInspectorView.cpp | 3 +- src/openstudio_lib/ConstructionsView.cpp | 5 +- src/openstudio_lib/GroundTemperatureView.cpp | 18 +++---- src/openstudio_lib/LocationTabView.cpp | 3 +- .../OSCollapsibleItemHeader.cpp | 3 +- src/openstudio_lib/SimSettingsView.cpp | 54 +++++++++++++------ src/openstudio_lib/YearSettingsWidget.cpp | 2 +- 8 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/model_editor/InspectorGadget.cpp b/src/model_editor/InspectorGadget.cpp index 5bb4c6084..14e315c6c 100644 --- a/src/model_editor/InspectorGadget.cpp +++ b/src/model_editor/InspectorGadget.cpp @@ -500,8 +500,7 @@ void InspectorGadget::layoutHeaderText(QVBoxLayout* layout, QWidget* parent, con label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); label->setToolTip(docUrl); - label->setText( - QStringLiteral(R"(%2)").arg(docUrl, typeName.toHtmlEscaped())); + label->setText(QStringLiteral(R"(%2)").arg(docUrl, typeName.toHtmlEscaped())); } else { label->setText(typeName); } diff --git a/src/openstudio_lib/BuildingInspectorView.cpp b/src/openstudio_lib/BuildingInspectorView.cpp index 101da0233..149cd1e72 100644 --- a/src/openstudio_lib/BuildingInspectorView.cpp +++ b/src/openstudio_lib/BuildingInspectorView.cpp @@ -443,8 +443,7 @@ BuildingInspectorView::BuildingInspectorView(bool isIP, bool displayAdditionalPr label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = - QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-simulation-parameters.html#building"; + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-simulation-parameters.html#building"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("North Axis: "))); } diff --git a/src/openstudio_lib/ConstructionsView.cpp b/src/openstudio_lib/ConstructionsView.cpp index d28cc3143..b0eeffd86 100644 --- a/src/openstudio_lib/ConstructionsView.cpp +++ b/src/openstudio_lib/ConstructionsView.cpp @@ -26,9 +26,8 @@ namespace openstudio { ConstructionsView::ConstructionsView(bool isIP, const openstudio::model::Model& model, QWidget* parent) - : ModelSubTabView( - new ModelObjectTypeListView(ConstructionsView::modelObjectTypesNamesAndUrls(), model, true, OSItemType::ListItem, false, parent), - new ConstructionsInspectorView(isIP, model, parent), false, parent) { + : ModelSubTabView(new ModelObjectTypeListView(ConstructionsView::modelObjectTypesNamesAndUrls(), model, true, OSItemType::ListItem, false, parent), + new ConstructionsInspectorView(isIP, model, parent), false, parent) { connect(this, &ConstructionsView::toggleUnitsClicked, modelObjectInspectorView(), &ModelObjectInspectorView::toggleUnitsClicked); } diff --git a/src/openstudio_lib/GroundTemperatureView.cpp b/src/openstudio_lib/GroundTemperatureView.cpp index 82b3b7540..5c75ea0c3 100644 --- a/src/openstudio_lib/GroundTemperatureView.cpp +++ b/src/openstudio_lib/GroundTemperatureView.cpp @@ -57,8 +57,7 @@ GroundTemperatureEntry::GroundTemperatureEntry(const QString& label, const QStri m_label->setTextFormat(Qt::RichText); m_label->setOpenExternalLinks(true); m_label->setToolTip(url); - m_label->setText( - QStringLiteral(R"(%2)").arg(url, label.toHtmlEscaped())); + m_label->setText(QStringLiteral(R"(%2)").arg(url, label.toHtmlEscaped())); } else { m_label->setText(label); } @@ -103,16 +102,11 @@ GroundTemperatureListView::GroundTemperatureListView(QWidget* parent) : QWidget( static const QString lcwBase = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html"; - m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), - lcwBase + "#sitegroundtemperaturebuildingsurface", this); - m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), - lcwBase + "#sitegroundtemperatureshallow", this); - m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), - lcwBase + "#sitegroundtemperaturedeep", this); - m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), - lcwBase + "#sitegroundtemperaturefcfactormethod", this); - m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), - lcwBase + "#sitewatermainstemperature", this); + m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), lcwBase + "#sitegroundtemperaturebuildingsurface", this); + m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), lcwBase + "#sitegroundtemperatureshallow", this); + m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), lcwBase + "#sitegroundtemperaturedeep", this); + m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), lcwBase + "#sitegroundtemperaturefcfactormethod", this); + m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), lcwBase + "#sitewatermainstemperature", this); connect(m_bsEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onBuildingSurfaceClicked); connect(m_shEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onShallowClicked); diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index 58d403330..542cdd8b7 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -215,8 +215,7 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) - + "group-location-climate-weather-file-access.html"; + static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Weather File"))); } diff --git a/src/openstudio_lib/OSCollapsibleItemHeader.cpp b/src/openstudio_lib/OSCollapsibleItemHeader.cpp index 68f876135..877b49ddb 100644 --- a/src/openstudio_lib/OSCollapsibleItemHeader.cpp +++ b/src/openstudio_lib/OSCollapsibleItemHeader.cpp @@ -44,8 +44,7 @@ OSCollapsibleItemHeader::OSCollapsibleItemHeader(const QString& text, const OSIt m_textLabel->setTextFormat(Qt::RichText); m_textLabel->setOpenExternalLinks(true); m_textLabel->setToolTip(url); - m_textLabel->setText( - QStringLiteral(R"(%2)").arg(url, m_plainText.toHtmlEscaped())); + m_textLabel->setText(QStringLiteral(R"(%2)").arg(url, m_plainText.toHtmlEscaped())); } else { m_textLabel->setText(m_plainText); } diff --git a/src/openstudio_lib/SimSettingsView.cpp b/src/openstudio_lib/SimSettingsView.cpp index 03e4984e3..b667aed3a 100644 --- a/src/openstudio_lib/SimSettingsView.cpp +++ b/src/openstudio_lib/SimSettingsView.cpp @@ -242,7 +242,8 @@ void SimSettingsView::createWidgets() { static const QString iorf = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); - collapsibleInspector = new CollapsibleInspector(tr("Advanced RunPeriod Parameters"), iorf + "group-location-climate-weather-file-access.html#runperiod", createRunPeriodAdvancedWidget()); + collapsibleInspector = new CollapsibleInspector( + tr("Advanced RunPeriod Parameters"), iorf + "group-location-climate-weather-file-access.html#runperiod", createRunPeriodAdvancedWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:RadianceParameters ******************* @@ -250,7 +251,8 @@ void SimSettingsView::createWidgets() { mainLayout->addWidget(collapsibleInspector); //******************* OS:SimulationControl ******************* - collapsibleInspector = new CollapsibleInspector(tr("Simulation Control"), iorf + "group-simulation-parameters.html#simulationcontrol", createSimulationControlWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Simulation Control"), iorf + "group-simulation-parameters.html#simulationcontrol", createSimulationControlWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ProgramControl ******************* @@ -258,39 +260,53 @@ void SimSettingsView::createWidgets() { mainLayout->addWidget(collapsibleInspector); //******************* OS:OutputControl:ReportingTolerances ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Control Reporting Tolerances"), iorf + "input-for-output.html#outputcontrolreportingtolerances", createOutputControlReportingTolerancesWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Output Control Reporting Tolerances"), iorf + "input-for-output.html#outputcontrolreportingtolerances", + createOutputControlReportingTolerancesWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ConvergenceLimits ******************* - collapsibleInspector = new CollapsibleInspector(tr("Convergence Limits"), iorf + "group-simulation-parameters.html#convergencelimits", createConvergenceLimitsWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Convergence Limits"), iorf + "group-simulation-parameters.html#convergencelimits", createConvergenceLimitsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ShadowCalculation ******************* - collapsibleInspector = new CollapsibleInspector(tr("Shadow Calculation"), iorf + "group-simulation-parameters.html#shadowcalculation", createShadowCalculationWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Shadow Calculation"), iorf + "group-simulation-parameters.html#shadowcalculation", createShadowCalculationWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:SurfaceConvectionAlgorithm:Inside ******************* - collapsibleInspector = new CollapsibleInspector(tr("Inside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithminside", createSurfaceConvectionAlgorithmInsideWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Inside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithminside", + createSurfaceConvectionAlgorithmInsideWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:SurfaceConvectionAlgorithm:Outside ******************* - collapsibleInspector = new CollapsibleInspector(tr("Outside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithmoutside", createSurfaceConvectionAlgorithmOutsideWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Outside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithmoutside", + createSurfaceConvectionAlgorithmOutsideWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:HeatBalanceAlgorithm ******************* - collapsibleInspector = new CollapsibleInspector(tr("Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#heatbalancealgorithm", createHeatBalanceAlgorithmWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#heatbalancealgorithm", + createHeatBalanceAlgorithmWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirHeatBalanceAlgorithm ******************* - collapsibleInspector = new CollapsibleInspector(tr("Zone Air Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#zoneairheatbalancealgorithm", createZoneAirHeatBalanceAlgorithmWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Zone Air Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#zoneairheatbalancealgorithm", + createZoneAirHeatBalanceAlgorithmWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirContaminantBalance ******************* - collapsibleInspector = new CollapsibleInspector(tr("Zone Air Contaminant Balance"), iorf + "group-simulation-parameters.html#zoneaircontaminantbalance", createZoneAirContaminantBalanceWidget()); + collapsibleInspector = new CollapsibleInspector( + tr("Zone Air Contaminant Balance"), iorf + "group-simulation-parameters.html#zoneaircontaminantbalance", createZoneAirContaminantBalanceWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneCapacitanceMultiplier:ResearchSpecial ******************* - collapsibleInspector = new CollapsibleInspector(tr("Zone Capacitance Multiple Research Special"), iorf + "group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial", createZoneCapacitanceMultipleResearchSpecialWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Zone Capacitance Multiple Research Special"), + iorf + "group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial", + createZoneCapacitanceMultipleResearchSpecialWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:JSON ******************* @@ -298,15 +314,19 @@ void SimSettingsView::createWidgets() { mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:Table:SummaryReports ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Table Summary Reports"), iorf + "output-table-summaryreports.html#outputtablesummaryreports", createOutputTableSummaryReportsWidget()); + collapsibleInspector = new CollapsibleInspector( + tr("Output Table Summary Reports"), iorf + "output-table-summaryreports.html#outputtablesummaryreports", createOutputTableSummaryReportsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:Diagnostics ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Diagnostics"), iorf + "group-simulation-parameters.html#outputdiagnostics", createOutputDiagnosticsWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Output Diagnostics"), iorf + "group-simulation-parameters.html#outputdiagnostics", createOutputDiagnosticsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:OutputControl:ResilienceSummaries ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output Control Resilience Summaries"), iorf + "input-for-output.html#OutputControlResilienceSummaries", createOutputControlResilienceSummariesWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Output Control Resilience Summaries"), iorf + "input-for-output.html#OutputControlResilienceSummaries", + createOutputControlResilienceSummariesWidget()); mainLayout->addWidget(collapsibleInspector); mainLayout->addStretch(); @@ -332,7 +352,8 @@ QWidget* SimSettingsView::createRunPeriodWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html#runperiod"; + static const QString url = + QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html#runperiod"; label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Run Period"))); } @@ -618,7 +639,8 @@ QWidget* SimSettingsView::createSizingParametersWidget() { { static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-design-objects.html#sizingparameters"; label->setToolTip(url); - label->setText(QStringLiteral(R"(%2)").arg(url, tr("Sizing Parameters"))); + label->setText( + QStringLiteral(R"(%2)").arg(url, tr("Sizing Parameters"))); } mainLayout->addWidget(label); diff --git a/src/openstudio_lib/YearSettingsWidget.cpp b/src/openstudio_lib/YearSettingsWidget.cpp index 2ef235034..10d52631c 100644 --- a/src/openstudio_lib/YearSettingsWidget.cpp +++ b/src/openstudio_lib/YearSettingsWidget.cpp @@ -109,7 +109,7 @@ YearSettingsWidget::YearSettingsWidget(const model::Model& model, QWidget* paren dstLabel->setOpenExternalLinks(true); { static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) - + "group-location-climate-weather-file-access.html#field-daylight-saving-time-indicator"; + + "group-location-climate-weather-file-access.html#field-daylight-saving-time-indicator"; dstLabel->setToolTip(url); dstLabel->setText(QStringLiteral(R"(%2)").arg(url, tr("Daylight Savings Time:"))); } From 2e6866e0329414aac48c8f22dff94830af3de09e Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Mon, 1 Jun 2026 09:43:52 +0200 Subject: [PATCH 12/18] fix: address macumber review comments on IddObjectDocUrl and BuildingInspectorView - Add qWarning log when iddObjectDocUrl cannot find a URL for a type - Use iddObjectDocUrl("OS:Building") in BuildingInspectorView instead of hardcoded URL fragment, consolidating all URL fragments in one place Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/IddObjectDocUrl.hpp | 4 +++- src/openstudio_lib/BuildingInspectorView.cpp | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 679e5234a..002fee04d 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -8,6 +8,7 @@ #include #include +#include #include "../utilities/OpenStudioApplicationPathHelpers.hpp" @@ -459,7 +460,8 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { if (it != urlMap.constEnd()) { return base + it.value(); } - return QString(); + qWarning() << "Cannot find doc url for: " + iddTypeName; + return {}; } #endif // MODELEDITOR_IDDOBJECTDOCURL_HPP diff --git a/src/openstudio_lib/BuildingInspectorView.cpp b/src/openstudio_lib/BuildingInspectorView.cpp index 149cd1e72..416605706 100644 --- a/src/openstudio_lib/BuildingInspectorView.cpp +++ b/src/openstudio_lib/BuildingInspectorView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "BuildingInspectorView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSIntegerEdit.hpp" @@ -443,7 +443,7 @@ BuildingInspectorView::BuildingInspectorView(bool isIP, bool displayAdditionalPr label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-simulation-parameters.html#building"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:Building")); label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("North Axis: "))); } From 73631dabfe247773ca6bcb1a1d726b011282c706 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Mon, 1 Jun 2026 11:26:46 +0200 Subject: [PATCH 13/18] feat: add iddGroupDocUrl() mapping OpenStudio IDD groups to BigLadder pages Adds a new iddGroupDocUrl(groupName) function to IddObjectDocUrl.hpp that maps OpenStudio.idd \group names to their corresponding BigLadder EnergyPlus I/O Reference page URLs. Groups that span multiple EnergyPlus chapters (e.g. "OpenStudio HVAC") are intentionally omitted. Also updates check_doc_urls.py regex to cover groupMap entries alongside the existing urlMap entries. Co-Authored-By: Claude Sonnet 4.6 --- scripts/check_doc_urls.py | 5 ++-- src/model_editor/IddObjectDocUrl.hpp | 36 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/scripts/check_doc_urls.py b/scripts/check_doc_urls.py index c574c076c..959bc766b 100644 --- a/scripts/check_doc_urls.py +++ b/scripts/check_doc_urls.py @@ -44,10 +44,11 @@ # Files to scan and the regex patterns that extract URL fragments from them # --------------------------------------------------------------------------- -# Matches values in the IddObjectDocUrl.hpp urlMap: +# Matches values in the IddObjectDocUrl.hpp urlMap and groupMap: # {"OS:Something", "group-foo.html#anchor"}, +# {"OpenStudio Group Name", "group-foo.html"}, IDDOBJECTDOCURL_PATTERN = re.compile( - r'"OS:[^"]+"\s*,\s*"([^"]+\.html(?:#[^"]*)?)"' + r'"(?:OS:|OpenStudio |Solar |Electric |Energy |User |Python |Airflow)[^"]*"\s*,\s*"([^"]+\.html(?:#[^"]*)?)"' ) # Matches QString URL constructions in .cpp files: diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 002fee04d..2c0aa3333 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -464,4 +464,40 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { return {}; } +// Returns the BigLadder EnergyPlus I/O Reference page URL for a given +// OpenStudio IDD group name (e.g. "OpenStudio Simulation"), or an empty string +// if the group has no known BigLadder page. Group names match \group +// declarations in OpenStudio.idd. Groups that span multiple EnergyPlus +// chapters (e.g. "OpenStudio HVAC") are omitted. +inline QString iddGroupDocUrl(const QString& groupName) { + static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); + + // clang-format off + static const QHash groupMap{ + {"OpenStudio Core", "group-simulation-parameters.html"}, + {"OpenStudio Simulation", "group-simulation-parameters.html"}, + {"OpenStudio Site", "group-location-climate-weather-file-access.html"}, + {"OpenStudio Materials", "group-surface-construction-elements.html"}, + {"OpenStudio Constructions", "group-surface-construction-elements.html"}, + {"OpenStudio Space Load Definitions", "group-internal-gains-people-lights-other.html"}, + {"OpenStudio Exterior Equipment Definitions", "group-exterior-energy-use-equipment.html"}, + {"OpenStudio Schedules", "group-schedules.html"}, + {"OpenStudio Geometry", "group-thermal-zone-description-geometry.html"}, + {"OpenStudio Space Loads", "group-internal-gains-people-lights-other.html"}, + {"OpenStudio Exterior Equipment", "group-exterior-energy-use-equipment.html"}, + {"OpenStudio Lighting Simulation", "group-daylighting.html"}, + {"OpenStudio Refrigeration", "group-refrigeration.html"}, + {"Solar Collectors", "group-solar-collectors.html"}, + {"Energy Management System (EMS)", "group-energy-management-system-ems.html"}, + {"User Defined HVAC and Plant Component Models", "group-user-defined-hvac-and-plant-component.html"}, + }; + // clang-format on + + auto it = groupMap.constFind(groupName); + if (it != groupMap.constEnd()) { + return base + it.value(); + } + return {}; +} + #endif // MODELEDITOR_IDDOBJECTDOCURL_HPP From 82421eb87270337c9a42f9c19519f469b129a0ac Mon Sep 17 00:00:00 2001 From: Mike Lovejoy <69771412+Ski90Moo@users.noreply.github.com> Date: Wed, 3 Jun 2026 08:13:47 +0200 Subject: [PATCH 14/18] Update src/model_editor/IddObjectDocUrl.hpp Co-authored-by: Dan Macumber --- src/model_editor/IddObjectDocUrl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 2c0aa3333..96cc44f45 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -497,6 +497,7 @@ inline QString iddGroupDocUrl(const QString& groupName) { if (it != groupMap.constEnd()) { return base + it.value(); } + qWarning() << "Cannot find doc url for: " + groupName; return {}; } From ec5050e162b49a4fd1cb90313e39eb5251ac35d9 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Wed, 3 Jun 2026 09:29:26 +0200 Subject: [PATCH 15/18] refactor: consolidate all hardcoded doc URLs into IddObjectDocUrl.hpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses macumber's review comment (#discussion_r3338463868). - Add 18 missing type→URL entries to IddObjectDocUrl.hpp (Construction variants, WindowMaterial variants, Schedule:File, GroundTemperature Shallow/Deep, RunPeriodControl:DaylightSavingTime, ConvergenceLimits, ZoneCapacitanceMultiplier:ResearchSpecial, Output types, LifeCycleCost types) - Replace all bigladdersoftwareDocBaseUrl() + hardcoded fragment patterns in 9 view files with iddObjectDocUrl() / iddGroupDocUrl() calls - Affected files: ConstructionsView, MaterialsView, LoadsView, ScheduleOthersView, SimSettingsView, GroundTemperatureView, LifeCycleCostsTabView, LocationTabView, YearSettingsWidget Co-Authored-By: Claude Sonnet 4.6 --- src/model_editor/IddObjectDocUrl.hpp | 22 +++++++++++ src/openstudio_lib/ConstructionsView.cpp | 17 ++++---- src/openstudio_lib/GroundTemperatureView.cpp | 14 +++---- src/openstudio_lib/LifeCycleCostsTabView.cpp | 8 ++-- src/openstudio_lib/LoadsView.cpp | 25 +++++------- src/openstudio_lib/LocationTabView.cpp | 7 ++-- src/openstudio_lib/MaterialsView.cpp | 34 ++++++++-------- src/openstudio_lib/ScheduleOthersView.cpp | 11 ++---- src/openstudio_lib/SimSettingsView.cpp | 41 +++++++++----------- src/openstudio_lib/YearSettingsWidget.cpp | 5 +-- 10 files changed, 93 insertions(+), 91 deletions(-) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 96cc44f45..dd7597411 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -31,16 +31,21 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:HeatBalanceAlgorithm", "group-simulation-parameters.html#heatbalancealgorithm"}, {"OS:ZoneAirHeatBalanceAlgorithm", "group-simulation-parameters.html#zoneairheatbalancealgorithm"}, {"OS:ZoneAirContaminantBalance", "group-simulation-parameters.html#zoneaircontaminantbalance"}, + {"OS:ConvergenceLimits", "group-simulation-parameters.html#convergencelimits"}, + {"OS:ZoneCapacitanceMultiplier:ResearchSpecial", "group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial"}, // Location and Climate {"OS:Site:Location", "group-location-climate-weather-file-access.html#sitelocation"}, {"OS:Site:GroundTemperature:Undisturbed:KusudaAchenbach", "group-location-climate-weather-file-access.html#sitegroundtemperatureundisturbedkusudaachenbach"}, {"OS:Site:GroundTemperature:BuildingSurface", "group-location-climate-weather-file-access.html#sitegroundtemperaturebuildingsurface"}, + {"OS:Site:GroundTemperature:Shallow", "group-location-climate-weather-file-access.html#sitegroundtemperatureshallow"}, + {"OS:Site:GroundTemperature:Deep", "group-location-climate-weather-file-access.html#sitegroundtemperaturedeep"}, {"OS:Site:GroundTemperature:FCfactorMethod", "group-location-climate-weather-file-access.html#sitegroundtemperaturefcfactormethod"}, {"OS:Site:GroundReflectance", "group-location-climate-weather-file-access.html#sitegroundreflectance"}, {"OS:Site:WaterMainsTemperature", "group-location-climate-weather-file-access.html#sitewatermainstemperature"}, {"OS:SizingPeriod:DesignDay", "group-location-climate-weather-file-access.html#sizingperioddesignday"}, {"OS:DesignDay", "group-location-climate-weather-file-access.html#sizingperioddesignday"}, + {"OS:RunPeriodControl:DaylightSavingTime", "group-location-climate-weather-file-access.html#runperiodcontroldaylightsavingtime"}, // Schedules {"OS:ScheduleTypeLimits", "group-schedules.html#scheduletypelimits"}, @@ -53,6 +58,7 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Schedule:Week:Compact", "group-schedules.html#scheduleweekcompact"}, {"OS:Schedule:Year", "group-schedules.html#scheduleyear"}, {"OS:Schedule:Ruleset", "group-schedules.html#scheduleyear"}, + {"OS:Schedule:File", "group-schedules.html#schedulefile"}, // Surface Construction Elements {"OS:Material", "group-surface-construction-elements.html#material"}, @@ -70,6 +76,11 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Construction", "group-surface-construction-elements.html#construction-000"}, {"OS:Construction:InternalSource", "group-surface-construction-elements.html#constructioninternalsource"}, {"OS:Construction:WindowDataFile", "group-surface-construction-elements.html#constructionwindowdatafile"}, + {"OS:Construction:AirBoundary", "group-surface-construction-elements.html#constructionairboundary"}, + {"OS:Construction:CfactorUndergroundWall", "group-surface-construction-elements.html#constructioncfactorundergroundwall"}, + {"OS:Construction:FfactorGroundFloor", "group-surface-construction-elements.html#constructionffactorgroundfloor"}, + {"OS:WindowMaterial:DaylightRedirectionDevice", "group-surface-construction-elements.html#windowmaterialblind"}, + {"OS:WindowMaterial:Glazing:RefractionExtinctionMethod", "group-surface-construction-elements.html#windowmaterialglazingrefractionextinctionmethod"}, {"OS:WindowProperty:FrameAndDivider", "group-thermal-zone-description-geometry.html#windowpropertyframeanddivider"}, // Thermal Zone Description and Geometry @@ -453,6 +464,17 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { {"OS:Table:IndependentVariable", "group-performance-tables.html#tableindependentvariable"}, {"OS:Table:IndependentVariableList", "group-performance-tables.html#tableindependentvariablelist"}, {"OS:Table:Lookup", "group-performance-tables.html#tablelookup"}, + + // Output + {"OS:Output:Diagnostics", "group-simulation-parameters.html#outputdiagnostics"}, + {"OS:OutputControl:ReportingTolerances", "input-for-output.html#outputcontrolreportingtolerances"}, + {"OS:Output:JSON", "input-for-output.html#outputjson"}, + {"OS:Output:Table:SummaryReports", "output-table-summaryreports.html#outputtablesummaryreports"}, + {"OS:OutputControl:ResilienceSummaries", "input-for-output.html#OutputControlResilienceSummaries"}, + + // Life Cycle Cost + {"OS:LifeCycleCost:Parameters", "lifecyclecost-parameters.html#lifecyclecostparameters"}, + {"OS:LifeCycleCost:UsePriceEscalation", "lifecyclecost-usepriceescalation.html#lifecyclecostusepriceescalation"}, }; // clang-format on diff --git a/src/openstudio_lib/ConstructionsView.cpp b/src/openstudio_lib/ConstructionsView.cpp index b0eeffd86..9327c42c5 100644 --- a/src/openstudio_lib/ConstructionsView.cpp +++ b/src/openstudio_lib/ConstructionsView.cpp @@ -12,7 +12,7 @@ #include "ConstructionInternalSourceInspectorView.hpp" #include "ConstructionWindowDataFileInspectorView.hpp" #include "ModelObjectTypeListView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include @@ -32,17 +32,16 @@ ConstructionsView::ConstructionsView(bool isIP, const openstudio::model::Model& } std::vector> ConstructionsView::modelObjectTypesNamesAndUrls() { - static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); - static const QString sce = base + QStringLiteral("group-surface-construction-elements.html"); - using T = std::tuple; return { - T{IddObjectType::OS_Construction, tr("Constructions"), sce + "#construction-000"}, - T{IddObjectType::OS_Construction_AirBoundary, tr("Air Boundary Constructions"), sce + "#constructionairboundary"}, - T{IddObjectType::OS_Construction_InternalSource, tr("Internal Source Constructions"), sce + "#constructioninternalsource"}, + T{IddObjectType::OS_Construction, tr("Constructions"), iddObjectDocUrl(QStringLiteral("OS:Construction"))}, + T{IddObjectType::OS_Construction_AirBoundary, tr("Air Boundary Constructions"), iddObjectDocUrl(QStringLiteral("OS:Construction:AirBoundary"))}, + T{IddObjectType::OS_Construction_InternalSource, tr("Internal Source Constructions"), + iddObjectDocUrl(QStringLiteral("OS:Construction:InternalSource"))}, T{IddObjectType::OS_Construction_CfactorUndergroundWall, tr("C-factor Underground Wall Constructions"), - sce + "#constructioncfactorundergroundwall"}, - T{IddObjectType::OS_Construction_FfactorGroundFloor, tr("F-factor Ground Floor Constructions"), sce + "#constructionffactorgroundfloor"}, + iddObjectDocUrl(QStringLiteral("OS:Construction:CfactorUndergroundWall"))}, + T{IddObjectType::OS_Construction_FfactorGroundFloor, tr("F-factor Ground Floor Constructions"), + iddObjectDocUrl(QStringLiteral("OS:Construction:FfactorGroundFloor"))}, // Not currently supported // T{IddObjectType::OS_Construction_WindowDataFile, tr("Window Data File Constructions"), {}}, }; diff --git a/src/openstudio_lib/GroundTemperatureView.cpp b/src/openstudio_lib/GroundTemperatureView.cpp index 5c75ea0c3..fe6db99b2 100644 --- a/src/openstudio_lib/GroundTemperatureView.cpp +++ b/src/openstudio_lib/GroundTemperatureView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "GroundTemperatureView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" @@ -100,13 +100,11 @@ GroundTemperatureListView::GroundTemperatureListView(QWidget* parent) : QWidget( layout->setSpacing(0); setLayout(layout); - static const QString lcwBase = - QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html"; - m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), lcwBase + "#sitegroundtemperaturebuildingsurface", this); - m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), lcwBase + "#sitegroundtemperatureshallow", this); - m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), lcwBase + "#sitegroundtemperaturedeep", this); - m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), lcwBase + "#sitegroundtemperaturefcfactormethod", this); - m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), lcwBase + "#sitewatermainstemperature", this); + m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:BuildingSurface")), this); + m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:Shallow")), this); + m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:Deep")), this); + m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:FCfactorMethod")), this); + m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), iddObjectDocUrl(QStringLiteral("OS:Site:WaterMainsTemperature")), this); connect(m_bsEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onBuildingSurfaceClicked); connect(m_shEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onShallowClicked); diff --git a/src/openstudio_lib/LifeCycleCostsTabView.cpp b/src/openstudio_lib/LifeCycleCostsTabView.cpp index 54f96cb36..355cf572d 100644 --- a/src/openstudio_lib/LifeCycleCostsTabView.cpp +++ b/src/openstudio_lib/LifeCycleCostsTabView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "LifeCycleCostsTabView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "../shared_gui_components/OSDoubleEdit.hpp" @@ -64,8 +64,7 @@ void LifeCycleCostsView::createWidgets() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = - QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "lifecyclecost-parameters.html#lifecyclecostparameters"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:LifeCycleCost:Parameters")); label->setToolTip(url); label->setText( QStringLiteral(R"(%2)").arg(url, tr("Life Cycle Cost Parameters"))); @@ -156,8 +155,7 @@ void LifeCycleCostsView::createWidgets() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = - QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "lifecyclecost-usepriceescalation.html#lifecyclecostusepriceescalation"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:LifeCycleCost:UsePriceEscalation")); label->setToolTip(url); label->setText(QStringLiteral(R"(%2)") .arg(url, tr("Use National Institute of Standards and Technology (NIST) Fuel Escalation Rates"))); diff --git a/src/openstudio_lib/LoadsView.cpp b/src/openstudio_lib/LoadsView.cpp index 2f43b7cfa..b1d12b0ac 100644 --- a/src/openstudio_lib/LoadsView.cpp +++ b/src/openstudio_lib/LoadsView.cpp @@ -5,7 +5,7 @@ #include "LoadsView.hpp" #include "ModelObjectTypeListView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "PeopleInspectorView.hpp" #include "InternalMassInspectorView.hpp" #include "LightsInspectorView.hpp" @@ -44,23 +44,18 @@ LoadsView::LoadsView(bool isIP, const openstudio::model::Model& model, QWidget* } std::vector> LoadsView::modelObjectTypesNamesAndUrls() { - static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); - static const QString iag = base + QStringLiteral("group-internal-gains-people-lights-other.html"); - static const QString tzg = base + QStringLiteral("group-thermal-zone-description-geometry.html"); - static const QString wsg = base + QStringLiteral("group-water-systems.html"); - using T = std::tuple; return { - T{IddObjectType::OS_People_Definition, tr("People Definitions"), iag + "#people"}, - T{IddObjectType::OS_Lights_Definition, tr("Lights Definitions"), iag + "#lights-000"}, + T{IddObjectType::OS_People_Definition, tr("People Definitions"), iddObjectDocUrl(QStringLiteral("OS:People"))}, + T{IddObjectType::OS_Lights_Definition, tr("Lights Definitions"), iddObjectDocUrl(QStringLiteral("OS:Lights"))}, T{IddObjectType::OS_Luminaire_Definition, tr("Luminaire Definitions"), {}}, - T{IddObjectType::OS_ElectricEquipment_Definition, tr("Electric Equipment Definitions"), iag + "#electricequipment"}, - T{IddObjectType::OS_GasEquipment_Definition, tr("Gas Equipment Definitions"), iag + "#gasequipment"}, - T{IddObjectType::OS_SteamEquipment_Definition, tr("Steam Equipment Definitions"), iag + "#steamequipment"}, - T{IddObjectType::OS_OtherEquipment_Definition, tr("Other Equipment Definitions"), iag + "#otherequipment"}, - T{IddObjectType::OS_InternalMass_Definition, tr("Internal Mass Definitions"), tzg + "#internalmass"}, - T{IddObjectType::OS_WaterUse_Equipment_Definition, tr("Water Use Equipment Definitions"), wsg + "#wateruseequipment"}, - T{IddObjectType::OS_HotWaterEquipment_Definition, tr("Hot Water Equipment Definitions"), iag + "#hotwaterequipment"}, + T{IddObjectType::OS_ElectricEquipment_Definition, tr("Electric Equipment Definitions"), iddObjectDocUrl(QStringLiteral("OS:ElectricEquipment"))}, + T{IddObjectType::OS_GasEquipment_Definition, tr("Gas Equipment Definitions"), iddObjectDocUrl(QStringLiteral("OS:GasEquipment"))}, + T{IddObjectType::OS_SteamEquipment_Definition, tr("Steam Equipment Definitions"), iddObjectDocUrl(QStringLiteral("OS:SteamEquipment"))}, + T{IddObjectType::OS_OtherEquipment_Definition, tr("Other Equipment Definitions"), iddObjectDocUrl(QStringLiteral("OS:OtherEquipment"))}, + T{IddObjectType::OS_InternalMass_Definition, tr("Internal Mass Definitions"), iddObjectDocUrl(QStringLiteral("OS:InternalMass"))}, + T{IddObjectType::OS_WaterUse_Equipment_Definition, tr("Water Use Equipment Definitions"), iddObjectDocUrl(QStringLiteral("OS:WaterUse:Equipment"))}, + T{IddObjectType::OS_HotWaterEquipment_Definition, tr("Hot Water Equipment Definitions"), iddObjectDocUrl(QStringLiteral("OS:HotWaterEquipment"))}, }; } diff --git a/src/openstudio_lib/LocationTabView.cpp b/src/openstudio_lib/LocationTabView.cpp index 542cdd8b7..79a97c2c0 100644 --- a/src/openstudio_lib/LocationTabView.cpp +++ b/src/openstudio_lib/LocationTabView.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "LocationTabView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "DesignDayGridView.hpp" #include "ModelObjectListView.hpp" @@ -215,7 +215,7 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html"; + static const QString url = iddGroupDocUrl(QStringLiteral("OpenStudio Site")); label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Weather File"))); } @@ -469,8 +469,7 @@ LocationView::LocationView(bool isIP, const model::Model& model, const QString& label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = - QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html#sizingperioddesignday"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:SizingPeriod:DesignDay")); label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Design Days"))); } diff --git a/src/openstudio_lib/MaterialsView.cpp b/src/openstudio_lib/MaterialsView.cpp index d69f41f6e..69e0fe8ee 100644 --- a/src/openstudio_lib/MaterialsView.cpp +++ b/src/openstudio_lib/MaterialsView.cpp @@ -11,7 +11,7 @@ #include "MaterialNoMassInspectorView.hpp" #include "MaterialRoofVegetationInspectorView.hpp" #include "ModelObjectTypeListView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "WindowMaterialBlindInspectorView.hpp" #include "WindowMaterialDaylightRedirectionDeviceInspectorView.hpp" #include "WindowMaterialGasInspectorView.hpp" @@ -44,29 +44,27 @@ MaterialsView::MaterialsView(bool isIP, const openstudio::model::Model& model, c } std::vector> MaterialsView::modelObjectTypesNamesAndUrls() { - static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); - static const QString sce = base + QStringLiteral("group-surface-construction-elements.html"); - using T = std::tuple; return { - T{IddObjectType::OS_Material, tr("Materials"), sce + "#material"}, - T{IddObjectType::OS_Material_NoMass, tr("No Mass Materials"), sce + "#materialnomass"}, - T{IddObjectType::OS_Material_AirGap, tr("Air Gap Materials"), sce + "#materialairgap"}, + T{IddObjectType::OS_Material, tr("Materials"), iddObjectDocUrl(QStringLiteral("OS:Material"))}, + T{IddObjectType::OS_Material_NoMass, tr("No Mass Materials"), iddObjectDocUrl(QStringLiteral("OS:Material:NoMass"))}, + T{IddObjectType::OS_Material_AirGap, tr("Air Gap Materials"), iddObjectDocUrl(QStringLiteral("OS:Material:AirGap"))}, T{IddObjectType::OS_WindowMaterial_SimpleGlazingSystem, tr("Simple Glazing System Window Materials"), - sce + "#windowmaterialsimpleglazingsystem"}, - T{IddObjectType::OS_WindowMaterial_Glazing, tr("Glazing Window Materials"), sce + "#windowmaterialglazing"}, - T{IddObjectType::OS_WindowMaterial_Gas, tr("Gas Window Materials"), sce + "#windowmaterialgas"}, - T{IddObjectType::OS_WindowMaterial_GasMixture, tr("Gas Mixture Window Materials"), sce + "#windowmaterialgasmixture"}, - T{IddObjectType::OS_WindowMaterial_Blind, tr("Blind Window Materials"), sce + "#windowmaterialblind"}, + iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:SimpleGlazingSystem"))}, + T{IddObjectType::OS_WindowMaterial_Glazing, tr("Glazing Window Materials"), iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:Glazing"))}, + T{IddObjectType::OS_WindowMaterial_Gas, tr("Gas Window Materials"), iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:Gas"))}, + T{IddObjectType::OS_WindowMaterial_GasMixture, tr("Gas Mixture Window Materials"), iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:GasMixture"))}, + T{IddObjectType::OS_WindowMaterial_Blind, tr("Blind Window Materials"), iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:Blind"))}, T{IddObjectType::OS_WindowMaterial_DaylightRedirectionDevice, tr("Daylight Redirection Device Window Materials"), - sce + "#windowmaterialblind"}, - T{IddObjectType::OS_WindowMaterial_Screen, tr("Screen Window Materials"), sce + "#windowmaterialscreen"}, - T{IddObjectType::OS_WindowMaterial_Shade, tr("Shade Window Materials"), sce + "#windowmaterialshade"}, + iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:DaylightRedirectionDevice"))}, + T{IddObjectType::OS_WindowMaterial_Screen, tr("Screen Window Materials"), iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:Screen"))}, + T{IddObjectType::OS_WindowMaterial_Shade, tr("Shade Window Materials"), iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:Shade"))}, // Oddballs at the bottom - T{IddObjectType::OS_Material_InfraredTransparent, tr("Infrared Transparent Materials"), sce + "#materialinfraredtransparent"}, - T{IddObjectType::OS_Material_RoofVegetation, tr("Roof Vegetation Materials"), sce + "#materialroofvegetation"}, + T{IddObjectType::OS_Material_InfraredTransparent, tr("Infrared Transparent Materials"), + iddObjectDocUrl(QStringLiteral("OS:Material:InfraredTransparent"))}, + T{IddObjectType::OS_Material_RoofVegetation, tr("Roof Vegetation Materials"), iddObjectDocUrl(QStringLiteral("OS:Material:RoofVegetation"))}, T{IddObjectType::OS_WindowMaterial_Glazing_RefractionExtinctionMethod, tr("Refraction Extinction Method Glazing Window Materials"), - sce + "#windowmaterialglazingrefractionextinctionmethod"}, + iddObjectDocUrl(QStringLiteral("OS:WindowMaterial:Glazing:RefractionExtinctionMethod"))}, // TODO: commented out until ThermochromicGlazing is properly wrapped // T{IddObjectType::OS_WindowMaterial_GlazingGroup_Thermochromic, tr("Glazing Group Thermochromic Window Materials"), sce + "#windowmaterialglazinggroupthermochromic"}, }; diff --git a/src/openstudio_lib/ScheduleOthersView.cpp b/src/openstudio_lib/ScheduleOthersView.cpp index 1038e4c85..46eeb247a 100644 --- a/src/openstudio_lib/ScheduleOthersView.cpp +++ b/src/openstudio_lib/ScheduleOthersView.cpp @@ -5,7 +5,7 @@ #include "ScheduleOthersView.hpp" #include "ModelObjectTypeListView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "ScheduleConstantInspectorView.hpp" #include "ScheduleCompactInspectorView.hpp" @@ -28,14 +28,11 @@ ScheduleOthersView::ScheduleOthersView(const openstudio::model::Model& model, QW new ScheduleOthersInspectorView(model, parent), false, parent) {} std::vector> ScheduleOthersView::modelObjectTypesNamesAndUrls() { - static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); - static const QString sch = base + QStringLiteral("group-schedules.html"); - using T = std::tuple; return { - T{IddObjectType::OS_Schedule_Constant, tr("Schedule Constant"), sch + "#scheduleconstant"}, - T{IddObjectType::OS_Schedule_Compact, tr("Schedule Compact"), sch + "#schedulecompact"}, - T{IddObjectType::OS_Schedule_File, tr("Schedule File"), sch + "#schedulefile"}, + T{IddObjectType::OS_Schedule_Constant, tr("Schedule Constant"), iddObjectDocUrl(QStringLiteral("OS:Schedule:Constant"))}, + T{IddObjectType::OS_Schedule_Compact, tr("Schedule Compact"), iddObjectDocUrl(QStringLiteral("OS:Schedule:Compact"))}, + T{IddObjectType::OS_Schedule_File, tr("Schedule File"), iddObjectDocUrl(QStringLiteral("OS:Schedule:File"))}, }; } diff --git a/src/openstudio_lib/SimSettingsView.cpp b/src/openstudio_lib/SimSettingsView.cpp index b667aed3a..94c192764 100644 --- a/src/openstudio_lib/SimSettingsView.cpp +++ b/src/openstudio_lib/SimSettingsView.cpp @@ -7,7 +7,7 @@ #include "CollapsibleInspector.hpp" #include "ModelObjectTypeListView.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "OSAppBase.hpp" #include "../shared_gui_components/OSComboBox.hpp" #include "OSDocument.hpp" @@ -240,10 +240,8 @@ void SimSettingsView::createWidgets() { //******************* OS:Timestep ******************* mainLayout->addWidget(createTimestepWidget()); - static const QString iorf = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); - collapsibleInspector = new CollapsibleInspector( - tr("Advanced RunPeriod Parameters"), iorf + "group-location-climate-weather-file-access.html#runperiod", createRunPeriodAdvancedWidget()); + tr("Advanced RunPeriod Parameters"), iddObjectDocUrl(QStringLiteral("OS:RunPeriod")), createRunPeriodAdvancedWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:RadianceParameters ******************* @@ -252,7 +250,7 @@ void SimSettingsView::createWidgets() { //******************* OS:SimulationControl ******************* collapsibleInspector = - new CollapsibleInspector(tr("Simulation Control"), iorf + "group-simulation-parameters.html#simulationcontrol", createSimulationControlWidget()); + new CollapsibleInspector(tr("Simulation Control"), iddObjectDocUrl(QStringLiteral("OS:SimulationControl")), createSimulationControlWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ProgramControl ******************* @@ -261,71 +259,71 @@ void SimSettingsView::createWidgets() { //******************* OS:OutputControl:ReportingTolerances ******************* collapsibleInspector = - new CollapsibleInspector(tr("Output Control Reporting Tolerances"), iorf + "input-for-output.html#outputcontrolreportingtolerances", + new CollapsibleInspector(tr("Output Control Reporting Tolerances"), iddObjectDocUrl(QStringLiteral("OS:OutputControl:ReportingTolerances")), createOutputControlReportingTolerancesWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ConvergenceLimits ******************* collapsibleInspector = - new CollapsibleInspector(tr("Convergence Limits"), iorf + "group-simulation-parameters.html#convergencelimits", createConvergenceLimitsWidget()); + new CollapsibleInspector(tr("Convergence Limits"), iddObjectDocUrl(QStringLiteral("OS:ConvergenceLimits")), createConvergenceLimitsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ShadowCalculation ******************* collapsibleInspector = - new CollapsibleInspector(tr("Shadow Calculation"), iorf + "group-simulation-parameters.html#shadowcalculation", createShadowCalculationWidget()); + new CollapsibleInspector(tr("Shadow Calculation"), iddObjectDocUrl(QStringLiteral("OS:ShadowCalculation")), createShadowCalculationWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:SurfaceConvectionAlgorithm:Inside ******************* collapsibleInspector = - new CollapsibleInspector(tr("Inside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithminside", + new CollapsibleInspector(tr("Inside Surface Convection Algorithm"), iddObjectDocUrl(QStringLiteral("OS:SurfaceConvectionAlgorithm:Inside")), createSurfaceConvectionAlgorithmInsideWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:SurfaceConvectionAlgorithm:Outside ******************* collapsibleInspector = - new CollapsibleInspector(tr("Outside Surface Convection Algorithm"), iorf + "group-simulation-parameters.html#surfaceconvectionalgorithmoutside", + new CollapsibleInspector(tr("Outside Surface Convection Algorithm"), iddObjectDocUrl(QStringLiteral("OS:SurfaceConvectionAlgorithm:Outside")), createSurfaceConvectionAlgorithmOutsideWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:HeatBalanceAlgorithm ******************* - collapsibleInspector = new CollapsibleInspector(tr("Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#heatbalancealgorithm", + collapsibleInspector = new CollapsibleInspector(tr("Heat Balance Algorithm"), iddObjectDocUrl(QStringLiteral("OS:HeatBalanceAlgorithm")), createHeatBalanceAlgorithmWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirHeatBalanceAlgorithm ******************* collapsibleInspector = - new CollapsibleInspector(tr("Zone Air Heat Balance Algorithm"), iorf + "group-simulation-parameters.html#zoneairheatbalancealgorithm", + new CollapsibleInspector(tr("Zone Air Heat Balance Algorithm"), iddObjectDocUrl(QStringLiteral("OS:ZoneAirHeatBalanceAlgorithm")), createZoneAirHeatBalanceAlgorithmWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirContaminantBalance ******************* collapsibleInspector = new CollapsibleInspector( - tr("Zone Air Contaminant Balance"), iorf + "group-simulation-parameters.html#zoneaircontaminantbalance", createZoneAirContaminantBalanceWidget()); + tr("Zone Air Contaminant Balance"), iddObjectDocUrl(QStringLiteral("OS:ZoneAirContaminantBalance")), createZoneAirContaminantBalanceWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneCapacitanceMultiplier:ResearchSpecial ******************* collapsibleInspector = new CollapsibleInspector(tr("Zone Capacitance Multiple Research Special"), - iorf + "group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial", + iddObjectDocUrl(QStringLiteral("OS:ZoneCapacitanceMultiplier:ResearchSpecial")), createZoneCapacitanceMultipleResearchSpecialWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:JSON ******************* - collapsibleInspector = new CollapsibleInspector(tr("Output JSON"), iorf + "input-for-output.html#outputjson", createOutputJSONWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Output JSON"), iddObjectDocUrl(QStringLiteral("OS:Output:JSON")), createOutputJSONWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:Table:SummaryReports ******************* collapsibleInspector = new CollapsibleInspector( - tr("Output Table Summary Reports"), iorf + "output-table-summaryreports.html#outputtablesummaryreports", createOutputTableSummaryReportsWidget()); + tr("Output Table Summary Reports"), iddObjectDocUrl(QStringLiteral("OS:Output:Table:SummaryReports")), createOutputTableSummaryReportsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:Output:Diagnostics ******************* collapsibleInspector = - new CollapsibleInspector(tr("Output Diagnostics"), iorf + "group-simulation-parameters.html#outputdiagnostics", createOutputDiagnosticsWidget()); + new CollapsibleInspector(tr("Output Diagnostics"), iddObjectDocUrl(QStringLiteral("OS:Output:Diagnostics")), createOutputDiagnosticsWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:OutputControl:ResilienceSummaries ******************* collapsibleInspector = - new CollapsibleInspector(tr("Output Control Resilience Summaries"), iorf + "input-for-output.html#OutputControlResilienceSummaries", + new CollapsibleInspector(tr("Output Control Resilience Summaries"), iddObjectDocUrl(QStringLiteral("OS:OutputControl:ResilienceSummaries")), createOutputControlResilienceSummariesWidget()); mainLayout->addWidget(collapsibleInspector); @@ -352,8 +350,7 @@ QWidget* SimSettingsView::createRunPeriodWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = - QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-location-climate-weather-file-access.html#runperiod"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:RunPeriod")); label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Run Period"))); } @@ -637,7 +634,7 @@ QWidget* SimSettingsView::createSizingParametersWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-design-objects.html#sizingparameters"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:Sizing:Parameters")); label->setToolTip(url); label->setText( QStringLiteral(R"(%2)").arg(url, tr("Sizing Parameters"))); @@ -695,7 +692,7 @@ QWidget* SimSettingsView::createTimestepWidget() { label->setTextFormat(Qt::RichText); label->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "group-simulation-parameters.html#timestep"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:Timestep")); label->setToolTip(url); label->setText(QStringLiteral(R"(%2)").arg(url, tr("Timestep"))); } diff --git a/src/openstudio_lib/YearSettingsWidget.cpp b/src/openstudio_lib/YearSettingsWidget.cpp index 10d52631c..469aa35e6 100644 --- a/src/openstudio_lib/YearSettingsWidget.cpp +++ b/src/openstudio_lib/YearSettingsWidget.cpp @@ -4,7 +4,7 @@ ***********************************************************************************************************************/ #include "YearSettingsWidget.hpp" -#include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include "../model_editor/IddObjectDocUrl.hpp" #include "OSAppBase.hpp" #include "OSDocument.hpp" @@ -108,8 +108,7 @@ YearSettingsWidget::YearSettingsWidget(const model::Model& model, QWidget* paren dstLabel->setTextFormat(Qt::RichText); dstLabel->setOpenExternalLinks(true); { - static const QString url = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) - + "group-location-climate-weather-file-access.html#field-daylight-saving-time-indicator"; + static const QString url = iddObjectDocUrl(QStringLiteral("OS:RunPeriodControl:DaylightSavingTime")); dstLabel->setToolTip(url); dstLabel->setText(QStringLiteral(R"(%2)").arg(url, tr("Daylight Savings Time:"))); } From bec4e6b2290f67b8650a0c32ebfd7cbb971b0c9f Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Mon, 8 Jun 2026 16:50:12 +0200 Subject: [PATCH 16/18] style: apply clang-format 18.1.3 to fix CI formatting check --- src/openstudio_lib/GroundTemperatureView.cpp | 12 ++++++++---- src/openstudio_lib/SimSettingsView.cpp | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/openstudio_lib/GroundTemperatureView.cpp b/src/openstudio_lib/GroundTemperatureView.cpp index fe6db99b2..7207d2de5 100644 --- a/src/openstudio_lib/GroundTemperatureView.cpp +++ b/src/openstudio_lib/GroundTemperatureView.cpp @@ -100,11 +100,15 @@ GroundTemperatureListView::GroundTemperatureListView(QWidget* parent) : QWidget( layout->setSpacing(0); setLayout(layout); - m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:BuildingSurface")), this); - m_shEntry = new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:Shallow")), this); + m_bsEntry = new GroundTemperatureEntry(tr("Building Surface Ground Temperatures"), + iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:BuildingSurface")), this); + m_shEntry = + new GroundTemperatureEntry(tr("Shallow Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:Shallow")), this); m_deepEntry = new GroundTemperatureEntry(tr("Deep Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:Deep")), this); - m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:FCfactorMethod")), this); - m_waterMainsEntry = new GroundTemperatureEntry(tr("Water Mains Temperature"), iddObjectDocUrl(QStringLiteral("OS:Site:WaterMainsTemperature")), this); + m_fcEntry = new GroundTemperatureEntry(tr("FCfactorMethod Ground Temperatures"), + iddObjectDocUrl(QStringLiteral("OS:Site:GroundTemperature:FCfactorMethod")), this); + m_waterMainsEntry = + new GroundTemperatureEntry(tr("Water Mains Temperature"), iddObjectDocUrl(QStringLiteral("OS:Site:WaterMainsTemperature")), this); connect(m_bsEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onBuildingSurfaceClicked); connect(m_shEntry, &GroundTemperatureEntry::clicked, this, &GroundTemperatureListView::onShallowClicked); diff --git a/src/openstudio_lib/SimSettingsView.cpp b/src/openstudio_lib/SimSettingsView.cpp index 94c192764..b5d1ea5bc 100644 --- a/src/openstudio_lib/SimSettingsView.cpp +++ b/src/openstudio_lib/SimSettingsView.cpp @@ -240,8 +240,8 @@ void SimSettingsView::createWidgets() { //******************* OS:Timestep ******************* mainLayout->addWidget(createTimestepWidget()); - collapsibleInspector = new CollapsibleInspector( - tr("Advanced RunPeriod Parameters"), iddObjectDocUrl(QStringLiteral("OS:RunPeriod")), createRunPeriodAdvancedWidget()); + collapsibleInspector = + new CollapsibleInspector(tr("Advanced RunPeriod Parameters"), iddObjectDocUrl(QStringLiteral("OS:RunPeriod")), createRunPeriodAdvancedWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:RadianceParameters ******************* @@ -297,8 +297,8 @@ void SimSettingsView::createWidgets() { mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneAirContaminantBalance ******************* - collapsibleInspector = new CollapsibleInspector( - tr("Zone Air Contaminant Balance"), iddObjectDocUrl(QStringLiteral("OS:ZoneAirContaminantBalance")), createZoneAirContaminantBalanceWidget()); + collapsibleInspector = new CollapsibleInspector(tr("Zone Air Contaminant Balance"), iddObjectDocUrl(QStringLiteral("OS:ZoneAirContaminantBalance")), + createZoneAirContaminantBalanceWidget()); mainLayout->addWidget(collapsibleInspector); //******************* OS:ZoneCapacitanceMultiplier:ResearchSpecial ******************* From 6b0a468529a505e3b7346b83e94c9b421af509df Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Thu, 11 Jun 2026 21:24:32 +0200 Subject: [PATCH 17/18] fix: derive BigLadder doc URL from SDK's EnergyPlus version ENERGYPLUS_VERSION_MAJOR/MINOR in FindOpenStudioSDK.cmake had drifted to 25-1 while the bundled OpenStudio 3.11.0 SDK ships EnergyPlus 25.2, producing doc links for the wrong EnergyPlus version. Instead of a second manually-maintained version constant, build the BigLadder base URL from energyPlusVersionMajor()/energyPlusVersionMinor() in the SDK's OpenStudio.hxx, which is already the source of truth and updates automatically whenever the SDK is bumped. check_doc_urls.py now auto-detects the same version from OpenStudio.hxx instead of a hardcoded 25-1 base URL. Co-Authored-By: Claude Sonnet 4.6 --- FindOpenStudioSDK.cmake | 4 -- scripts/check_doc_urls.py | 72 +++++++++++++++++-- src/model_editor/IddObjectDocUrl.hpp | 3 +- .../OpenStudioApplicationPathHelpers.cxx.in | 3 +- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/FindOpenStudioSDK.cmake b/FindOpenStudioSDK.cmake index 9712cc5ae..a838253a9 100644 --- a/FindOpenStudioSDK.cmake +++ b/FindOpenStudioSDK.cmake @@ -8,10 +8,6 @@ set(OPENSTUDIO_VERSION_PRERELEASE "") # Enter SHA, always, eg "+79857912c4" set(OPENSTUDIO_VERSION_SHA "+241b8abb4d") -set(ENERGYPLUS_VERSION_MAJOR 25) -set(ENERGYPLUS_VERSION_MINOR 1) -set(BIGLADDERSOFTWARE_DOC_BASE_URL "https://bigladdersoftware.com/epx/docs/${ENERGYPLUS_VERSION_MAJOR}-${ENERGYPLUS_VERSION_MINOR}/input-output-reference/") - # Paths where the cmake-downloaded archives will be put set(OPENSTUDIO_ARCHIVE_DIR "${PROJECT_BINARY_DIR}/OpenStudio-${OPENSTUDIO_VERSION}") diff --git a/scripts/check_doc_urls.py b/scripts/check_doc_urls.py index 959bc766b..3ca2b4f14 100644 --- a/scripts/check_doc_urls.py +++ b/scripts/check_doc_urls.py @@ -6,7 +6,14 @@ every anchor referenced actually exists in the page HTML, and reports failures. Usage: - python scripts/check_doc_urls.py [--repo-root PATH] [--delay SEC] + python scripts/check_doc_urls.py [--repo-root PATH] [--delay SEC] [--openstudio-hxx PATH] + +The BigLadder doc version (eg "25-2") is auto-detected from the OpenStudio SDK's +OpenStudio.hxx (energyPlusVersionMajor()/energyPlusVersionMinor()), the same values +openstudio::bigladdersoftwareDocBaseUrl() uses at runtime. The SDK is located by +searching for OpenStudio-*/*/include/openstudio/OpenStudio.hxx under --repo-root +(covers both in-source and build/ out-of-source SDK downloads), or pass +--openstudio-hxx to point at it directly. Exit codes: 0 All URLs valid @@ -75,7 +82,16 @@ "src/openstudio_lib/BuildingInspectorView.cpp", ] -BIGLADDERSOFTWARE_BASE = "https://bigladdersoftware.com/epx/docs/25-1/input-output-reference/" +# Where to look for the downloaded OpenStudio SDK's OpenStudio.hxx, relative to repo root. +SDK_HXX_GLOBS = [ + "OpenStudio-*/*/include/openstudio/OpenStudio.hxx", + "build*/OpenStudio-*/*/include/openstudio/OpenStudio.hxx", +] + +ENERGYPLUS_VERSION_RE = { + "major": re.compile(r"energyPlusVersionMajor\(\)\s*\{\s*return\s*(\d+);"), + "minor": re.compile(r"energyPlusVersionMinor\(\)\s*\{\s*return\s*(\d+);"), +} # --------------------------------------------------------------------------- @@ -93,11 +109,40 @@ def handle_starttag(self, tag, attrs): self.ids.add(value) +# --------------------------------------------------------------------------- +# EnergyPlus version detection (mirrors openstudio::bigladdersoftwareDocBaseUrl()) +# --------------------------------------------------------------------------- + +def find_openstudio_hxx(repo_root: Path) -> Path | None: + for pattern in SDK_HXX_GLOBS: + matches = sorted(repo_root.glob(pattern)) + if matches: + return matches[0] + return None + + +def detect_bigladdersoftware_base(hxx_path: Path) -> str: + """ + Parse energyPlusVersionMajor()/energyPlusVersionMinor() from the SDK's + OpenStudio.hxx and build the BigLadder I/O Reference base URL the same way + openstudio::bigladdersoftwareDocBaseUrl() does at runtime. + """ + text = hxx_path.read_text(encoding="utf-8") + versions = {} + for part, pattern in ENERGYPLUS_VERSION_RE.items(): + m = pattern.search(text) + if not m: + raise ValueError(f"Could not find energyPlusVersion{part.capitalize()}() in {hxx_path}") + versions[part] = m.group(1) + + return f"https://bigladdersoftware.com/epx/docs/{versions['major']}-{versions['minor']}/input-output-reference/" + + # --------------------------------------------------------------------------- # URL extraction # --------------------------------------------------------------------------- -def extract_fragments(repo_root: Path): +def extract_fragments(repo_root: Path, base_url: str): """ Returns a dict: page_url -> list of (anchor_or_None, source_file, line_no) """ @@ -125,7 +170,7 @@ def extract_fragments(repo_root: Path): page_part, anchor = fragment.split("#", 1) else: page_part, anchor = fragment, None - page_url = BIGLADDERSOFTWARE_BASE + page_part + page_url = base_url + page_part results[page_url].append((anchor, rel_path, lineno)) return results @@ -166,12 +211,29 @@ def main(): default=0.5, help="Seconds to wait between page fetches (default: 0.5)", ) + parser.add_argument( + "--openstudio-hxx", + help="Path to the OpenStudio SDK's OpenStudio.hxx (default: auto-detect under --repo-root)", + ) args = parser.parse_args() repo_root = Path(args.repo_root).resolve() print(f"Scanning repo: {repo_root}") - fragments = extract_fragments(repo_root) + hxx_path = Path(args.openstudio_hxx).resolve() if args.openstudio_hxx else find_openstudio_hxx(repo_root) + if hxx_path is None or not hxx_path.exists(): + print( + "ERROR: Could not find the OpenStudio SDK's OpenStudio.hxx " + f"(looked for {SDK_HXX_GLOBS} under {repo_root}).\n" + "Build/configure the project first, or pass --openstudio-hxx explicitly.", + file=sys.stderr, + ) + sys.exit(2) + + base_url = detect_bigladdersoftware_base(hxx_path) + print(f"Using EnergyPlus doc base URL: {base_url}\n (from {hxx_path})") + + fragments = extract_fragments(repo_root, base_url) if not fragments: print("No URLs found — check SOURCE_FILES list.", file=sys.stderr) sys.exit(2) diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index dd7597411..5a98196a3 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -14,7 +14,8 @@ // Returns the BigLadder EnergyPlus I/O Reference URL for the given OS IDD type name // (e.g. "OS:ThermalZone"), or an empty string if none is known. -// Base URL version is controlled by ENERGYPLUS_VERSION_MAJOR/MINOR in FindOpenStudioSDK.cmake. +// Base URL version matches the EnergyPlus version bundled with the OpenStudio SDK +// (see openstudio::bigladdersoftwareDocBaseUrl()). inline QString iddObjectDocUrl(const QString& iddTypeName) { static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); diff --git a/src/utilities/OpenStudioApplicationPathHelpers.cxx.in b/src/utilities/OpenStudioApplicationPathHelpers.cxx.in index b4631ea6d..e798591af 100644 --- a/src/utilities/OpenStudioApplicationPathHelpers.cxx.in +++ b/src/utilities/OpenStudioApplicationPathHelpers.cxx.in @@ -206,7 +206,8 @@ bool isOpenStudioApplicationModuleRunningFromBuildDirectory() { } std::string bigladdersoftwareDocBaseUrl() { - return "${BIGLADDERSOFTWARE_DOC_BASE_URL}"; + return "https://bigladdersoftware.com/epx/docs/" + std::to_string(energyPlusVersionMajor()) + "-" + std::to_string(energyPlusVersionMinor()) + + "/input-output-reference/"; } openstudio::path getOpenStudioCoreCLI() { From 2e6d7f147ab519b02a9192ff9b529511e435b314 Mon Sep 17 00:00:00 2001 From: Ski90Moo Date: Wed, 24 Jun 2026 21:01:15 +0200 Subject: [PATCH 18/18] feat: point doc links at a locally-bundled EnergyPlus docs export Stopgap per macumber's PR 876 request to stop depending on a live third-party site for the I/O Reference docs: download jmarrec's pre-built HTML export from Google Drive at configure time, install it alongside the app, and remap all existing doc URLs to point at it. - FindEnergyPlusDocs.cmake downloads, MD5-verifies, and extracts the export, mirroring FindOpenStudioSDK.cmake's pattern. - bigladdersoftwareDocBaseUrl() replaced with energyPlusDocDirectory(), resolving build-tree vs. installed locations like resourcesPath(). - IddObjectDocUrl.hpp's 393 urlMap/groupMap entries remapped across 47 distinct pages to the export's actual filenames, with every anchor verified to resolve against the export's HTML. 6 pages needed manual correction beyond simple prefix-stripping, including two genuine content-relocation cases (AirTerminal:* objects and the Output:JSON/ ReportingTolerances/ResilienceSummaries group) caught only because every anchor was checked against real id= attributes rather than trusting the filename match. - check_doc_urls.py now validates the local files instead of fetching bigladdersoftware.com. Verified via an actual cmake configure + build of the affected targets (openstudioapp_utilities, openstudio_modeleditor, openstudio_lib) plus the full OpenStudioApp executable, and a live run confirming doc-link tooltips open the local HTML at the right anchor. The reproducible build pipeline behind the export is still pending from jmarrec; this Drive download is an interim measure. --- .gitignore | 4 + CMakeLists.txt | 5 + FindEnergyPlusDocs.cmake | 113 +++ scripts/check_doc_urls.py | 185 ++-- src/model_editor/IddObjectDocUrl.hpp | 803 +++++++++--------- .../OpenStudioApplicationPathHelpers.cxx.in | 9 +- .../OpenStudioApplicationPathHelpers.hpp | 4 +- 7 files changed, 586 insertions(+), 537 deletions(-) create mode 100644 FindEnergyPlusDocs.cmake diff --git a/.gitignore b/.gitignore index b0d7e27d8..d533750d5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ relwithdebinfo/ profile/ /super-build-shared/ /super-build-static/ +/Products/ *.sublime-workspace @@ -45,3 +46,6 @@ clang_format.patch conan-cache .ccache CMakeUserPresets.json + +# Local working notes, not for commit +ENERGYPLUS_DOCS_WORKFLOW.md diff --git a/CMakeLists.txt b/CMakeLists.txt index a1b31df89..c0396f390 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,10 @@ endif() # Or it'll download a zip/tar.gz for you include(FindOpenStudioSDK.cmake) +# Downloads a local copy of the EnergyPlus Input Output Reference HTML documentation, +# so doc links in the app can point at it instead of a live website. +include(FindEnergyPlusDocs.cmake) + ############################################################################### # C O N A N # ############################################################################### @@ -786,6 +790,7 @@ endif() install(DIRECTORY "${openstudio_ROOT_DIR}/Radiance" DESTINATION "." COMPONENT "OpenStudioApp" USE_SOURCE_PERMISSIONS) install(DIRECTORY "${openstudio_ROOT_DIR}/Ruby" DESTINATION "." COMPONENT "OpenStudioApp" USE_SOURCE_PERMISSIONS) install(DIRECTORY "${openstudio_ROOT_DIR}/EnergyPlus" DESTINATION "." COMPONENT "OpenStudioApp" USE_SOURCE_PERMISSIONS) +install(DIRECTORY "${ENERGYPLUS_DOCS_DIR}" DESTINATION "EnergyPlus/doc" COMPONENT "OpenStudioApp" USE_SOURCE_PERMISSIONS) install(DIRECTORY "${openstudio_ROOT_DIR}/Examples" DESTINATION "." COMPONENT "OpenStudioApp" USE_SOURCE_PERMISSIONS) install(DIRECTORY "${openstudio_ROOT_DIR}/Python" DESTINATION "." COMPONENT "Python" USE_SOURCE_PERMISSIONS) diff --git a/FindEnergyPlusDocs.cmake b/FindEnergyPlusDocs.cmake new file mode 100644 index 000000000..bde642303 --- /dev/null +++ b/FindEnergyPlusDocs.cmake @@ -0,0 +1,113 @@ +# Downloads a pre-built HTML export of EnergyPlus's Input Output Reference documentation +# and stages it for installation alongside the application, so doc links can point at a +# local copy instead of a live website. +# +# This is a stopgap: the export is produced manually today, not by a reproducible pipeline +# we control. Bump ENERGYPLUS_DOCS_VERSION/_URL/_EXPECTED_MD5 together whenever a new export +# is published for a newer bundled EnergyPlus version. + +set(ENERGYPLUS_DOCS_VERSION "25.2.0") +set(ENERGYPLUS_DOCS_URL "https://drive.google.com/uc?export=download&id=1nUXQjdpX_AlCqA121Rnedr8edpS2lie5") +set(ENERGYPLUS_DOCS_EXPECTED_MD5 "f13e0a862e6a956f716d78def055a804") + +set(ENERGYPLUS_DOCS_ARCHIVE_DIR "${PROJECT_BINARY_DIR}/EnergyPlusDocsArchive") +set(ENERGYPLUS_DOCS_ARCHIVE_NAME "EnergyPlus-docs-${ENERGYPLUS_DOCS_VERSION}.tar.gz") +set(ENERGYPLUS_DOCS_ARCHIVE_PATH "${ENERGYPLUS_DOCS_ARCHIVE_DIR}/${ENERGYPLUS_DOCS_ARCHIVE_NAME}") + +# Where the extracted, installable HTML ends up. Kept as a cache variable so the rest of +# the build (the install() rule, and the .cxx.in path baked in for build-tree runs) can +# refer to it without re-deriving it. +set(ENERGYPLUS_DOCS_DIR "${PROJECT_BINARY_DIR}/EnergyPlus/doc/input-output-reference" + CACHE PATH "Directory containing the extracted EnergyPlus Input Output Reference HTML" FORCE) + +file(MAKE_DIRECTORY "${ENERGYPLUS_DOCS_ARCHIVE_DIR}") + +set(ENERGYPLUS_DOCS_HASH "") +if(EXISTS "${ENERGYPLUS_DOCS_ARCHIVE_PATH}") + file(MD5 "${ENERGYPLUS_DOCS_ARCHIVE_PATH}" ENERGYPLUS_DOCS_HASH) +endif() + +set(ENERGYPLUS_DOCS_NEEDS_EXTRACT FALSE) + +if(NOT EXISTS "${ENERGYPLUS_DOCS_ARCHIVE_PATH}" OR NOT "${ENERGYPLUS_DOCS_HASH}" MATCHES "${ENERGYPLUS_DOCS_EXPECTED_MD5}") + if(NOT EXISTS "${ENERGYPLUS_DOCS_ARCHIVE_PATH}") + message(STATUS "EnergyPlus docs archive doesn't exist at \"${ENERGYPLUS_DOCS_ARCHIVE_PATH}\"") + else() + message(STATUS + "Existing EnergyPlus docs archive md5sum HASH mismatch\n" + " for file: ${ENERGYPLUS_DOCS_ARCHIVE_PATH}\n" + " expected hash: [${ENERGYPLUS_DOCS_EXPECTED_MD5}]\n" + " actual hash: [${ENERGYPLUS_DOCS_HASH}]\n" + ) + endif() + + message(STATUS "Downloading EnergyPlus docs: ${ENERGYPLUS_DOCS_URL}") + file(DOWNLOAD "${ENERGYPLUS_DOCS_URL}" "${ENERGYPLUS_DOCS_ARCHIVE_PATH}" + SHOW_PROGRESS + INACTIVITY_TIMEOUT 900 # 15-min timeout + STATUS ENERGYPLUS_DOCS_DOWNLOAD_STATUS + ) + list(GET ENERGYPLUS_DOCS_DOWNLOAD_STATUS 0 ENERGYPLUS_DOCS_DOWNLOAD_STATUS_CODE) + list(GET ENERGYPLUS_DOCS_DOWNLOAD_STATUS 1 ENERGYPLUS_DOCS_DOWNLOAD_ERROR_MSG) + + if(ENERGYPLUS_DOCS_DOWNLOAD_STATUS_CODE) + message(FATAL_ERROR + "Download of EnergyPlus docs from ${ENERGYPLUS_DOCS_URL} failed: " + "status code = ${ENERGYPLUS_DOCS_DOWNLOAD_STATUS_CODE}, message = ${ENERGYPLUS_DOCS_DOWNLOAD_ERROR_MSG}" + ) + endif() + + file(MD5 "${ENERGYPLUS_DOCS_ARCHIVE_PATH}" ENERGYPLUS_DOCS_HASH) + if(NOT "${ENERGYPLUS_DOCS_HASH}" MATCHES "${ENERGYPLUS_DOCS_EXPECTED_MD5}") + message(FATAL_ERROR + "Download of EnergyPlus docs seemed to have worked, but archive md5sum HASH mismatch\n" + " for file: ${ENERGYPLUS_DOCS_ARCHIVE_PATH}\n" + " from URL: ${ENERGYPLUS_DOCS_URL}\n" + " expected hash: [${ENERGYPLUS_DOCS_EXPECTED_MD5}]\n" + " actual hash: [${ENERGYPLUS_DOCS_HASH}]\n" + ) + endif() + + message(STATUS "Download of EnergyPlus docs succeeded") + set(ENERGYPLUS_DOCS_NEEDS_EXTRACT TRUE) +endif() + +if(ENERGYPLUS_DOCS_NEEDS_EXTRACT OR NOT EXISTS "${ENERGYPLUS_DOCS_DIR}") + if(EXISTS "${ENERGYPLUS_DOCS_DIR}") + file(REMOVE_RECURSE "${ENERGYPLUS_DOCS_DIR}") + endif() + + set(ENERGYPLUS_DOCS_EXTRACT_STAGING "${ENERGYPLUS_DOCS_ARCHIVE_DIR}/extracted") + file(REMOVE_RECURSE "${ENERGYPLUS_DOCS_EXTRACT_STAGING}") + file(MAKE_DIRECTORY "${ENERGYPLUS_DOCS_EXTRACT_STAGING}") + + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xfz "${ENERGYPLUS_DOCS_ARCHIVE_PATH}" + WORKING_DIRECTORY "${ENERGYPLUS_DOCS_EXTRACT_STAGING}" + RESULT_VARIABLE ENERGYPLUS_DOCS_EXTRACT_RESULT + ) + if(NOT ENERGYPLUS_DOCS_EXTRACT_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to extract ${ENERGYPLUS_DOCS_ARCHIVE_PATH}") + endif() + + # The archive wraps everything in a single top-level directory; find it regardless of name. + file(GLOB ENERGYPLUS_DOCS_EXTRACTED_SUBDIRS LIST_DIRECTORIES TRUE "${ENERGYPLUS_DOCS_EXTRACT_STAGING}/*") + list(LENGTH ENERGYPLUS_DOCS_EXTRACTED_SUBDIRS ENERGYPLUS_DOCS_EXTRACTED_SUBDIRS_COUNT) + if(NOT ENERGYPLUS_DOCS_EXTRACTED_SUBDIRS_COUNT EQUAL 1) + message(FATAL_ERROR "Expected exactly one top-level directory in ${ENERGYPLUS_DOCS_ARCHIVE_NAME}, found ${ENERGYPLUS_DOCS_EXTRACTED_SUBDIRS_COUNT}") + endif() + list(GET ENERGYPLUS_DOCS_EXTRACTED_SUBDIRS 0 ENERGYPLUS_DOCS_EXTRACTED_SUBDIR) + + # Drop macOS AppleDouble resource-fork files left over from how the export was archived. + file(GLOB_RECURSE ENERGYPLUS_DOCS_APPLEDOUBLE_FILES "${ENERGYPLUS_DOCS_EXTRACTED_SUBDIR}/._*") + if(ENERGYPLUS_DOCS_APPLEDOUBLE_FILES) + file(REMOVE ${ENERGYPLUS_DOCS_APPLEDOUBLE_FILES}) + endif() + + get_filename_component(ENERGYPLUS_DOCS_DIR_PARENT "${ENERGYPLUS_DOCS_DIR}" DIRECTORY) + file(MAKE_DIRECTORY "${ENERGYPLUS_DOCS_DIR_PARENT}") + file(RENAME "${ENERGYPLUS_DOCS_EXTRACTED_SUBDIR}" "${ENERGYPLUS_DOCS_DIR}") + file(REMOVE_RECURSE "${ENERGYPLUS_DOCS_EXTRACT_STAGING}") + + message(STATUS "EnergyPlus docs extracted to ${ENERGYPLUS_DOCS_DIR}") +endif() diff --git a/scripts/check_doc_urls.py b/scripts/check_doc_urls.py index 3ca2b4f14..a5c3f61ac 100644 --- a/scripts/check_doc_urls.py +++ b/scripts/check_doc_urls.py @@ -1,98 +1,51 @@ #!/usr/bin/env python3 """ -check_doc_urls.py - Verify BigLadder EnergyPlus I/O Reference URLs in OpenStudioApp source. +check_doc_urls.py - Verify the local EnergyPlus Input Output Reference doc links in OpenStudioApp source. -Scans source files for doc URL strings, fetches each unique page once, checks that -every anchor referenced actually exists in the page HTML, and reports failures. +Scans IddObjectDocUrl.hpp for page#anchor references, and checks that every referenced page +exists and every anchor referenced actually has a matching id= in that page's HTML. Usage: - python scripts/check_doc_urls.py [--repo-root PATH] [--delay SEC] [--openstudio-hxx PATH] + python scripts/check_doc_urls.py [--repo-root PATH] [--docs-dir PATH] -The BigLadder doc version (eg "25-2") is auto-detected from the OpenStudio SDK's -OpenStudio.hxx (energyPlusVersionMajor()/energyPlusVersionMinor()), the same values -openstudio::bigladdersoftwareDocBaseUrl() uses at runtime. The SDK is located by -searching for OpenStudio-*/*/include/openstudio/OpenStudio.hxx under --repo-root -(covers both in-source and build/ out-of-source SDK downloads), or pass ---openstudio-hxx to point at it directly. +The documentation directory is auto-detected by searching for EnergyPlus/doc/input-output-reference +under --repo-root (covers build-tree layouts), or pass --docs-dir to point at it directly +(this is the same directory openstudio::energyPlusDocDirectory() resolves to at runtime). Exit codes: 0 All URLs valid - 1 One or more broken/missing anchors found + 1 One or more broken/missing pages or anchors found 2 Usage / dependency error - -Why a Python script rather than a GTest network test ------------------------------------------------------ -BigLadder returns HTTP 200 for *any* URL on an existing page, regardless of whether -the anchor exists. A plain HTTP HEAD or GET check would silently pass even when an -anchor has been renamed or removed. Verifying anchor IDs requires fetching the full -page HTML and scanning for id="..." attributes — straightforward in Python with -html.parser, but awkward in C++/Qt without a full HTML parser dependency. - -GTest network tests were also considered but ruled out because: - - They are slow and flaky in CI (network dependency). - - QNetworkAccessManager requires a running event loop and async handling. - - GTest provides no natural mechanism to fetch-and-parse HTML for anchor checks. - -This script runs standalone (no build step), can be invoked as a pre-commit hook or -CI job, and completes in roughly one second per unique page fetched. """ import argparse import re import sys -import time from collections import defaultdict from html.parser import HTMLParser from pathlib import Path -from urllib.request import urlopen -from urllib.error import URLError # --------------------------------------------------------------------------- -# Files to scan and the regex patterns that extract URL fragments from them +# Files to scan and the regex pattern that extracts page#anchor fragments from them # --------------------------------------------------------------------------- # Matches values in the IddObjectDocUrl.hpp urlMap and groupMap: -# {"OS:Something", "group-foo.html#anchor"}, -# {"OpenStudio Group Name", "group-foo.html"}, +# {"OS:Something", "1.5-group-foo.html#anchor"}, +# {"OpenStudio Group Name", "1.5-group-foo.html"}, IDDOBJECTDOCURL_PATTERN = re.compile( r'"(?:OS:|OpenStudio |Solar |Electric |Energy |User |Python |Airflow)[^"]*"\s*,\s*"([^"]+\.html(?:#[^"]*)?)"' ) -# Matches QString URL constructions in .cpp files: -# QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()) + "page.html#anchor" -# or the old QStringLiteral(BASE "page.html#anchor") form -CPP_URL_FRAGMENT_PATTERN = re.compile( - r'(?:bigladdersoftwareDocBaseUrl\(\)\s*\+\s*"([^"]+\.html(?:#[^"]*)?)"' - r'|QStringLiteral\(BIGLADDERSOFTWARE_DOC_BASE_URL\s*"([^"]+\.html(?:#[^"]*)?)"' - r'|\+\s*"(group-[^"]+\.html(?:#[^"]*)?)"' - r'|\+\s*"(lifecyclecost-[^"]+\.html(?:#[^"]*)?)")' -) - SOURCE_FILES = [ "src/model_editor/IddObjectDocUrl.hpp", - "src/openstudio_lib/SimSettingsView.cpp", - "src/openstudio_lib/LoadsView.cpp", - "src/openstudio_lib/ConstructionsView.cpp", - "src/openstudio_lib/MaterialsView.cpp", - "src/openstudio_lib/ScheduleOthersView.cpp", - "src/openstudio_lib/LocationTabView.cpp", - "src/openstudio_lib/YearSettingsWidget.cpp", - "src/openstudio_lib/GroundTemperatureView.cpp", - "src/openstudio_lib/LifeCycleCostsTabView.cpp", - "src/openstudio_lib/BuildingInspectorView.cpp", ] -# Where to look for the downloaded OpenStudio SDK's OpenStudio.hxx, relative to repo root. -SDK_HXX_GLOBS = [ - "OpenStudio-*/*/include/openstudio/OpenStudio.hxx", - "build*/OpenStudio-*/*/include/openstudio/OpenStudio.hxx", +# Where to look for the extracted documentation, relative to repo root. +DOCS_DIR_GLOBS = [ + "EnergyPlus/doc/input-output-reference", + "build*/EnergyPlus/doc/input-output-reference", ] -ENERGYPLUS_VERSION_RE = { - "major": re.compile(r"energyPlusVersionMajor\(\)\s*\{\s*return\s*(\d+);"), - "minor": re.compile(r"energyPlusVersionMinor\(\)\s*\{\s*return\s*(\d+);"), -} - # --------------------------------------------------------------------------- # HTML parser that collects all id= attributes @@ -110,41 +63,24 @@ def handle_starttag(self, tag, attrs): # --------------------------------------------------------------------------- -# EnergyPlus version detection (mirrors openstudio::bigladdersoftwareDocBaseUrl()) +# Docs directory detection # --------------------------------------------------------------------------- -def find_openstudio_hxx(repo_root: Path) -> Path | None: - for pattern in SDK_HXX_GLOBS: +def find_docs_dir(repo_root: Path) -> Path | None: + for pattern in DOCS_DIR_GLOBS: matches = sorted(repo_root.glob(pattern)) if matches: return matches[0] return None -def detect_bigladdersoftware_base(hxx_path: Path) -> str: - """ - Parse energyPlusVersionMajor()/energyPlusVersionMinor() from the SDK's - OpenStudio.hxx and build the BigLadder I/O Reference base URL the same way - openstudio::bigladdersoftwareDocBaseUrl() does at runtime. - """ - text = hxx_path.read_text(encoding="utf-8") - versions = {} - for part, pattern in ENERGYPLUS_VERSION_RE.items(): - m = pattern.search(text) - if not m: - raise ValueError(f"Could not find energyPlusVersion{part.capitalize()}() in {hxx_path}") - versions[part] = m.group(1) - - return f"https://bigladdersoftware.com/epx/docs/{versions['major']}-{versions['minor']}/input-output-reference/" - - # --------------------------------------------------------------------------- # URL extraction # --------------------------------------------------------------------------- -def extract_fragments(repo_root: Path, base_url: str): +def extract_fragments(repo_root: Path): """ - Returns a dict: page_url -> list of (anchor_or_None, source_file, line_no) + Returns a dict: page_name -> list of (anchor_or_None, source_file, line_no) """ results = defaultdict(list) @@ -156,41 +92,31 @@ def extract_fragments(repo_root: Path, base_url: str): text = src.read_text(encoding="utf-8") - if rel_path.endswith("IddObjectDocUrl.hpp"): - pattern = IDDOBJECTDOCURL_PATTERN - else: - pattern = CPP_URL_FRAGMENT_PATTERN - for lineno, line in enumerate(text.splitlines(), 1): - for m in pattern.finditer(line): - fragment = next((g for g in m.groups() if g), None) - if not fragment: - continue + for m in IDDOBJECTDOCURL_PATTERN.finditer(line): + fragment = m.group(1) if "#" in fragment: - page_part, anchor = fragment.split("#", 1) + page_name, anchor = fragment.split("#", 1) else: - page_part, anchor = fragment, None - page_url = base_url + page_part - results[page_url].append((anchor, rel_path, lineno)) + page_name, anchor = fragment, None + results[page_name].append((anchor, rel_path, lineno)) return results # --------------------------------------------------------------------------- -# Page fetching with simple cache +# Page reading with simple cache # --------------------------------------------------------------------------- -def fetch_anchors(url: str, delay: float = 0.5) -> set | None: - """Fetch a page and return the set of id= values, or None on error.""" +def read_anchors(path: Path) -> set | None: + """Read a local HTML file and return the set of id= values, or None on error.""" try: - time.sleep(delay) - with urlopen(url, timeout=15) as resp: - html = resp.read().decode("utf-8", errors="replace") + html = path.read_text(encoding="utf-8", errors="replace") parser = AnchorCollector() parser.feed(html) return parser.ids - except URLError as e: - print(f" ERROR fetching {url}: {e}", file=sys.stderr) + except OSError as e: + print(f" ERROR reading {path}: {e}", file=sys.stderr) return None @@ -206,34 +132,27 @@ def main(): help="Path to the OpenStudioApplication repo root (default: current directory)", ) parser.add_argument( - "--delay", - type=float, - default=0.5, - help="Seconds to wait between page fetches (default: 0.5)", - ) - parser.add_argument( - "--openstudio-hxx", - help="Path to the OpenStudio SDK's OpenStudio.hxx (default: auto-detect under --repo-root)", + "--docs-dir", + help="Path to the extracted EnergyPlus Input Output Reference HTML (default: auto-detect under --repo-root)", ) args = parser.parse_args() repo_root = Path(args.repo_root).resolve() print(f"Scanning repo: {repo_root}") - hxx_path = Path(args.openstudio_hxx).resolve() if args.openstudio_hxx else find_openstudio_hxx(repo_root) - if hxx_path is None or not hxx_path.exists(): + docs_dir = Path(args.docs_dir).resolve() if args.docs_dir else find_docs_dir(repo_root) + if docs_dir is None or not docs_dir.is_dir(): print( - "ERROR: Could not find the OpenStudio SDK's OpenStudio.hxx " - f"(looked for {SDK_HXX_GLOBS} under {repo_root}).\n" - "Build/configure the project first, or pass --openstudio-hxx explicitly.", + "ERROR: Could not find the EnergyPlus docs directory " + f"(looked for {DOCS_DIR_GLOBS} under {repo_root}).\n" + "Configure/build the project first, or pass --docs-dir explicitly.", file=sys.stderr, ) sys.exit(2) - base_url = detect_bigladdersoftware_base(hxx_path) - print(f"Using EnergyPlus doc base URL: {base_url}\n (from {hxx_path})") + print(f"Using EnergyPlus docs directory: {docs_dir}") - fragments = extract_fragments(repo_root, base_url) + fragments = extract_fragments(repo_root) if not fragments: print("No URLs found — check SOURCE_FILES list.", file=sys.stderr) sys.exit(2) @@ -243,18 +162,22 @@ def main(): failures = [] page_cache = {} - for page_url in sorted(fragments): - print(f"Checking: {page_url}") - if page_url not in page_cache: - page_cache[page_url] = fetch_anchors(page_url, delay=args.delay) + for page_name in sorted(fragments): + page_path = docs_dir / page_name + print(f"Checking: {page_path}") + if page_name not in page_cache: + if not page_path.exists(): + page_cache[page_name] = None + else: + page_cache[page_name] = read_anchors(page_path) - page_ids = page_cache[page_url] + page_ids = page_cache[page_name] - for anchor, src_file, lineno in fragments[page_url]: + for anchor, src_file, lineno in fragments[page_name]: if page_ids is None: - failures.append((src_file, lineno, page_url, anchor, "page fetch failed")) + failures.append((src_file, lineno, page_name, anchor, "page not found")) elif anchor and anchor not in page_ids: - failures.append((src_file, lineno, page_url, anchor, "anchor not found in page")) + failures.append((src_file, lineno, page_name, anchor, "anchor not found in page")) else: status = "OK" if anchor else "OK (no anchor)" print(f" {status}: #{anchor or ''}") @@ -262,9 +185,9 @@ def main(): print() if failures: print(f"FAILURES ({len(failures)}):") - for src_file, lineno, page_url, anchor, reason in failures: + for src_file, lineno, page_name, anchor, reason in failures: print(f" {src_file}:{lineno} #{anchor} -> {reason}") - print(f" {page_url}#{anchor or ''}") + print(f" {page_name}#{anchor or ''}") sys.exit(1) else: print("All URLs OK.") diff --git a/src/model_editor/IddObjectDocUrl.hpp b/src/model_editor/IddObjectDocUrl.hpp index 5a98196a3..4cbf2aae3 100644 --- a/src/model_editor/IddObjectDocUrl.hpp +++ b/src/model_editor/IddObjectDocUrl.hpp @@ -9,473 +9,475 @@ #include #include #include +#include #include "../utilities/OpenStudioApplicationPathHelpers.hpp" +#include -// Returns the BigLadder EnergyPlus I/O Reference URL for the given OS IDD type name +// Returns the local EnergyPlus Input Output Reference URL for the given OS IDD type name // (e.g. "OS:ThermalZone"), or an empty string if none is known. -// Base URL version matches the EnergyPlus version bundled with the OpenStudio SDK -// (see openstudio::bigladdersoftwareDocBaseUrl()). +// Points at the documentation bundled alongside the app (see openstudio::energyPlusDocDirectory()). inline QString iddObjectDocUrl(const QString& iddTypeName) { - static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); + static const QString base = + QUrl::fromLocalFile(QString::fromStdString(openstudio::toString(openstudio::energyPlusDocDirectory())) + "/").toString(); // clang-format off static const QHash urlMap{ // Simulation Parameters - {"OS:SimulationControl", "group-simulation-parameters.html#simulationcontrol"}, - {"OS:Building", "group-simulation-parameters.html#building"}, - {"OS:Timestep", "group-simulation-parameters.html#timestep"}, - {"OS:RunPeriod", "group-location-climate-weather-file-access.html#runperiod"}, - {"OS:ShadowCalculation", "group-simulation-parameters.html#shadowcalculation"}, - {"OS:SurfaceConvectionAlgorithm:Inside", "group-simulation-parameters.html#surfaceconvectionalgorithminside"}, - {"OS:SurfaceConvectionAlgorithm:Outside", "group-simulation-parameters.html#surfaceconvectionalgorithmoutside"}, - {"OS:HeatBalanceAlgorithm", "group-simulation-parameters.html#heatbalancealgorithm"}, - {"OS:ZoneAirHeatBalanceAlgorithm", "group-simulation-parameters.html#zoneairheatbalancealgorithm"}, - {"OS:ZoneAirContaminantBalance", "group-simulation-parameters.html#zoneaircontaminantbalance"}, - {"OS:ConvergenceLimits", "group-simulation-parameters.html#convergencelimits"}, - {"OS:ZoneCapacitanceMultiplier:ResearchSpecial", "group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial"}, + {"OS:SimulationControl", "1.5-group-simulation-parameters.html#simulationcontrol"}, + {"OS:Building", "1.5-group-simulation-parameters.html#building"}, + {"OS:Timestep", "1.5-group-simulation-parameters.html#timestep"}, + {"OS:RunPeriod", "1.7-group-location-climate-weather-file-access.html#runperiod"}, + {"OS:ShadowCalculation", "1.5-group-simulation-parameters.html#shadowcalculation"}, + {"OS:SurfaceConvectionAlgorithm:Inside", "1.5-group-simulation-parameters.html#surfaceconvectionalgorithminside"}, + {"OS:SurfaceConvectionAlgorithm:Outside", "1.5-group-simulation-parameters.html#surfaceconvectionalgorithmoutside"}, + {"OS:HeatBalanceAlgorithm", "1.5-group-simulation-parameters.html#heatbalancealgorithm"}, + {"OS:ZoneAirHeatBalanceAlgorithm", "1.5-group-simulation-parameters.html#zoneairheatbalancealgorithm"}, + {"OS:ZoneAirContaminantBalance", "1.5-group-simulation-parameters.html#zoneaircontaminantbalance"}, + {"OS:ConvergenceLimits", "1.5-group-simulation-parameters.html#convergencelimits"}, + {"OS:ZoneCapacitanceMultiplier:ResearchSpecial", "1.5-group-simulation-parameters.html#zonecapacitancemultiplierresearchspecial"}, // Location and Climate - {"OS:Site:Location", "group-location-climate-weather-file-access.html#sitelocation"}, - {"OS:Site:GroundTemperature:Undisturbed:KusudaAchenbach", "group-location-climate-weather-file-access.html#sitegroundtemperatureundisturbedkusudaachenbach"}, - {"OS:Site:GroundTemperature:BuildingSurface", "group-location-climate-weather-file-access.html#sitegroundtemperaturebuildingsurface"}, - {"OS:Site:GroundTemperature:Shallow", "group-location-climate-weather-file-access.html#sitegroundtemperatureshallow"}, - {"OS:Site:GroundTemperature:Deep", "group-location-climate-weather-file-access.html#sitegroundtemperaturedeep"}, - {"OS:Site:GroundTemperature:FCfactorMethod", "group-location-climate-weather-file-access.html#sitegroundtemperaturefcfactormethod"}, - {"OS:Site:GroundReflectance", "group-location-climate-weather-file-access.html#sitegroundreflectance"}, - {"OS:Site:WaterMainsTemperature", "group-location-climate-weather-file-access.html#sitewatermainstemperature"}, - {"OS:SizingPeriod:DesignDay", "group-location-climate-weather-file-access.html#sizingperioddesignday"}, - {"OS:DesignDay", "group-location-climate-weather-file-access.html#sizingperioddesignday"}, - {"OS:RunPeriodControl:DaylightSavingTime", "group-location-climate-weather-file-access.html#runperiodcontroldaylightsavingtime"}, + {"OS:Site:Location", "1.7-group-location-climate-weather-file-access.html#sitelocation"}, + {"OS:Site:GroundTemperature:Undisturbed:KusudaAchenbach", "1.7-group-location-climate-weather-file-access.html#sitegroundtemperatureundisturbedkusudaachenbach"}, + {"OS:Site:GroundTemperature:BuildingSurface", "1.7-group-location-climate-weather-file-access.html#sitegroundtemperaturebuildingsurface"}, + {"OS:Site:GroundTemperature:Shallow", "1.7-group-location-climate-weather-file-access.html#sitegroundtemperatureshallow"}, + {"OS:Site:GroundTemperature:Deep", "1.7-group-location-climate-weather-file-access.html#sitegroundtemperaturedeep"}, + {"OS:Site:GroundTemperature:FCfactorMethod", "1.7-group-location-climate-weather-file-access.html#sitegroundtemperaturefcfactormethod"}, + {"OS:Site:GroundReflectance", "1.7-group-location-climate-weather-file-access.html#sitegroundreflectance"}, + {"OS:Site:WaterMainsTemperature", "1.7-group-location-climate-weather-file-access.html#sitewatermainstemperature"}, + {"OS:SizingPeriod:DesignDay", "1.7-group-location-climate-weather-file-access.html#sizingperioddesignday"}, + {"OS:DesignDay", "1.7-group-location-climate-weather-file-access.html#sizingperioddesignday"}, + {"OS:RunPeriodControl:DaylightSavingTime", "1.7-group-location-climate-weather-file-access.html#runperiodcontroldaylightsavingtime"}, // Schedules - {"OS:ScheduleTypeLimits", "group-schedules.html#scheduletypelimits"}, - {"OS:Schedule:Compact", "group-schedules.html#schedulecompact"}, - {"OS:Schedule:Constant", "group-schedules.html#scheduleconstant"}, - {"OS:Schedule:Day", "group-schedules.html#day-schedules"}, - {"OS:Schedule:Day:Hourly", "group-schedules.html#scheduledayhourly"}, - {"OS:Schedule:Day:Interval", "group-schedules.html#scheduledayinterval"}, - {"OS:Schedule:Week:Daily", "group-schedules.html#scheduleweekdaily"}, - {"OS:Schedule:Week:Compact", "group-schedules.html#scheduleweekcompact"}, - {"OS:Schedule:Year", "group-schedules.html#scheduleyear"}, - {"OS:Schedule:Ruleset", "group-schedules.html#scheduleyear"}, - {"OS:Schedule:File", "group-schedules.html#schedulefile"}, + {"OS:ScheduleTypeLimits", "1.8-group-schedules.html#scheduletypelimits"}, + {"OS:Schedule:Compact", "1.8-group-schedules.html#schedulecompact"}, + {"OS:Schedule:Constant", "1.8-group-schedules.html#scheduleconstant"}, + {"OS:Schedule:Day", "1.8-group-schedules.html#day-schedules"}, + {"OS:Schedule:Day:Hourly", "1.8-group-schedules.html#scheduledayhourly"}, + {"OS:Schedule:Day:Interval", "1.8-group-schedules.html#scheduledayinterval"}, + {"OS:Schedule:Week:Daily", "1.8-group-schedules.html#scheduleweekdaily"}, + {"OS:Schedule:Week:Compact", "1.8-group-schedules.html#scheduleweekcompact"}, + {"OS:Schedule:Year", "1.8-group-schedules.html#scheduleyear"}, + {"OS:Schedule:Ruleset", "1.8-group-schedules.html#scheduleyear"}, + {"OS:Schedule:File", "1.8-group-schedules.html#schedulefile"}, // Surface Construction Elements - {"OS:Material", "group-surface-construction-elements.html#material"}, - {"OS:Material:NoMass", "group-surface-construction-elements.html#materialnomass"}, - {"OS:Material:AirGap", "group-surface-construction-elements.html#materialairgap"}, - {"OS:Material:InfraredTransparent", "group-surface-construction-elements.html#materialinfraredtransparent"}, - {"OS:Material:RoofVegetation", "group-surface-construction-elements.html#materialroofvegetation"}, - {"OS:WindowMaterial:Glazing", "group-surface-construction-elements.html#windowmaterialglazing"}, - {"OS:WindowMaterial:Gas", "group-surface-construction-elements.html#windowmaterialgas"}, - {"OS:WindowMaterial:GasMixture", "group-surface-construction-elements.html#windowmaterialgasmixture"}, - {"OS:WindowMaterial:SimpleGlazingSystem", "group-surface-construction-elements.html#windowmaterialsimpleglazingsystem"}, - {"OS:WindowMaterial:Blind", "group-surface-construction-elements.html#windowmaterialblind"}, - {"OS:WindowMaterial:Screen", "group-surface-construction-elements.html#windowmaterialscreen"}, - {"OS:WindowMaterial:Shade", "group-surface-construction-elements.html#windowmaterialshade"}, - {"OS:Construction", "group-surface-construction-elements.html#construction-000"}, - {"OS:Construction:InternalSource", "group-surface-construction-elements.html#constructioninternalsource"}, - {"OS:Construction:WindowDataFile", "group-surface-construction-elements.html#constructionwindowdatafile"}, - {"OS:Construction:AirBoundary", "group-surface-construction-elements.html#constructionairboundary"}, - {"OS:Construction:CfactorUndergroundWall", "group-surface-construction-elements.html#constructioncfactorundergroundwall"}, - {"OS:Construction:FfactorGroundFloor", "group-surface-construction-elements.html#constructionffactorgroundfloor"}, - {"OS:WindowMaterial:DaylightRedirectionDevice", "group-surface-construction-elements.html#windowmaterialblind"}, - {"OS:WindowMaterial:Glazing:RefractionExtinctionMethod", "group-surface-construction-elements.html#windowmaterialglazingrefractionextinctionmethod"}, - {"OS:WindowProperty:FrameAndDivider", "group-thermal-zone-description-geometry.html#windowpropertyframeanddivider"}, + {"OS:Material", "1.9-group-surface-construction-elements.html#material"}, + {"OS:Material:NoMass", "1.9-group-surface-construction-elements.html#materialnomass"}, + {"OS:Material:AirGap", "1.9-group-surface-construction-elements.html#materialairgap"}, + {"OS:Material:InfraredTransparent", "1.9-group-surface-construction-elements.html#materialinfraredtransparent"}, + {"OS:Material:RoofVegetation", "1.9-group-surface-construction-elements.html#materialroofvegetation"}, + {"OS:WindowMaterial:Glazing", "1.9-group-surface-construction-elements.html#windowmaterialglazing"}, + {"OS:WindowMaterial:Gas", "1.9-group-surface-construction-elements.html#windowmaterialgas"}, + {"OS:WindowMaterial:GasMixture", "1.9-group-surface-construction-elements.html#windowmaterialgasmixture"}, + {"OS:WindowMaterial:SimpleGlazingSystem", "1.9-group-surface-construction-elements.html#windowmaterialsimpleglazingsystem"}, + {"OS:WindowMaterial:Blind", "1.9-group-surface-construction-elements.html#windowmaterialblind"}, + {"OS:WindowMaterial:Screen", "1.9-group-surface-construction-elements.html#windowmaterialscreen"}, + {"OS:WindowMaterial:Shade", "1.9-group-surface-construction-elements.html#windowmaterialshade"}, + {"OS:Construction", "1.9-group-surface-construction-elements.html#construction-000"}, + {"OS:Construction:InternalSource", "1.9-group-surface-construction-elements.html#constructioninternalsource"}, + {"OS:Construction:WindowDataFile", "1.9-group-surface-construction-elements.html#constructionwindowdatafile"}, + {"OS:Construction:AirBoundary", "1.9-group-surface-construction-elements.html#constructionairboundary"}, + {"OS:Construction:CfactorUndergroundWall", "1.9-group-surface-construction-elements.html#constructioncfactorundergroundwall"}, + {"OS:Construction:FfactorGroundFloor", "1.9-group-surface-construction-elements.html#constructionffactorgroundfloor"}, + {"OS:WindowMaterial:DaylightRedirectionDevice", "1.9-group-surface-construction-elements.html#windowmaterialblind"}, + {"OS:WindowMaterial:Glazing:RefractionExtinctionMethod", "1.9-group-surface-construction-elements.html#windowmaterialglazingrefractionextinctionmethod"}, + {"OS:WindowProperty:FrameAndDivider", "1.10-group-thermal-zone-descriptiongeometry.html#windowpropertyframeanddivider"}, // Thermal Zone Description and Geometry - {"OS:ThermalZone", "group-thermal-zone-description-geometry.html"}, - {"OS:Space", "group-thermal-zone-description-geometry.html"}, - {"OS:SpaceType", "group-thermal-zone-description-geometry.html"}, - {"OS:BuildingStory", "group-thermal-zone-description-geometry.html"}, - {"OS:Surface", "group-thermal-zone-description-geometry.html#buildingsurfacedetailed"}, - {"OS:SubSurface", "group-thermal-zone-description-geometry.html#fenestrationsurfacedetailed"}, - {"OS:ShadingControl", "group-thermal-zone-description-geometry.html#windowpropertyshadingcontrol"}, - {"OS:InteriorPartitionSurfaceGroup", "group-thermal-zone-description-geometry.html"}, + {"OS:ThermalZone", "1.10-group-thermal-zone-descriptiongeometry.html"}, + {"OS:Space", "1.10-group-thermal-zone-descriptiongeometry.html"}, + {"OS:SpaceType", "1.10-group-thermal-zone-descriptiongeometry.html"}, + {"OS:BuildingStory", "1.10-group-thermal-zone-descriptiongeometry.html"}, + {"OS:Surface", "1.10-group-thermal-zone-descriptiongeometry.html#buildingsurfacedetailed"}, + {"OS:SubSurface", "1.10-group-thermal-zone-descriptiongeometry.html#fenestrationsurfacedetailed"}, + {"OS:ShadingControl", "1.10-group-thermal-zone-descriptiongeometry.html#windowpropertyshadingcontrol"}, + {"OS:InteriorPartitionSurfaceGroup", "1.10-group-thermal-zone-descriptiongeometry.html"}, // Daylighting - {"OS:Daylighting:Control", "group-daylighting.html#daylightingcontrols-000"}, - {"OS:DaylightingDevice:Shelf", "group-daylighting.html#daylightingdeviceshelf"}, - {"OS:DaylightingDevice:Tubular", "group-daylighting.html#daylightingdevicetubular"}, - {"OS:DaylightingDevice:LightWell", "group-daylighting.html#daylightingdevicelightwell"}, + {"OS:Daylighting:Control", "1.15-group-daylighting.html#daylightingcontrols-000"}, + {"OS:DaylightingDevice:Shelf", "1.15-group-daylighting.html#daylightingdeviceshelf"}, + {"OS:DaylightingDevice:Tubular", "1.15-group-daylighting.html#daylightingdevicetubular"}, + {"OS:DaylightingDevice:LightWell", "1.15-group-daylighting.html#daylightingdevicelightwell"}, // Internal Gains - {"OS:People", "group-internal-gains-people-lights-other.html#people"}, - {"OS:Lights", "group-internal-gains-people-lights-other.html#lights-000"}, - {"OS:ElectricEquipment", "group-internal-gains-people-lights-other.html#electricequipment"}, - {"OS:GasEquipment", "group-internal-gains-people-lights-other.html#gasequipment"}, - {"OS:HotWaterEquipment", "group-internal-gains-people-lights-other.html#hotwaterequipment"}, - {"OS:SteamEquipment", "group-internal-gains-people-lights-other.html#steamequipment"}, - {"OS:OtherEquipment", "group-internal-gains-people-lights-other.html#otherequipment"}, - {"OS:InternalMass", "group-thermal-zone-description-geometry.html#internalmass"}, - {"OS:SwimmingPool:Indoor", "group-internal-gains-people-lights-other.html#swimmingpoolindoor"}, + {"OS:People", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#people"}, + {"OS:Lights", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#lights-000"}, + {"OS:ElectricEquipment", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#electricequipment"}, + {"OS:GasEquipment", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#gasequipment"}, + {"OS:HotWaterEquipment", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#hotwaterequipment"}, + {"OS:SteamEquipment", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#steamequipment"}, + {"OS:OtherEquipment", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#otherequipment"}, + {"OS:InternalMass", "1.10-group-thermal-zone-descriptiongeometry.html#internalmass"}, + {"OS:SwimmingPool:Indoor", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html#swimmingpoolindoor"}, // Exterior Energy Use - {"OS:Exterior:Lights", "group-exterior-energy-use-equipment.html#exteriorlights"}, - {"OS:Exterior:FuelEquipment", "group-exterior-energy-use-equipment.html#exteriorfuelequipment"}, - {"OS:Exterior:WaterEquipment", "group-exterior-energy-use-equipment.html#exteriorwaterequipment"}, + {"OS:Exterior:Lights", "1.16-group-exterior-energy-use-equipment.html#exteriorlights"}, + {"OS:Exterior:FuelEquipment", "1.16-group-exterior-energy-use-equipment.html#exteriorfuelequipment"}, + {"OS:Exterior:WaterEquipment", "1.16-group-exterior-energy-use-equipment.html#exteriorwaterequipment"}, // Older OpenStudio type names - {"OS:ExteriorLights", "group-exterior-energy-use-equipment.html#exteriorlights"}, - {"OS:ExteriorFuelEquipment", "group-exterior-energy-use-equipment.html#exteriorfuelequipment"}, - {"OS:ExteriorWaterEquipment", "group-exterior-energy-use-equipment.html#exteriorwaterequipment"}, + {"OS:ExteriorLights", "1.16-group-exterior-energy-use-equipment.html#exteriorlights"}, + {"OS:ExteriorFuelEquipment", "1.16-group-exterior-energy-use-equipment.html#exteriorfuelequipment"}, + {"OS:ExteriorWaterEquipment", "1.16-group-exterior-energy-use-equipment.html#exteriorwaterequipment"}, // Zone Airflow - {"OS:SpaceInfiltration:DesignFlowRate", "group-airflow.html#zoneinfiltrationdesignflowrate"}, - {"OS:SpaceInfiltration:EffectiveLeakageArea", "group-airflow.html#zoneinfiltrationeffectiveleakagearea"}, - {"OS:ZoneVentilation:DesignFlowRate", "group-airflow.html#zoneventilationdesignflowrate"}, - {"OS:ZoneVentilation:WindandStackOpenArea", "group-airflow.html#zoneventilationwindandstackopenarea"}, - {"OS:ZoneMixing", "group-airflow.html#zonemixing"}, - {"OS:ZoneCrossMixing", "group-airflow.html#zonecrossmixing"}, + {"OS:SpaceInfiltration:DesignFlowRate", "1.17-group-airflow.html#zoneinfiltrationdesignflowrate"}, + {"OS:SpaceInfiltration:EffectiveLeakageArea", "1.17-group-airflow.html#zoneinfiltrationeffectiveleakagearea"}, + {"OS:ZoneVentilation:DesignFlowRate", "1.17-group-airflow.html#zoneventilationdesignflowrate"}, + {"OS:ZoneVentilation:WindandStackOpenArea", "1.17-group-airflow.html#zoneventilationwindandstackopenarea"}, + {"OS:ZoneMixing", "1.17-group-airflow.html#zonemixing"}, + {"OS:ZoneCrossMixing", "1.17-group-airflow.html#zonecrossmixing"}, // Design Objects / Sizing - {"OS:DesignSpecification:OutdoorAir", "group-design-objects.html#designspecificationoutdoorair"}, - {"OS:DesignSpecification:ZoneAirDistribution", "group-design-objects.html#designspecificationzoneairdistribution"}, - {"OS:Sizing:Zone", "group-design-objects.html#sizingzone"}, - {"OS:Sizing:System", "group-design-objects.html#sizingsystem"}, - {"OS:Sizing:Plant", "group-design-objects.html#sizingplant"}, - {"OS:Sizing:Parameters", "group-design-objects.html#sizingparameters"}, + {"OS:DesignSpecification:OutdoorAir", "1.18-group-design-objects.html#designspecificationoutdoorair"}, + {"OS:DesignSpecification:ZoneAirDistribution", "1.18-group-design-objects.html#designspecificationzoneairdistribution"}, + {"OS:Sizing:Zone", "1.18-group-design-objects.html#sizingzone"}, + {"OS:Sizing:System", "1.18-group-design-objects.html#sizingsystem"}, + {"OS:Sizing:Plant", "1.18-group-design-objects.html#sizingplant"}, + {"OS:Sizing:Parameters", "1.18-group-design-objects.html#sizingparameters"}, // Zone HVAC Controls and Thermostats - {"OS:ThermostatSetpoint:DualSetpoint", "group-zone-controls-thermostats.html#thermostatsetpointdualsetpoint"}, - {"OS:ThermostatSetpoint:SingleHeating", "group-zone-controls-thermostats.html#thermostatsetpointsingleheating"}, - {"OS:ThermostatSetpoint:SingleCooling", "group-zone-controls-thermostats.html#thermostatsetpointsinglecooling"}, - {"OS:ZoneControl:Thermostat", "group-zone-controls-thermostats.html#zonecontrolthermostat"}, - {"OS:ZoneControl:ContaminantController", "group-zone-controls-thermostats.html#zonecontrolcontaminantcontroller"}, - {"OS:ZoneControl:Humidistat", "group-zone-controls-thermostats.html#zonecontrolhumidistat"}, - {"OS:ZoneControl:Thermostat:StagedDualSetpoint", "group-zone-controls-thermostats.html#zonecontrolthermostatstageddualsetpoint"}, + {"OS:ThermostatSetpoint:DualSetpoint", "1.36-group---zone-controls---thermostats-and-humidistats.html#thermostatsetpointdualsetpoint"}, + {"OS:ThermostatSetpoint:SingleHeating", "1.36-group---zone-controls---thermostats-and-humidistats.html#thermostatsetpointsingleheating"}, + {"OS:ThermostatSetpoint:SingleCooling", "1.36-group---zone-controls---thermostats-and-humidistats.html#thermostatsetpointsinglecooling"}, + {"OS:ZoneControl:Thermostat", "1.36-group---zone-controls---thermostats-and-humidistats.html#zonecontrolthermostat"}, + {"OS:ZoneControl:ContaminantController", "1.36-group---zone-controls---thermostats-and-humidistats.html#zonecontrolcontaminantcontroller"}, + {"OS:ZoneControl:Humidistat", "1.36-group---zone-controls---thermostats-and-humidistats.html#zonecontrolhumidistat"}, + {"OS:ZoneControl:Thermostat:StagedDualSetpoint", "1.36-group---zone-controls---thermostats-and-humidistats.html#zonecontrolthermostatstageddualsetpoint"}, // Zone HVAC Equipment Connections - {"OS:ZoneHVAC:EquipmentList", "group-zone-equipment.html#zonehvacequipmentlist"}, - {"OS:ZoneHVAC:EquipmentConnections", "group-zone-equipment.html#zonehvacequipmentconnections"}, + {"OS:ZoneHVAC:EquipmentList", "1.29-group---zone-equipment.html#zonehvacequipmentlist"}, + {"OS:ZoneHVAC:EquipmentConnections", "1.29-group---zone-equipment.html#zonehvacequipmentconnections"}, // Zone HVAC Forced Air Units - {"OS:ZoneHVAC:PackagedTerminalAirConditioner", "group-zone-forced-air-units.html#zonehvacpackagedterminalairconditioner"}, - {"OS:ZoneHVAC:PackagedTerminalHeatPump", "group-zone-forced-air-units.html#zonehvacpackagedterminalheatpump"}, - {"OS:ZoneHVAC:WaterToAirHeatPump", "group-zone-forced-air-units.html#zonehvacwatertoairheatpump"}, - {"OS:ZoneHVAC:FourPipeFanCoil", "group-zone-forced-air-units.html#zonehvacfourpipefancoil"}, - {"OS:ZoneHVAC:UnitVentilator", "group-zone-forced-air-units.html#zonehvacunitventilator"}, - {"OS:ZoneHVAC:UnitHeater", "group-zone-forced-air-units.html#zonehvacunitheater"}, - {"OS:ZoneHVAC:IdealLoadsAirSystem", "group-zone-forced-air-units.html#zonehvacidealloadsairsystem"}, - {"OS:ZoneHVAC:EnergyRecoveryVentilator", "group-zone-forced-air-units.html#zonehvacenergyrecoveryventilator"}, - {"OS:ZoneHVAC:Dehumidifier:DX", "group-zone-forced-air-units.html#zonehvacdehumidifierdx"}, - {"OS:ZoneHVAC:EvaporativeCoolerUnit", "group-zone-forced-air-units.html#zonehvacevaporativecoolerunit"}, - {"OS:ZoneHVAC:Baseboard:Convective:Water", "group-radiative-convective-units.html#zonehvacbaseboardconvectivewater"}, - {"OS:ZoneHVAC:Baseboard:Convective:Electric", "group-radiative-convective-units.html#zonehvacbaseboardconvectiveelectric"}, - {"OS:ZoneHVAC:TerminalUnit:VariableRefrigerantFlow", "group-zone-forced-air-units.html#zonehvacterminalunitvariablerefrigerantflow"}, + {"OS:ZoneHVAC:PackagedTerminalAirConditioner", "1.31-group-zone-forced-air-units.html#zonehvacpackagedterminalairconditioner"}, + {"OS:ZoneHVAC:PackagedTerminalHeatPump", "1.31-group-zone-forced-air-units.html#zonehvacpackagedterminalheatpump"}, + {"OS:ZoneHVAC:WaterToAirHeatPump", "1.31-group-zone-forced-air-units.html#zonehvacwatertoairheatpump"}, + {"OS:ZoneHVAC:FourPipeFanCoil", "1.31-group-zone-forced-air-units.html#zonehvacfourpipefancoil"}, + {"OS:ZoneHVAC:UnitVentilator", "1.31-group-zone-forced-air-units.html#zonehvacunitventilator"}, + {"OS:ZoneHVAC:UnitHeater", "1.31-group-zone-forced-air-units.html#zonehvacunitheater"}, + {"OS:ZoneHVAC:IdealLoadsAirSystem", "1.31-group-zone-forced-air-units.html#zonehvacidealloadsairsystem"}, + {"OS:ZoneHVAC:EnergyRecoveryVentilator", "1.31-group-zone-forced-air-units.html#zonehvacenergyrecoveryventilator"}, + {"OS:ZoneHVAC:Dehumidifier:DX", "1.31-group-zone-forced-air-units.html#zonehvacdehumidifierdx"}, + {"OS:ZoneHVAC:EvaporativeCoolerUnit", "1.31-group-zone-forced-air-units.html#zonehvacevaporativecoolerunit"}, + {"OS:ZoneHVAC:Baseboard:Convective:Water", "1.34-group-radiative-convective-units.html#zonehvacbaseboardconvectivewater"}, + {"OS:ZoneHVAC:Baseboard:Convective:Electric", "1.34-group-radiative-convective-units.html#zonehvacbaseboardconvectiveelectric"}, + {"OS:ZoneHVAC:TerminalUnit:VariableRefrigerantFlow", "1.31-group-zone-forced-air-units.html#zonehvacterminalunitvariablerefrigerantflow"}, // Zone HVAC Radiative / Cooling Panels - {"OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water", "group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, - {"OS:ZoneHVAC:Baseboard:RadiantConvective:Water", "group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, - {"OS:ZoneHVAC:Baseboard:RadiantConvective:Electric","group-radiative-convective-units.html#zonehvacbaseboardradiantconvectiveelectric"}, - {"OS:ZoneHVAC:HighTemperatureRadiant", "group-radiative-convective-units.html#zonehvachightemperatureradiant"}, - {"OS:ZoneHVAC:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflow"}, - {"OS:ZoneHVAC:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, - {"OS:ZoneHVAC:LowTemperatureRadiant:Electric", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantelectric"}, + {"OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water", "1.34-group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, + {"OS:ZoneHVAC:Baseboard:RadiantConvective:Water", "1.34-group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, + {"OS:ZoneHVAC:Baseboard:RadiantConvective:Electric","1.34-group-radiative-convective-units.html#zonehvacbaseboardradiantconvectiveelectric"}, + {"OS:ZoneHVAC:HighTemperatureRadiant", "1.34-group-radiative-convective-units.html#zonehvachightemperatureradiant"}, + {"OS:ZoneHVAC:LowTemperatureRadiant:VariableFlow", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflow"}, + {"OS:ZoneHVAC:LowTemperatureRadiant:ConstantFlow", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, + {"OS:ZoneHVAC:LowTemperatureRadiant:Electric", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantelectric"}, // Air Terminals - {"OS:AirTerminal:SingleDuct:VAV:Reheat", "group-air-distribution-equipment.html#airterminalsingleductvavreheat"}, - {"OS:AirTerminal:SingleDuct:VAV:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductvavnoreheat"}, - {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat", "group-air-distribution-equipment.html#airterminalsingleductvavheatandcoolreheat"}, - {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductvavheatandcoolnoreheat"}, - {"OS:AirTerminal:SingleDuct:ConstantVolume:Reheat", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumereheat"}, - {"OS:AirTerminal:SingleDuct:ConstantVolume:NoReheat", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumenoreheat"}, - {"OS:AirTerminal:SingleDuct:ConstantVolume:CooledBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumecooledbeam"}, - {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, - {"OS:AirTerminal:SingleDuct:ParallelPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductparallelpiureheat"}, - {"OS:AirTerminal:SingleDuct:SeriesPIU:Reheat", "group-air-distribution-equipment.html#airterminalsingleductseriespiureheat"}, - {"OS:AirTerminal:SingleDuct:InletSideMixer", "group-air-distribution-equipment.html#airterminalsingleductmixer"}, - {"OS:AirTerminal:DualDuct:VAV", "group-air-distribution-equipment.html#airterminaldualductvav"}, - {"OS:AirTerminal:DualDuct:VAV:OutdoorAir", "group-air-distribution-equipment.html#airterminaldualductvavoutdoorair"}, - {"OS:AirTerminal:DualDuct:ConstantVolume", "group-air-distribution-equipment.html#airterminaldualductconstantvolume"}, - {"OS:AirTerminal:FourPipeInduction", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipeinduction"}, - {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipeinduction"}, + {"OS:AirTerminal:SingleDuct:VAV:Reheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductvavreheat"}, + {"OS:AirTerminal:SingleDuct:VAV:NoReheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductvavnoreheat"}, + {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:Reheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductvavheatandcoolreheat"}, + {"OS:AirTerminal:SingleDuct:VAV:HeatAndCool:NoReheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductvavheatandcoolnoreheat"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:Reheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumereheat"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:NoReheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumenoreheat"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:CooledBeam", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumecooledbeam"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeBeam", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumefourpipebeam"}, + {"OS:AirTerminal:SingleDuct:ParallelPIU:Reheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductparallelpiureheat"}, + {"OS:AirTerminal:SingleDuct:SeriesPIU:Reheat", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductseriespiureheat"}, + {"OS:AirTerminal:SingleDuct:InletSideMixer", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductmixer"}, + {"OS:AirTerminal:DualDuct:VAV", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminaldualductvav"}, + {"OS:AirTerminal:DualDuct:VAV:OutdoorAir", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminaldualductvavoutdoorair"}, + {"OS:AirTerminal:DualDuct:ConstantVolume", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminaldualductconstantvolume"}, + {"OS:AirTerminal:FourPipeInduction", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumefourpipeinduction"}, + {"OS:AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumefourpipeinduction"}, // Fans - {"OS:Fan:ConstantVolume", "group-fans.html#fanconstantvolume"}, - {"OS:Fan:VariableVolume", "group-fans.html#fanvariablevolume"}, - {"OS:Fan:OnOff", "group-fans.html#fanonoff"}, - {"OS:Fan:ZoneExhaust", "group-fans.html#fanzoneexhaust"}, - {"OS:Fan:SystemModel", "group-fans.html#fansystemmodel"}, - {"OS:Fan:ComponentModel", "group-fans.html#fancomponentmodel"}, + {"OS:Fan:ConstantVolume", "1.43-group-fans.html#fanconstantvolume"}, + {"OS:Fan:VariableVolume", "1.43-group-fans.html#fanvariablevolume"}, + {"OS:Fan:OnOff", "1.43-group-fans.html#fanonoff"}, + {"OS:Fan:ZoneExhaust", "1.43-group-fans.html#fanzoneexhaust"}, + {"OS:Fan:SystemModel", "1.43-group-fans.html#fansystemmodel"}, + {"OS:Fan:ComponentModel", "1.43-group-fans.html#fancomponentmodel"}, // Coils - Cooling - {"OS:Coil:Cooling:DX:SingleSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxsinglespeed"}, - {"OS:Coil:Cooling:DX:TwoSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxtwospeed"}, - {"OS:Coil:Cooling:DX:MultiSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, - {"OS:Coil:Cooling:DX:VariableSpeed", "group-heating-and-cooling-coils.html#coilcoolingdxvariablespeed"}, - {"OS:Coil:Cooling:DX:VariableRefrigerantFlow", "group-heating-and-cooling-coils.html#coilcoolingdxvariablerefrigerantflow"}, - {"OS:Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl", "group-heating-and-cooling-coils.html#coilcoolingdxvariablerefrigerantflowfluidtemperaturecontrol"}, - {"OS:Coil:Cooling:Water", "group-heating-and-cooling-coils.html#coilcoolingwater"}, - {"OS:Coil:Cooling:Water:DetailedGeometry", "group-heating-and-cooling-coils.html#coilcoolingwaterdetailedgeometry"}, - {"OS:Coil:Cooling:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpequationfit"}, - {"OS:Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpvariablespeedequationfit"}, - {"OS:Coil:Cooling:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, - {"OS:Coil:Cooling:DX:TwoStageWithHumidityControlMode", "group-heating-and-cooling-coils.html#coilcoolingdxtwostagewithhumiditycontrolmode"}, - {"OS:Coil:Cooling:DX:MultiSpeed:StageData", "group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, - {"OS:Coil:Cooling:Water:Panel:Radiant", "group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, - {"OS:Coil:Cooling:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, - {"OS:Coil:Cooling:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflow"}, - {"OS:CoilPerformance:DX:Cooling", "group-heating-and-cooling-coils.html#coilperformancedxcooling"}, + {"OS:Coil:Cooling:DX:SingleSpeed", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxsinglespeed"}, + {"OS:Coil:Cooling:DX:TwoSpeed", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxtwospeed"}, + {"OS:Coil:Cooling:DX:MultiSpeed", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, + {"OS:Coil:Cooling:DX:VariableSpeed", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxvariablespeed"}, + {"OS:Coil:Cooling:DX:VariableRefrigerantFlow", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxvariablerefrigerantflow"}, + {"OS:Coil:Cooling:DX:VariableRefrigerantFlow:FluidTemperatureControl", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxvariablerefrigerantflowfluidtemperaturecontrol"}, + {"OS:Coil:Cooling:Water", "1.42-group-heating-and-cooling-coils.html#coilcoolingwater"}, + {"OS:Coil:Cooling:Water:DetailedGeometry", "1.42-group-heating-and-cooling-coils.html#coilcoolingwaterdetailedgeometry"}, + {"OS:Coil:Cooling:WaterToAirHeatPump:EquationFit", "1.42-group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpequationfit"}, + {"OS:Coil:Cooling:WaterToAirHeatPump:VariableSpeedEquationFit", "1.42-group-heating-and-cooling-coils.html#coilcoolingwatertoairheatpumpvariablespeedequationfit"}, + {"OS:Coil:Cooling:FourPipeBeam", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumefourpipebeam"}, + {"OS:Coil:Cooling:DX:TwoStageWithHumidityControlMode", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxtwostagewithhumiditycontrolmode"}, + {"OS:Coil:Cooling:DX:MultiSpeed:StageData", "1.42-group-heating-and-cooling-coils.html#coilcoolingdxmultispeed"}, + {"OS:Coil:Cooling:Water:Panel:Radiant", "1.34-group-radiative-convective-units.html#zonehvaccoolingpanelradiantconvectivewater"}, + {"OS:Coil:Cooling:LowTemperatureRadiant:ConstantFlow", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, + {"OS:Coil:Cooling:LowTemperatureRadiant:VariableFlow", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflow"}, + {"OS:CoilPerformance:DX:Cooling", "1.42-group-heating-and-cooling-coils.html#coilperformancedxcooling"}, // Coils - Heating - {"OS:Coil:Heating:Gas", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, - {"OS:Coil:Heating:Fuel", "group-heating-and-cooling-coils.html#coilheatinggas-000"}, - {"OS:Coil:Heating:Electric", "group-heating-and-cooling-coils.html#coilheatingelectric"}, - {"OS:Coil:Heating:Water", "group-heating-and-cooling-coils.html#coilheatingwater"}, - {"OS:Coil:Heating:DX:SingleSpeed", "group-heating-and-cooling-coils.html#coilheatingdxsinglespeed"}, - {"OS:Coil:Heating:DX:MultiSpeed", "group-heating-and-cooling-coils.html#coilheatingdxmultispeed"}, - {"OS:Coil:Heating:DX:VariableSpeed", "group-heating-and-cooling-coils.html#coilheatingdxvariablespeed"}, - {"OS:Coil:Heating:DX:VariableRefrigerantFlow", "group-heating-and-cooling-coils.html#coilheatingdxvariablerefrigerantflow"}, - {"OS:Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl", "group-heating-and-cooling-coils.html#coilheatingdxvariablerefrigerantflowfluidtemperaturecontrol"}, - {"OS:Coil:Heating:WaterToAirHeatPump:EquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpequationfit"}, - {"OS:Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit", "group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpvariablespeedequationfit"}, - {"OS:Coil:Heating:Desuperheater", "group-heating-and-cooling-coils.html#coilheatingdesuperheater"}, - {"OS:Coil:Heating:FourPipeBeam", "group-air-distribution-equipment.html#airterminalsingleductconstantvolumefourpipebeam"}, - {"OS:Coil:Heating:Gas:MultiStage", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, - {"OS:Coil:Heating:Gas:MultiStage:StageData", "group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, - {"OS:Coil:Heating:LowTemperatureRadiant:ConstantFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, - {"OS:Coil:Heating:LowTemperatureRadiant:VariableFlow", "group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflowdesign"}, - {"OS:Coil:Heating:Water:Baseboard", "group-radiative-convective-units.html#zonehvacbaseboardconvectivewater"}, - {"OS:Coil:Heating:Water:Baseboard:Radiant", "group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, - {"OS:Coil:WaterHeating:AirToWaterHeatPump", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, - {"OS:Coil:WaterHeating:AirToWaterHeatPump:Pumped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, - {"OS:Coil:WaterHeating:AirToWaterHeatPump:Wrapped", "group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumpwrapped"}, - {"OS:Coil:WaterHeating:Desuperheater", "group-heating-and-cooling-coils.html#coilwaterheatingdesuperheater"}, + {"OS:Coil:Heating:Gas", "1.42-group-heating-and-cooling-coils.html#coilheatinggas-000"}, + {"OS:Coil:Heating:Fuel", "1.42-group-heating-and-cooling-coils.html#coilheatinggas-000"}, + {"OS:Coil:Heating:Electric", "1.42-group-heating-and-cooling-coils.html#coilheatingelectric"}, + {"OS:Coil:Heating:Water", "1.42-group-heating-and-cooling-coils.html#coilheatingwater"}, + {"OS:Coil:Heating:DX:SingleSpeed", "1.42-group-heating-and-cooling-coils.html#coilheatingdxsinglespeed"}, + {"OS:Coil:Heating:DX:MultiSpeed", "1.42-group-heating-and-cooling-coils.html#coilheatingdxmultispeed"}, + {"OS:Coil:Heating:DX:VariableSpeed", "1.42-group-heating-and-cooling-coils.html#coilheatingdxvariablespeed"}, + {"OS:Coil:Heating:DX:VariableRefrigerantFlow", "1.42-group-heating-and-cooling-coils.html#coilheatingdxvariablerefrigerantflow"}, + {"OS:Coil:Heating:DX:VariableRefrigerantFlow:FluidTemperatureControl", "1.42-group-heating-and-cooling-coils.html#coilheatingdxvariablerefrigerantflowfluidtemperaturecontrol"}, + {"OS:Coil:Heating:WaterToAirHeatPump:EquationFit", "1.42-group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpequationfit"}, + {"OS:Coil:Heating:WaterToAirHeatPump:VariableSpeedEquationFit", "1.42-group-heating-and-cooling-coils.html#coilheatingwatertoairheatpumpvariablespeedequationfit"}, + {"OS:Coil:Heating:Desuperheater", "1.42-group-heating-and-cooling-coils.html#coilheatingdesuperheater"}, + {"OS:Coil:Heating:FourPipeBeam", "1.30-group-zone-HVAC-air-loop-terminal-units.html#airterminalsingleductconstantvolumefourpipebeam"}, + {"OS:Coil:Heating:Gas:MultiStage", "1.42-group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, + {"OS:Coil:Heating:Gas:MultiStage:StageData", "1.42-group-heating-and-cooling-coils.html#coilheatinggasmultistage"}, + {"OS:Coil:Heating:LowTemperatureRadiant:ConstantFlow", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantconstantflow"}, + {"OS:Coil:Heating:LowTemperatureRadiant:VariableFlow", "1.34-group-radiative-convective-units.html#zonehvaclowtemperatureradiantvariableflowdesign"}, + {"OS:Coil:Heating:Water:Baseboard", "1.34-group-radiative-convective-units.html#zonehvacbaseboardconvectivewater"}, + {"OS:Coil:Heating:Water:Baseboard:Radiant", "1.34-group-radiative-convective-units.html#zonehvacbaseboardradiantconvectivewater"}, + {"OS:Coil:WaterHeating:AirToWaterHeatPump", "1.42-group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, + {"OS:Coil:WaterHeating:AirToWaterHeatPump:Pumped", "1.42-group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumppumped"}, + {"OS:Coil:WaterHeating:AirToWaterHeatPump:Wrapped", "1.42-group-heating-and-cooling-coils.html#coilwaterheatingairtowaterheatpumpwrapped"}, + {"OS:Coil:WaterHeating:Desuperheater", "1.42-group-heating-and-cooling-coils.html#coilwaterheatingdesuperheater"}, // Evaporative Coolers - {"OS:EvaporativeCooler:Direct:ResearchSpecial", "group-evaporative-coolers.html#evaporativecoolerdirectresearchspecial"}, - {"OS:EvaporativeCooler:Indirect:ResearchSpecial", "group-evaporative-coolers.html#evaporativecoolerindirectresearchspecial"}, - {"OS:EvaporativeCooler:Direct:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerdirectceldekpad"}, - {"OS:EvaporativeCooler:Indirect:CelDekPad", "group-evaporative-coolers.html#evaporativecoolerindirectceldekpad"}, - {"OS:EvaporativeCooler:Indirect:WetCoil", "group-evaporative-coolers.html#evaporativecoolerindirectwetcoil"}, + {"OS:EvaporativeCooler:Direct:ResearchSpecial", "1.52-group-evaporative-coolers.html#evaporativecoolerdirectresearchspecial"}, + {"OS:EvaporativeCooler:Indirect:ResearchSpecial", "1.52-group-evaporative-coolers.html#evaporativecoolerindirectresearchspecial"}, + {"OS:EvaporativeCooler:Direct:CelDekPad", "1.52-group-evaporative-coolers.html#evaporativecoolerdirectceldekpad"}, + {"OS:EvaporativeCooler:Indirect:CelDekPad", "1.52-group-evaporative-coolers.html#evaporativecoolerindirectceldekpad"}, + {"OS:EvaporativeCooler:Indirect:WetCoil", "1.52-group-evaporative-coolers.html#evaporativecoolerindirectwetcoil"}, // Humidifiers - {"OS:Humidifier:Steam:Electric", "group-humidifiers-and-dehumidifiers.html#humidifiersteamelectric"}, - {"OS:Humidifier:Steam:Gas", "group-humidifiers-and-dehumidifiers.html#humidifiersteamgas"}, + {"OS:Humidifier:Steam:Electric", "1.44-group-humidifiers-and-dehumidifiers.html#humidifiersteamelectric"}, + {"OS:Humidifier:Steam:Gas", "1.44-group-humidifiers-and-dehumidifiers.html#humidifiersteamgas"}, // Unitary Equipment - {"OS:AirLoopHVAC:UnitaryHeatPump:AirToAir", "group-unitary-equipment.html#airloophvacunitaryheatpumpairtoair"}, - {"OS:AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed", "group-unitary-equipment.html#airloophvacunitaryheatpumpairtoairmultispeed"}, - {"OS:AirLoopHVAC:UnitarySystem", "group-unitary-equipment.html#airloophvacunitarysystem"}, - {"OS:AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", "group-unitary-equipment.html#airloophvacunitaryheatcoolvavchangeoverbypass"}, + {"OS:AirLoopHVAC:UnitaryHeatPump:AirToAir", "1.32-group-unitary-equipment.html#airloophvacunitaryheatpumpairtoair"}, + {"OS:AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed", "1.32-group-unitary-equipment.html#airloophvacunitaryheatpumpairtoairmultispeed"}, + {"OS:AirLoopHVAC:UnitarySystem", "1.32-group-unitary-equipment.html#airloophvacunitarysystem"}, + {"OS:AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", "1.32-group-unitary-equipment.html#airloophvacunitaryheatcoolvavchangeoverbypass"}, // Variable Refrigerant Flow - {"OS:AirConditioner:VariableRefrigerantFlow", "group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflow"}, - {"OS:AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl", "group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflowfluidtemperaturecontrol"}, - {"OS:AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR", "group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflowfluidtemperaturecontrolhr"}, + {"OS:AirConditioner:VariableRefrigerantFlow", "1.33-group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflow"}, + {"OS:AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl", "1.33-group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflowfluidtemperaturecontrol"}, + {"OS:AirConditioner:VariableRefrigerantFlow:FluidTemperatureControl:HR", "1.33-group-variable-refrigerant-flow-equipment.html#airconditionervariablerefrigerantflowfluidtemperaturecontrolhr"}, // Air Distribution / AirLoop - {"OS:AirLoopHVAC", "group-air-distribution.html#group-air-distribution"}, - {"OS:AirLoopHVAC:OutdoorAirSystem", "group-air-distribution.html#airloophvacoutdoorairsystem"}, - {"OS:OutdoorAir:Mixer", "group-air-distribution.html#outdoorairmixer"}, - {"OS:Controller:OutdoorAir", "group-controllers.html#controlleroutdoorair"}, - {"OS:Controller:MechanicalVentilation", "group-controllers.html#controllermechanicalventilation"}, - {"OS:ZoneHVAC:EnergyRecoveryVentilator:Controller", "group-controllers.html#zonehvacenergyrecoveryventilatorcontroller"}, - {"OS:AirLoopHVAC:ZoneMixer", "group-air-path.html#airloophvaczonemixer"}, - {"OS:AirLoopHVAC:ZoneSplitter", "group-air-path.html#airloophvaczonesplitter"}, - {"OS:AirLoopHVAC:ReturnPlenum", "group-air-path.html#airloophvacreturnplenum"}, - {"OS:AirLoopHVAC:SupplyPlenum", "group-air-path.html#airloophvacsupplyplenum"}, + {"OS:AirLoopHVAC", "1.26-group-air-distribution.html#group-air-distribution"}, + {"OS:AirLoopHVAC:OutdoorAirSystem", "1.26-group-air-distribution.html#airloophvacoutdoorairsystem"}, + {"OS:OutdoorAir:Mixer", "1.26-group-air-distribution.html#outdoorairmixer"}, + {"OS:Controller:OutdoorAir", "1.51-group-controllers.html#controlleroutdoorair"}, + {"OS:Controller:MechanicalVentilation", "1.51-group-controllers.html#controllermechanicalventilation"}, + {"OS:ZoneHVAC:EnergyRecoveryVentilator:Controller", "1.51-group-controllers.html#zonehvacenergyrecoveryventilatorcontroller"}, + {"OS:AirLoopHVAC:ZoneMixer", "1.37-group-air-path.html#airloophvaczonemixer"}, + {"OS:AirLoopHVAC:ZoneSplitter", "1.37-group-air-path.html#airloophvaczonesplitter"}, + {"OS:AirLoopHVAC:ReturnPlenum", "1.37-group-air-path.html#airloophvacreturnplenum"}, + {"OS:AirLoopHVAC:SupplyPlenum", "1.37-group-air-path.html#airloophvacsupplyplenum"}, // Setpoint Managers - {"OS:SetpointManager:Scheduled", "group-setpoint-managers.html#setpointmanagerscheduled"}, - {"OS:SetpointManager:Scheduled:DualSetpoint", "group-setpoint-managers.html#setpointmanagerscheduleddualsetpoint"}, - {"OS:SetpointManager:MixedAir", "group-setpoint-managers.html#setpointmanagermixedair"}, - {"OS:SetpointManager:OutdoorAirReset", "group-setpoint-managers.html#setpointmanageroutdoorairreset"}, - {"OS:SetpointManager:SingleZone:Reheat", "group-setpoint-managers.html#setpointmanagersinglezonereheat"}, - {"OS:SetpointManager:SingleZone:Heating", "group-setpoint-managers.html#setpointmanagersinglezoneheating"}, - {"OS:SetpointManager:SingleZone:Cooling", "group-setpoint-managers.html#setpointmanagersinglezonecooling"}, - {"OS:SetpointManager:Warmest", "group-setpoint-managers.html#setpointmanagerwarmest"}, - {"OS:SetpointManager:Coldest", "group-setpoint-managers.html#setpointmanagercoldest"}, - {"OS:SetpointManager:FollowOutdoorAirTemperature", "group-setpoint-managers.html#setpointmanagerfollowoutdoorairtemperature"}, - {"OS:SetpointManager:FollowGroundTemperature", "group-setpoint-managers.html#setpointmanagerfollowgroundtemperature"}, - {"OS:SetpointManager:CondenserEnteringReset", "group-setpoint-managers.html#setpointmanagercondenserenteringreset"}, - {"OS:SetpointManager:WarmestTemperatureFlow", "group-setpoint-managers.html#setpointmanagerwarmesttemperatureflow"}, - {"OS:SetpointManager:OutdoorAirPretreat", "group-setpoint-managers.html#setpointmanageroutdoorairpretreat"}, - {"OS:SetpointManager:MultiZone:Heating:Average", "group-setpoint-managers.html#setpointmanagermultizoneheatingaverage"}, - {"OS:SetpointManager:MultiZone:Cooling:Average", "group-setpoint-managers.html#setpointmanagermultizonecoolingaverage"}, - {"OS:SetpointManager:FollowSystemNodeTemperature", "group-setpoint-managers.html#setpointmanagerfollowsystemnodetemperature"}, - {"OS:SetpointManager:MultiZone:Humidity:Maximum", "group-setpoint-managers.html#setpointmanagermultizonehumiditymaximum"}, - {"OS:SetpointManager:MultiZone:Humidity:Minimum", "group-setpoint-managers.html#setpointmanagermultizonehumidityminimum"}, - {"OS:SetpointManager:MultiZone:MaximumHumidity:Average", "group-setpoint-managers.html#setpointmanagermultizonemaximumhumidityaverage"}, - {"OS:SetpointManager:MultiZone:MinimumHumidity:Average", "group-setpoint-managers.html#setpointmanagermultizoneminimumhumidityaverage"}, - {"OS:SetpointManager:SingleZone:Humidity:Maximum", "group-setpoint-managers.html#setpointmanagersinglezonehumiditymaximum"}, - {"OS:SetpointManager:SingleZone:Humidity:Minimum", "group-setpoint-managers.html#setpointmanagersinglezonehumidityminimum"}, - {"OS:SetpointManager:SingleZone:OneStageCooling", "group-setpoint-managers.html#setpointmanagersinglezoneonestagecooling"}, - {"OS:SetpointManager:SingleZone:OneStageHeating", "group-setpoint-managers.html#setpointmanagersinglezoneonestageheating"}, - {"OS:SetpointManager:SystemNodeReset:Humidity", "group-setpoint-managers.html#setpointmanagersystemnoderesethumidity"}, - {"OS:SetpointManager:SystemNodeReset:Temperature", "group-setpoint-managers.html#setpointmanagersystemnoderesettemperature"}, + {"OS:SetpointManager:Scheduled", "1.50-group-setpoint-managers.html#setpointmanagerscheduled"}, + {"OS:SetpointManager:Scheduled:DualSetpoint", "1.50-group-setpoint-managers.html#setpointmanagerscheduleddualsetpoint"}, + {"OS:SetpointManager:MixedAir", "1.50-group-setpoint-managers.html#setpointmanagermixedair"}, + {"OS:SetpointManager:OutdoorAirReset", "1.50-group-setpoint-managers.html#setpointmanageroutdoorairreset"}, + {"OS:SetpointManager:SingleZone:Reheat", "1.50-group-setpoint-managers.html#setpointmanagersinglezonereheat"}, + {"OS:SetpointManager:SingleZone:Heating", "1.50-group-setpoint-managers.html#setpointmanagersinglezoneheating"}, + {"OS:SetpointManager:SingleZone:Cooling", "1.50-group-setpoint-managers.html#setpointmanagersinglezonecooling"}, + {"OS:SetpointManager:Warmest", "1.50-group-setpoint-managers.html#setpointmanagerwarmest"}, + {"OS:SetpointManager:Coldest", "1.50-group-setpoint-managers.html#setpointmanagercoldest"}, + {"OS:SetpointManager:FollowOutdoorAirTemperature", "1.50-group-setpoint-managers.html#setpointmanagerfollowoutdoorairtemperature"}, + {"OS:SetpointManager:FollowGroundTemperature", "1.50-group-setpoint-managers.html#setpointmanagerfollowgroundtemperature"}, + {"OS:SetpointManager:CondenserEnteringReset", "1.50-group-setpoint-managers.html#setpointmanagercondenserenteringreset"}, + {"OS:SetpointManager:WarmestTemperatureFlow", "1.50-group-setpoint-managers.html#setpointmanagerwarmesttemperatureflow"}, + {"OS:SetpointManager:OutdoorAirPretreat", "1.50-group-setpoint-managers.html#setpointmanageroutdoorairpretreat"}, + {"OS:SetpointManager:MultiZone:Heating:Average", "1.50-group-setpoint-managers.html#setpointmanagermultizoneheatingaverage"}, + {"OS:SetpointManager:MultiZone:Cooling:Average", "1.50-group-setpoint-managers.html#setpointmanagermultizonecoolingaverage"}, + {"OS:SetpointManager:FollowSystemNodeTemperature", "1.50-group-setpoint-managers.html#setpointmanagerfollowsystemnodetemperature"}, + {"OS:SetpointManager:MultiZone:Humidity:Maximum", "1.50-group-setpoint-managers.html#setpointmanagermultizonehumiditymaximum"}, + {"OS:SetpointManager:MultiZone:Humidity:Minimum", "1.50-group-setpoint-managers.html#setpointmanagermultizonehumidityminimum"}, + {"OS:SetpointManager:MultiZone:MaximumHumidity:Average", "1.50-group-setpoint-managers.html#setpointmanagermultizonemaximumhumidityaverage"}, + {"OS:SetpointManager:MultiZone:MinimumHumidity:Average", "1.50-group-setpoint-managers.html#setpointmanagermultizoneminimumhumidityaverage"}, + {"OS:SetpointManager:SingleZone:Humidity:Maximum", "1.50-group-setpoint-managers.html#setpointmanagersinglezonehumiditymaximum"}, + {"OS:SetpointManager:SingleZone:Humidity:Minimum", "1.50-group-setpoint-managers.html#setpointmanagersinglezonehumidityminimum"}, + {"OS:SetpointManager:SingleZone:OneStageCooling", "1.50-group-setpoint-managers.html#setpointmanagersinglezoneonestagecooling"}, + {"OS:SetpointManager:SingleZone:OneStageHeating", "1.50-group-setpoint-managers.html#setpointmanagersinglezoneonestageheating"}, + {"OS:SetpointManager:SystemNodeReset:Humidity", "1.50-group-setpoint-managers.html#setpointmanagersystemnoderesethumidity"}, + {"OS:SetpointManager:SystemNodeReset:Temperature", "1.50-group-setpoint-managers.html#setpointmanagersystemnoderesettemperature"}, // Pumps - {"OS:Pump:VariableSpeed", "group-pumps.html#pumpvariablespeed"}, - {"OS:Pump:ConstantSpeed", "group-pumps.html#pumpconstantspeed"}, - {"OS:HeaderedPumps:VariableSpeed", "group-pumps.html#headeredpumpsvariablespeed"}, - {"OS:HeaderedPumps:ConstantSpeed", "group-pumps.html#headeredpumpsconstantspeed"}, + {"OS:Pump:VariableSpeed", "1.40-group-pumps.html#pumpvariablespeed"}, + {"OS:Pump:ConstantSpeed", "1.40-group-pumps.html#pumpconstantspeed"}, + {"OS:HeaderedPumps:VariableSpeed", "1.40-group-pumps.html#headeredpumpsvariablespeed"}, + {"OS:HeaderedPumps:ConstantSpeed", "1.40-group-pumps.html#headeredpumpsconstantspeed"}, // Solar Collectors - {"OS:SolarCollector:FlatPlate:Water", "group-solar-collectors.html#solarcollectorflatplatewater"}, - {"OS:SolarCollector:IntegralCollectorStorage", "group-solar-collectors.html#solarcollectorintegralcollectorstorage"}, - {"OS:SolarCollector:UnglazedTranspired", "group-solar-collectors.html#solarcollectorunglazedtranspired"}, - {"OS:SolarCollector:FlatPlate:PhotovoltaicThermal", "group-solar-collectors.html#solarcollectorflatplatephotovoltaicthermal"}, - {"OS:SolarCollectorPerformance:FlatPlate", "group-solar-collectors.html#solarcollectorperformanceflatplate"}, - {"OS:SolarCollectorPerformance:IntegralCollectorStorage", "group-solar-collectors.html#solarcollectorperformanceintegralcollectorstorage"}, + {"OS:SolarCollector:FlatPlate:Water", "1.39-group-solar-collectors.html#solarcollectorflatplatewater"}, + {"OS:SolarCollector:IntegralCollectorStorage", "1.39-group-solar-collectors.html#solarcollectorintegralcollectorstorage"}, + {"OS:SolarCollector:UnglazedTranspired", "1.39-group-solar-collectors.html#solarcollectorunglazedtranspired"}, + {"OS:SolarCollector:FlatPlate:PhotovoltaicThermal", "1.39-group-solar-collectors.html#solarcollectorflatplatephotovoltaicthermal"}, + {"OS:SolarCollectorPerformance:FlatPlate", "1.39-group-solar-collectors.html#solarcollectorperformanceflatplate"}, + {"OS:SolarCollectorPerformance:IntegralCollectorStorage", "1.39-group-solar-collectors.html#solarcollectorperformanceintegralcollectorstorage"}, // Plant Heating and Cooling Equipment - {"OS:Boiler:HotWater", "group-plant-equipment.html#boilerhotwater"}, - {"OS:Boiler:Steam", "group-plant-equipment.html#boilersteam"}, - {"OS:Chiller:Electric:EIR", "group-plant-equipment.html#chillerelectriceir"}, - {"OS:Chiller:Electric:ReformulatedEIR", "group-plant-equipment.html#chillerelectricreformulatedeir"}, - {"OS:Chiller:Absorption", "group-plant-equipment.html#chillerabsorption"}, - {"OS:Chiller:Absorption:Indirect", "group-plant-equipment.html#chillerabsorptionindirect"}, - {"OS:Chiller:Absorption:Direct", "group-plant-equipment.html#chillerabsorption"}, - {"OS:ChillerHeater:Absorption:DirectFired", "group-plant-equipment.html#chillerheaterabsorptiondirectfired"}, - {"OS:DistrictCooling", "group-plant-equipment.html#districtcooling"}, - {"OS:DistrictHeating", "group-plant-equipment.html#districtheating"}, - {"OS:DistrictHeating:Water", "group-plant-equipment.html#districtheating"}, - {"OS:HeatPump:PlantLoop:EIR:Cooling", "group-plant-equipment.html#plhp_eir_cooling"}, - {"OS:HeatPump:PlantLoop:EIR:Heating", "group-plant-equipment.html#plhp_eir_heating"}, - {"OS:HeatPump:WaterToWater:EquationFit:Cooling", "group-plant-equipment.html#heatpumpwatertowaterequationfitcooling"}, - {"OS:HeatPump:WaterToWater:EquationFit:Heating", "group-plant-equipment.html#heatpumpwatertowaterequationfitheating"}, - {"OS:HeatPump:AirToWater:FuelFired:Cooling", "group-plant-equipment.html#plhp_fuelfired"}, - {"OS:HeatPump:AirToWater:FuelFired:Heating", "group-plant-equipment.html#plhp_fuelfired"}, - {"OS:CentralHeatPumpSystem", "group-plant-equipment.html#centralheatpumpsystem"}, - {"OS:CentralHeatPumpSystem:Module", "group-plant-equipment.html#centralheatpumpsystem"}, - {"OS:ChillerHeaterPerformance:Electric:EIR", "group-plant-equipment.html#chillerheaterperformancelectriceir"}, - {"OS:PlantComponent:TemperatureSource", "group-plant-equipment.html#plantcomponenttemperaturesource"}, - {"OS:PlantComponent:UserDefined", "group-user-defined-hvac-and-plant-component.html#plantcomponentuserdefined"}, + {"OS:Boiler:HotWater", "1.23-group-plant-equipment.html#boilerhotwater"}, + {"OS:Boiler:Steam", "1.23-group-plant-equipment.html#boilersteam"}, + {"OS:Chiller:Electric:EIR", "1.23-group-plant-equipment.html#chillerelectriceir"}, + {"OS:Chiller:Electric:ReformulatedEIR", "1.23-group-plant-equipment.html#chillerelectricreformulatedeir"}, + {"OS:Chiller:Absorption", "1.23-group-plant-equipment.html#chillerabsorption"}, + {"OS:Chiller:Absorption:Indirect", "1.23-group-plant-equipment.html#chillerabsorptionindirect"}, + {"OS:Chiller:Absorption:Direct", "1.23-group-plant-equipment.html#chillerabsorption"}, + {"OS:ChillerHeater:Absorption:DirectFired", "1.23-group-plant-equipment.html#chillerheaterabsorptiondirectfired"}, + {"OS:DistrictCooling", "1.23-group-plant-equipment.html#districtcooling"}, + {"OS:DistrictHeating", "1.23-group-plant-equipment.html#districtheating"}, + {"OS:DistrictHeating:Water", "1.23-group-plant-equipment.html#districtheating"}, + {"OS:HeatPump:PlantLoop:EIR:Cooling", "1.23-group-plant-equipment.html#plhp_eir_cooling"}, + {"OS:HeatPump:PlantLoop:EIR:Heating", "1.23-group-plant-equipment.html#plhp_eir_heating"}, + {"OS:HeatPump:WaterToWater:EquationFit:Cooling", "1.23-group-plant-equipment.html#heatpumpwatertowaterequationfitcooling"}, + {"OS:HeatPump:WaterToWater:EquationFit:Heating", "1.23-group-plant-equipment.html#heatpumpwatertowaterequationfitheating"}, + {"OS:HeatPump:AirToWater:FuelFired:Cooling", "1.23-group-plant-equipment.html#plhp_fuelfired"}, + {"OS:HeatPump:AirToWater:FuelFired:Heating", "1.23-group-plant-equipment.html#plhp_fuelfired"}, + {"OS:CentralHeatPumpSystem", "1.23-group-plant-equipment.html#centralheatpumpsystem"}, + {"OS:CentralHeatPumpSystem:Module", "1.23-group-plant-equipment.html#centralheatpumpsystem"}, + {"OS:ChillerHeaterPerformance:Electric:EIR", "1.23-group-plant-equipment.html#chillerheaterperformancelectriceir"}, + {"OS:PlantComponent:TemperatureSource", "1.23-group-plant-equipment.html#plantcomponenttemperaturesource"}, + {"OS:PlantComponent:UserDefined", "1.48-group-user-defined-hvac-and-plant-component-models.html#plantcomponentuserdefined"}, // Cooling Towers and Fluid Coolers - {"OS:CoolingTower:SingleSpeed", "group-condenser-equipment.html#coolingtowersinglespeed"}, - {"OS:CoolingTower:TwoSpeed", "group-condenser-equipment.html#coolingtowertwospeed"}, - {"OS:CoolingTower:VariableSpeed", "group-condenser-equipment.html#coolingtowervariablespeed"}, - {"OS:CoolingTower:VariableSpeed:Merkel", "group-condenser-equipment.html#coolingtowervariablespeedmerkel"}, - {"OS:CoolingTowerPerformance:CoolTools", "group-condenser-equipment.html#coolingtowerperformancecooltools"}, - {"OS:CoolingTowerPerformance:YorkCalc", "group-condenser-equipment.html#coolingtowerperformanceyorkcalc"}, - {"OS:EvaporativeFluidCooler:SingleSpeed", "group-condenser-equipment.html#evaporativefluidcoolersinglespeed"}, - {"OS:EvaporativeFluidCooler:TwoSpeed", "group-condenser-equipment.html#evaporativefluidcoolertwospeed"}, - {"OS:FluidCooler:SingleSpeed", "group-condenser-equipment.html#fluidcoolersinglespeed"}, - {"OS:FluidCooler:TwoSpeed", "group-condenser-equipment.html#fluidcoolertwospeed"}, + {"OS:CoolingTower:SingleSpeed", "1.25-group-condenser-equipment.html#coolingtowersinglespeed"}, + {"OS:CoolingTower:TwoSpeed", "1.25-group-condenser-equipment.html#coolingtowertwospeed"}, + {"OS:CoolingTower:VariableSpeed", "1.25-group-condenser-equipment.html#coolingtowervariablespeed"}, + {"OS:CoolingTower:VariableSpeed:Merkel", "1.25-group-condenser-equipment.html#coolingtowervariablespeedmerkel"}, + {"OS:CoolingTowerPerformance:CoolTools", "1.25-group-condenser-equipment.html#coolingtowerperformancecooltools"}, + {"OS:CoolingTowerPerformance:YorkCalc", "1.25-group-condenser-equipment.html#coolingtowerperformanceyorkcalc"}, + {"OS:EvaporativeFluidCooler:SingleSpeed", "1.25-group-condenser-equipment.html#evaporativefluidcoolersinglespeed"}, + {"OS:EvaporativeFluidCooler:TwoSpeed", "1.25-group-condenser-equipment.html#evaporativefluidcoolertwospeed"}, + {"OS:FluidCooler:SingleSpeed", "1.25-group-condenser-equipment.html#fluidcoolersinglespeed"}, + {"OS:FluidCooler:TwoSpeed", "1.25-group-condenser-equipment.html#fluidcoolertwospeed"}, // Heat Recovery - {"OS:HeatExchanger:AirToAir:SensibleAndLatent", "group-heat-recovery.html#heatexchangerairtoairsensibleandlatent"}, - {"OS:HeatExchanger:FluidToFluid", "group-condenser-equipment.html#heatexchangerfluidtofluid"}, - {"OS:HeatExchanger:Desiccant:BalancedFlow", "group-heat-recovery.html#heatexchangerdesiccantbalancedflow"}, + {"OS:HeatExchanger:AirToAir:SensibleAndLatent", "1.53-group-heat-recovery.html#heatexchangerairtoairsensibleandlatent"}, + {"OS:HeatExchanger:FluidToFluid", "1.25-group-condenser-equipment.html#heatexchangerfluidtofluid"}, + {"OS:HeatExchanger:Desiccant:BalancedFlow", "1.53-group-heat-recovery.html#heatexchangerdesiccantbalancedflow"}, // Condenser Equipment and Ground Heat Exchangers - {"OS:GroundHeatExchanger:Vertical", "group-condenser-equipment.html#groundheatexchangersystem"}, - {"OS:GroundHeatExchanger:HorizontalTrench", "group-condenser-equipment.html#groundheatexchangerhorizontaltrench"}, - {"OS:GroundHeatExchanger:Slinky", "group-condenser-equipment.html#groundheatexchangerslinky"}, + {"OS:GroundHeatExchanger:Vertical", "1.25-group-condenser-equipment.html#groundheatexchangersystem"}, + {"OS:GroundHeatExchanger:HorizontalTrench", "1.25-group-condenser-equipment.html#groundheatexchangerhorizontaltrench"}, + {"OS:GroundHeatExchanger:Slinky", "1.25-group-condenser-equipment.html#groundheatexchangerslinky"}, // Water Heaters and Thermal Storage - {"OS:WaterHeater:Mixed", "group-water-heaters.html#waterheatermixed"}, - {"OS:WaterHeater:Stratified", "group-water-heaters.html#waterheaterstratified"}, - {"OS:WaterHeater:HeatPump", "group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, - {"OS:WaterHeater:HeatPump:PumpedCondenser", "group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, - {"OS:WaterHeater:HeatPump:WrappedCondenser", "group-water-heaters.html#waterheaterheatpumpwrappedcondenser"}, - {"OS:WaterHeater:Sizing", "group-water-heaters.html#waterheatersizing"}, - {"OS:ThermalStorage:Ice:Detailed", "group-water-heaters.html#thermalstorageicedetailed"}, - {"OS:ThermalStorage:ChilledWater:Stratified", "group-water-heaters.html#thermalstoragechilledwaterstratified"}, + {"OS:WaterHeater:Mixed", "1.24-group-water-heaters.html#waterheatermixed"}, + {"OS:WaterHeater:Stratified", "1.24-group-water-heaters.html#waterheaterstratified"}, + {"OS:WaterHeater:HeatPump", "1.24-group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, + {"OS:WaterHeater:HeatPump:PumpedCondenser", "1.24-group-water-heaters.html#waterheaterheatpumppumpedcondenser"}, + {"OS:WaterHeater:HeatPump:WrappedCondenser", "1.24-group-water-heaters.html#waterheaterheatpumpwrappedcondenser"}, + {"OS:WaterHeater:Sizing", "1.24-group-water-heaters.html#waterheatersizing"}, + {"OS:ThermalStorage:Ice:Detailed", "1.24-group-water-heaters.html#thermalstorageicedetailed"}, + {"OS:ThermalStorage:ChilledWater:Stratified", "1.24-group-water-heaters.html#thermalstoragechilledwaterstratified"}, // Water Systems - {"OS:WaterUse:Equipment", "group-water-systems.html#wateruseequipment"}, - {"OS:WaterUse:Connections", "group-water-systems.html#wateruseconnections"}, + {"OS:WaterUse:Equipment", "1.56-group-water-systems.html#wateruseequipment"}, + {"OS:WaterUse:Connections", "1.56-group-water-systems.html#wateruseconnections"}, // Refrigeration - {"OS:Refrigeration:AirChiller", "group-refrigeration.html#refrigerationairchiller"}, - {"OS:Refrigeration:Case", "group-refrigeration.html#refrigerationcase"}, - {"OS:Refrigeration:Compressor", "group-refrigeration.html#refrigerationcompressor"}, - {"OS:Refrigeration:CompressorRack", "group-refrigeration.html#refrigerationcompressorrack"}, - {"OS:Refrigeration:Condenser:AirCooled", "group-refrigeration.html#refrigerationcondenseraircooled"}, - {"OS:Refrigeration:Condenser:Cascade", "group-refrigeration.html#refrigerationcondensercascade"}, - {"OS:Refrigeration:Condenser:EvaporativeCooled", "group-refrigeration.html#refrigerationcondenserevaporativecooled"}, - {"OS:Refrigeration:Condenser:WaterCooled", "group-refrigeration.html#refrigerationcondenserwatercooled"}, - {"OS:Refrigeration:DefrostCycleParameters", "group-refrigeration.html#refrigerationwalkin"}, - {"OS:Refrigeration:GasCooler:AirCooled", "group-refrigeration.html#refrigerationgascooleraircooled"}, - {"OS:Refrigeration:SecondarySystem", "group-refrigeration.html#refrigerationsecondarysystem"}, - {"OS:Refrigeration:Subcooler:LiquidSuction", "group-refrigeration.html#refrigerationsubcooler"}, - {"OS:Refrigeration:Subcooler:Mechanical", "group-refrigeration.html#refrigerationsubcooler"}, - {"OS:Refrigeration:System", "group-refrigeration.html#refrigerationsystem"}, - {"OS:Refrigeration:TranscriticalSystem", "group-refrigeration.html#refrigerationtranscriticalsystem"}, - {"OS:Refrigeration:WalkIn", "group-refrigeration.html#refrigerationwalkin"}, - {"OS:Refrigeration:WalkIn:ZoneBoundary", "group-refrigeration.html#refrigerationwalkin"}, + {"OS:Refrigeration:AirChiller", "1.35-group-refrigeration.html#refrigerationairchiller"}, + {"OS:Refrigeration:Case", "1.35-group-refrigeration.html#refrigerationcase"}, + {"OS:Refrigeration:Compressor", "1.35-group-refrigeration.html#refrigerationcompressor"}, + {"OS:Refrigeration:CompressorRack", "1.35-group-refrigeration.html#refrigerationcompressorrack"}, + {"OS:Refrigeration:Condenser:AirCooled", "1.35-group-refrigeration.html#refrigerationcondenseraircooled"}, + {"OS:Refrigeration:Condenser:Cascade", "1.35-group-refrigeration.html#refrigerationcondensercascade"}, + {"OS:Refrigeration:Condenser:EvaporativeCooled", "1.35-group-refrigeration.html#refrigerationcondenserevaporativecooled"}, + {"OS:Refrigeration:Condenser:WaterCooled", "1.35-group-refrigeration.html#refrigerationcondenserwatercooled"}, + {"OS:Refrigeration:DefrostCycleParameters", "1.35-group-refrigeration.html#refrigerationwalkin"}, + {"OS:Refrigeration:GasCooler:AirCooled", "1.35-group-refrigeration.html#refrigerationgascooleraircooled"}, + {"OS:Refrigeration:SecondarySystem", "1.35-group-refrigeration.html#refrigerationsecondarysystem"}, + {"OS:Refrigeration:Subcooler:LiquidSuction", "1.35-group-refrigeration.html#refrigerationsubcooler"}, + {"OS:Refrigeration:Subcooler:Mechanical", "1.35-group-refrigeration.html#refrigerationsubcooler"}, + {"OS:Refrigeration:System", "1.35-group-refrigeration.html#refrigerationsystem"}, + {"OS:Refrigeration:TranscriticalSystem", "1.35-group-refrigeration.html#refrigerationtranscriticalsystem"}, + {"OS:Refrigeration:WalkIn", "1.35-group-refrigeration.html#refrigerationwalkin"}, + {"OS:Refrigeration:WalkIn:ZoneBoundary", "1.35-group-refrigeration.html#refrigerationwalkin"}, // Node / Branch Management - {"OS:Pipe:Adiabatic", "group-node-branch-management.html#pipeadiabatic"}, - {"OS:Pipe:Indoor", "group-node-branch-management.html#pipeindoor"}, - {"OS:Pipe:Outdoor", "group-node-branch-management.html#pipeoutdoor"}, - {"OS:Duct", "group-node-branch-management.html#duct"}, + {"OS:Pipe:Adiabatic", "1.20-group-node-branch-management.html#pipeadiabatic"}, + {"OS:Pipe:Indoor", "1.20-group-node-branch-management.html#pipeindoor"}, + {"OS:Pipe:Outdoor", "1.20-group-node-branch-management.html#pipeoutdoor"}, + {"OS:Duct", "1.20-group-node-branch-management.html#duct"}, // Plant / Condenser Control - {"OS:PlantLoop", "group-plant-condenser-loops.html#plantloop"}, - {"OS:CondenserLoop", "group-plant-condenser-loops.html#condenserloop"}, - {"OS:PlantEquipmentList", "group-plant-condenser-control.html#plantequipmentlist"}, - {"OS:PlantEquipmentOperation:CoolingLoad", "group-plant-condenser-control.html#plantequipmentoperationcoolingload"}, - {"OS:PlantEquipmentOperation:HeatingLoad", "group-plant-condenser-control.html#plantequipmentoperationheatingload"}, - {"OS:PlantEquipmentOperation:ComponentSetpoint", "group-plant-condenser-control.html#plantequipmentoperationcomponentsetpoint"}, - {"OS:PlantEquipmentOperation:OutdoorDryBulb", "group-plant-condenser-control.html#plantequipmentoperationoutdoordrybulb"}, - {"OS:PlantEquipmentOperation:OutdoorWetBulb", "group-plant-condenser-control.html#plantequipmentoperationoutdoorwetbulb"}, - {"OS:PlantEquipmentOperation:ThermalEnergyStorage", "group-plant-condenser-control.html#plantequipmentoperationthermalenergystorage"}, - {"OS:PlantEquipmentOperation:Uncontrolled", "group-plant-condenser-control.html#plantequipmentoperationuncontrolled"}, - {"OS:TemperingValve", "group-plant-condenser-flow-control.html#temperingvalve"}, - {"OS:LoadProfile:Plant", "group-non-zone-equipment.html#loadprofileplant"}, - {"OS:AvailabilityManagerAssignmentList", "group-air-distribution.html#availabilitymanagerassignmentlist"}, - {"OS:AvailabilityManager:Scheduled", "group-system-availability-managers.html#availabilitymanagerscheduled"}, - {"OS:AvailabilityManager:ScheduledOn", "group-system-availability-managers.html#availabilitymanagerscheduledon"}, - {"OS:AvailabilityManager:ScheduledOff", "group-system-availability-managers.html#availabilitymanagerscheduledoff"}, - {"OS:AvailabilityManager:NightCycle", "group-system-availability-managers.html#availabilitymanagernightcycle"}, - {"OS:AvailabilityManager:DifferentialThermostat", "group-system-availability-managers.html#availabilitymanagerdifferentialthermostat"}, - {"OS:AvailabilityManager:OptimumStart", "group-system-availability-managers.html#availabilitymanageroptimumstart"}, - {"OS:AvailabilityManager:NightVentilation", "group-system-availability-managers.html#availabilitymanagernightventilation"}, - {"OS:AvailabilityManager:HybridVentilation", "group-system-availability-managers.html#availabilitymanagerhybridventilation"}, - {"OS:AvailabilityManager:LowTemperatureTurnOn", "group-system-availability-managers.html#availabilitymanagerlowtemperatureturnon"}, - {"OS:AvailabilityManager:HighTemperatureTurnOff", "group-system-availability-managers.html#availabilitymanagerhightemperatureturnoff"}, - {"OS:AvailabilityManager:LowTemperatureTurnOff", "group-system-availability-managers.html#availabilitymanagerlowtemperatureturnoff"}, - {"OS:AvailabilityManager:HighTemperatureTurnOn", "group-system-availability-managers.html#availabilitymanagerhightemperatureturnon"}, + {"OS:PlantLoop", "1.21-group-plant-condenser-loops.html#plantloop"}, + {"OS:CondenserLoop", "1.21-group-plant-condenser-loops.html#condenserloop"}, + {"OS:PlantEquipmentList", "1.22-group-plant-condenser-control.html#plantequipmentlist"}, + {"OS:PlantEquipmentOperation:CoolingLoad", "1.22-group-plant-condenser-control.html#plantequipmentoperationcoolingload"}, + {"OS:PlantEquipmentOperation:HeatingLoad", "1.22-group-plant-condenser-control.html#plantequipmentoperationheatingload"}, + {"OS:PlantEquipmentOperation:ComponentSetpoint", "1.22-group-plant-condenser-control.html#plantequipmentoperationcomponentsetpoint"}, + {"OS:PlantEquipmentOperation:OutdoorDryBulb", "1.22-group-plant-condenser-control.html#plantequipmentoperationoutdoordrybulb"}, + {"OS:PlantEquipmentOperation:OutdoorWetBulb", "1.22-group-plant-condenser-control.html#plantequipmentoperationoutdoorwetbulb"}, + {"OS:PlantEquipmentOperation:ThermalEnergyStorage", "1.22-group-plant-condenser-control.html#plantequipmentoperationthermalenergystorage"}, + {"OS:PlantEquipmentOperation:Uncontrolled", "1.22-group-plant-condenser-control.html#plantequipmentoperationuncontrolled"}, + {"OS:TemperingValve", "1.41-plant-condenser-flow-control.html#temperingvalve"}, + {"OS:LoadProfile:Plant", "1.38-group-non-zone-equipment.html#loadprofileplant"}, + {"OS:AvailabilityManagerAssignmentList", "1.26-group-air-distribution.html#availabilitymanagerassignmentlist"}, + {"OS:AvailabilityManager:Scheduled", "1.49-group-system-availability-managers.html#availabilitymanagerscheduled"}, + {"OS:AvailabilityManager:ScheduledOn", "1.49-group-system-availability-managers.html#availabilitymanagerscheduledon"}, + {"OS:AvailabilityManager:ScheduledOff", "1.49-group-system-availability-managers.html#availabilitymanagerscheduledoff"}, + {"OS:AvailabilityManager:NightCycle", "1.49-group-system-availability-managers.html#availabilitymanagernightcycle"}, + {"OS:AvailabilityManager:DifferentialThermostat", "1.49-group-system-availability-managers.html#availabilitymanagerdifferentialthermostat"}, + {"OS:AvailabilityManager:OptimumStart", "1.49-group-system-availability-managers.html#availabilitymanageroptimumstart"}, + {"OS:AvailabilityManager:NightVentilation", "1.49-group-system-availability-managers.html#availabilitymanagernightventilation"}, + {"OS:AvailabilityManager:HybridVentilation", "1.49-group-system-availability-managers.html#availabilitymanagerhybridventilation"}, + {"OS:AvailabilityManager:LowTemperatureTurnOn", "1.49-group-system-availability-managers.html#availabilitymanagerlowtemperatureturnon"}, + {"OS:AvailabilityManager:HighTemperatureTurnOff", "1.49-group-system-availability-managers.html#availabilitymanagerhightemperatureturnoff"}, + {"OS:AvailabilityManager:LowTemperatureTurnOff", "1.49-group-system-availability-managers.html#availabilitymanagerlowtemperatureturnoff"}, + {"OS:AvailabilityManager:HighTemperatureTurnOn", "1.49-group-system-availability-managers.html#availabilitymanagerhightemperatureturnon"}, // Energy Management System - {"OS:EnergyManagementSystem:Sensor", "group-energy-management-system-ems.html#energymanagementsystemsensor"}, - {"OS:EnergyManagementSystem:Actuator", "group-energy-management-system-ems.html#energymanagementsystemactuator"}, - {"OS:EnergyManagementSystem:Program", "group-energy-management-system-ems.html#energymanagementsystemprogram"}, - {"OS:EnergyManagementSystem:ProgramCallingManager", "group-energy-management-system-ems.html#energymanagementsystemprogramcallingmanager"}, - {"OS:EnergyManagementSystem:GlobalVariable", "group-energy-management-system-ems.html#energymanagementsystemglobalvariable"}, - {"OS:EnergyManagementSystem:OutputVariable", "group-energy-management-system-ems.html#energymanagementsystemoutputvariable"}, - {"OS:EnergyManagementSystem:TrendVariable", "group-energy-management-system-ems.html#energymanagementsystemtrendvariable"}, - {"OS:EnergyManagementSystem:InternalVariable", "group-energy-management-system-ems.html#energymanagementsysteminternalvariable"}, - {"OS:EnergyManagementSystem:ConstructionIndexVariable", "group-energy-management-system-ems.html#energymanagementsystemconstructionindexvariable"}, + {"OS:EnergyManagementSystem:Sensor", "1.45-group-energy-management-system-ems.html#energymanagementsystemsensor"}, + {"OS:EnergyManagementSystem:Actuator", "1.45-group-energy-management-system-ems.html#energymanagementsystemactuator"}, + {"OS:EnergyManagementSystem:Program", "1.45-group-energy-management-system-ems.html#energymanagementsystemprogram"}, + {"OS:EnergyManagementSystem:ProgramCallingManager", "1.45-group-energy-management-system-ems.html#energymanagementsystemprogramcallingmanager"}, + {"OS:EnergyManagementSystem:GlobalVariable", "1.45-group-energy-management-system-ems.html#energymanagementsystemglobalvariable"}, + {"OS:EnergyManagementSystem:OutputVariable", "1.45-group-energy-management-system-ems.html#energymanagementsystemoutputvariable"}, + {"OS:EnergyManagementSystem:TrendVariable", "1.45-group-energy-management-system-ems.html#energymanagementsystemtrendvariable"}, + {"OS:EnergyManagementSystem:InternalVariable", "1.45-group-energy-management-system-ems.html#energymanagementsysteminternalvariable"}, + {"OS:EnergyManagementSystem:ConstructionIndexVariable", "1.45-group-energy-management-system-ems.html#energymanagementsystemconstructionindexvariable"}, // Performance Curves - {"OS:Curve:Linear", "group-performance-curves.html#curvelinear"}, - {"OS:Curve:Quadratic", "group-performance-curves.html#curvequadratic"}, - {"OS:Curve:Cubic", "group-performance-curves.html#curvecubic"}, - {"OS:Curve:Quartic", "group-performance-curves.html#curvequartic"}, - {"OS:Curve:Exponent", "group-performance-curves.html#curveexponent"}, - {"OS:Curve:Bicubic", "group-performance-curves.html#curvebicubic"}, - {"OS:Curve:Biquadratic", "group-performance-curves.html#curvebiquadratic"}, - {"OS:Curve:QuadraticLinear", "group-performance-curves.html#curvequadraticlinear"}, - {"OS:Curve:CubicLinear", "group-performance-curves.html#curvecubiclinear"}, - {"OS:Curve:Triquadratic", "group-performance-curves.html#curvetriquadratic"}, - {"OS:Curve:FanPressureRise", "group-performance-curves.html#curvefanpressurerise"}, - {"OS:Curve:ExponentialDecay", "group-performance-curves.html#curveexponentialdecay"}, - {"OS:Curve:ExponentialSkewNormal", "group-performance-curves.html#curveexponentialskewnormal"}, - {"OS:Curve:Sigmoid", "group-performance-curves.html#curvesigmoid"}, - {"OS:Curve:QuadLinear", "group-performance-curves.html#curvequadlinear"}, - {"OS:Curve:QuintLinear", "group-performance-curves.html#curvequintlinear"}, - {"OS:Curve:RectangularHyperbola1", "group-performance-curves.html#curverectangularhyperbola1"}, - {"OS:Curve:RectangularHyperbola2", "group-performance-curves.html#curverectangularhyperbola2"}, - {"OS:Table:IndependentVariable", "group-performance-tables.html#tableindependentvariable"}, - {"OS:Table:IndependentVariableList", "group-performance-tables.html#tableindependentvariablelist"}, - {"OS:Table:Lookup", "group-performance-tables.html#tablelookup"}, + {"OS:Curve:Linear", "1.58-group---performance-curves.html#curvelinear"}, + {"OS:Curve:Quadratic", "1.58-group---performance-curves.html#curvequadratic"}, + {"OS:Curve:Cubic", "1.58-group---performance-curves.html#curvecubic"}, + {"OS:Curve:Quartic", "1.58-group---performance-curves.html#curvequartic"}, + {"OS:Curve:Exponent", "1.58-group---performance-curves.html#curveexponent"}, + {"OS:Curve:Bicubic", "1.58-group---performance-curves.html#curvebicubic"}, + {"OS:Curve:Biquadratic", "1.58-group---performance-curves.html#curvebiquadratic"}, + {"OS:Curve:QuadraticLinear", "1.58-group---performance-curves.html#curvequadraticlinear"}, + {"OS:Curve:CubicLinear", "1.58-group---performance-curves.html#curvecubiclinear"}, + {"OS:Curve:Triquadratic", "1.58-group---performance-curves.html#curvetriquadratic"}, + {"OS:Curve:FanPressureRise", "1.58-group---performance-curves.html#curvefanpressurerise"}, + {"OS:Curve:ExponentialDecay", "1.58-group---performance-curves.html#curveexponentialdecay"}, + {"OS:Curve:ExponentialSkewNormal", "1.58-group---performance-curves.html#curveexponentialskewnormal"}, + {"OS:Curve:Sigmoid", "1.58-group---performance-curves.html#curvesigmoid"}, + {"OS:Curve:QuadLinear", "1.58-group---performance-curves.html#curvequadlinear"}, + {"OS:Curve:QuintLinear", "1.58-group---performance-curves.html#curvequintlinear"}, + {"OS:Curve:RectangularHyperbola1", "1.58-group---performance-curves.html#curverectangularhyperbola1"}, + {"OS:Curve:RectangularHyperbola2", "1.58-group---performance-curves.html#curverectangularhyperbola2"}, + {"OS:Table:IndependentVariable", "1.59-group-performance-tables.html#tableindependentvariable"}, + {"OS:Table:IndependentVariableList", "1.59-group-performance-tables.html#tableindependentvariablelist"}, + {"OS:Table:Lookup", "1.59-group-performance-tables.html#tablelookup"}, // Output - {"OS:Output:Diagnostics", "group-simulation-parameters.html#outputdiagnostics"}, - {"OS:OutputControl:ReportingTolerances", "input-for-output.html#outputcontrolreportingtolerances"}, - {"OS:Output:JSON", "input-for-output.html#outputjson"}, - {"OS:Output:Table:SummaryReports", "output-table-summaryreports.html#outputtablesummaryreports"}, - {"OS:OutputControl:ResilienceSummaries", "input-for-output.html#OutputControlResilienceSummaries"}, + {"OS:Output:Diagnostics", "1.5-group-simulation-parameters.html#outputdiagnostics"}, + {"OS:OutputControl:ReportingTolerances", "5.1-group-reports.html#outputcontrolreportingtolerances"}, + {"OS:Output:JSON", "5.1-group-reports.html#outputjson"}, + {"OS:Output:Table:SummaryReports", "7.5-outputtablesummaryreports.html#outputtablesummaryreports"}, + {"OS:OutputControl:ResilienceSummaries", "5.1-group-reports.html#OutputControlResilienceSummaries"}, // Life Cycle Cost - {"OS:LifeCycleCost:Parameters", "lifecyclecost-parameters.html#lifecyclecostparameters"}, - {"OS:LifeCycleCost:UsePriceEscalation", "lifecyclecost-usepriceescalation.html#lifecyclecostusepriceescalation"}, + {"OS:LifeCycleCost:Parameters", "3.17-lifecyclecostparameters.html#lifecyclecostparameters"}, + {"OS:LifeCycleCost:UsePriceEscalation", "3.20-lifecyclecostusepriceescalation.html#lifecyclecostusepriceescalation"}, }; // clang-format on @@ -487,32 +489,33 @@ inline QString iddObjectDocUrl(const QString& iddTypeName) { return {}; } -// Returns the BigLadder EnergyPlus I/O Reference page URL for a given +// Returns the local EnergyPlus Input Output Reference page URL for a given // OpenStudio IDD group name (e.g. "OpenStudio Simulation"), or an empty string -// if the group has no known BigLadder page. Group names match \group +// if the group has no known page. Group names match \group // declarations in OpenStudio.idd. Groups that span multiple EnergyPlus // chapters (e.g. "OpenStudio HVAC") are omitted. inline QString iddGroupDocUrl(const QString& groupName) { - static const QString base = QString::fromStdString(openstudio::bigladdersoftwareDocBaseUrl()); + static const QString base = + QUrl::fromLocalFile(QString::fromStdString(openstudio::toString(openstudio::energyPlusDocDirectory())) + "/").toString(); // clang-format off static const QHash groupMap{ - {"OpenStudio Core", "group-simulation-parameters.html"}, - {"OpenStudio Simulation", "group-simulation-parameters.html"}, - {"OpenStudio Site", "group-location-climate-weather-file-access.html"}, - {"OpenStudio Materials", "group-surface-construction-elements.html"}, - {"OpenStudio Constructions", "group-surface-construction-elements.html"}, - {"OpenStudio Space Load Definitions", "group-internal-gains-people-lights-other.html"}, - {"OpenStudio Exterior Equipment Definitions", "group-exterior-energy-use-equipment.html"}, - {"OpenStudio Schedules", "group-schedules.html"}, - {"OpenStudio Geometry", "group-thermal-zone-description-geometry.html"}, - {"OpenStudio Space Loads", "group-internal-gains-people-lights-other.html"}, - {"OpenStudio Exterior Equipment", "group-exterior-energy-use-equipment.html"}, - {"OpenStudio Lighting Simulation", "group-daylighting.html"}, - {"OpenStudio Refrigeration", "group-refrigeration.html"}, - {"Solar Collectors", "group-solar-collectors.html"}, - {"Energy Management System (EMS)", "group-energy-management-system-ems.html"}, - {"User Defined HVAC and Plant Component Models", "group-user-defined-hvac-and-plant-component.html"}, + {"OpenStudio Core", "1.5-group-simulation-parameters.html"}, + {"OpenStudio Simulation", "1.5-group-simulation-parameters.html"}, + {"OpenStudio Site", "1.7-group-location-climate-weather-file-access.html"}, + {"OpenStudio Materials", "1.9-group-surface-construction-elements.html"}, + {"OpenStudio Constructions", "1.9-group-surface-construction-elements.html"}, + {"OpenStudio Space Load Definitions", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html"}, + {"OpenStudio Exterior Equipment Definitions", "1.16-group-exterior-energy-use-equipment.html"}, + {"OpenStudio Schedules", "1.8-group-schedules.html"}, + {"OpenStudio Geometry", "1.10-group-thermal-zone-descriptiongeometry.html"}, + {"OpenStudio Space Loads", "1.14-group-internal-gains-people-lights-other-internal-zone-equipment.html"}, + {"OpenStudio Exterior Equipment", "1.16-group-exterior-energy-use-equipment.html"}, + {"OpenStudio Lighting Simulation", "1.15-group-daylighting.html"}, + {"OpenStudio Refrigeration", "1.35-group-refrigeration.html"}, + {"Solar Collectors", "1.39-group-solar-collectors.html"}, + {"Energy Management System (EMS)", "1.45-group-energy-management-system-ems.html"}, + {"User Defined HVAC and Plant Component Models", "1.48-group-user-defined-hvac-and-plant-component-models.html"}, }; // clang-format on diff --git a/src/utilities/OpenStudioApplicationPathHelpers.cxx.in b/src/utilities/OpenStudioApplicationPathHelpers.cxx.in index e798591af..d8e6b61c0 100644 --- a/src/utilities/OpenStudioApplicationPathHelpers.cxx.in +++ b/src/utilities/OpenStudioApplicationPathHelpers.cxx.in @@ -8,7 +8,6 @@ // Include the core one as well #include #include -#include #include #include @@ -205,9 +204,11 @@ bool isOpenStudioApplicationModuleRunningFromBuildDirectory() { return pathBeginsWith(buildDir, runDir); } -std::string bigladdersoftwareDocBaseUrl() { - return "https://bigladdersoftware.com/epx/docs/" + std::to_string(energyPlusVersionMajor()) + "-" + std::to_string(energyPlusVersionMinor()) - + "/input-output-reference/"; +openstudio::path energyPlusDocDirectory() { + if (isOpenStudioApplicationRunningFromBuildDirectory()) { + return getOpenStudioApplicationBuildDirectory() / toPath("EnergyPlus/doc/input-output-reference"); + } + return getOpenStudioApplicationDirectory() / toPath("../EnergyPlus/doc/input-output-reference"); } openstudio::path getOpenStudioCoreCLI() { diff --git a/src/utilities/OpenStudioApplicationPathHelpers.hpp b/src/utilities/OpenStudioApplicationPathHelpers.hpp index 5a99366bd..b56794b13 100644 --- a/src/utilities/OpenStudioApplicationPathHelpers.hpp +++ b/src/utilities/OpenStudioApplicationPathHelpers.hpp @@ -60,8 +60,8 @@ OSAPP_UTILITIES_API bool isOpenStudioApplicationModuleRunningFromBuildDirectory( /// \returns The path to the OpenStudio Command Line Interface if it exists. OSAPP_UTILITIES_API openstudio::path getOpenStudioCoreCLI(); -/// \returns The base URL for the BigLadder EnergyPlus I/O Reference (versioned, trailing slash included) -OSAPP_UTILITIES_API std::string bigladdersoftwareDocBaseUrl(); +/// \returns The directory containing the local EnergyPlus Input Output Reference HTML documentation +OSAPP_UTILITIES_API openstudio::path energyPlusDocDirectory(); } // namespace openstudio