{"id":23401842,"url":"https://github.com/bbartling/brickmodelsummarizer","last_synced_at":"2026-02-19T06:32:15.755Z","repository":{"id":184911499,"uuid":"672351208","full_name":"bbartling/BrickModelSummarizer","owner":"bbartling","description":"Fine tuned LLM project for anything HVAC related...","archived":false,"fork":false,"pushed_at":"2025-02-01T15:15:18.000Z","size":4843,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2026-01-04T03:55:31.607Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bbartling.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-29T19:21:19.000Z","updated_at":"2025-02-01T15:15:22.000Z","dependencies_parsed_at":"2024-11-01T19:27:06.433Z","dependency_job_id":"a9941a8e-e1c6-4d46-838a-13ad35abe6fc","html_url":"https://github.com/bbartling/BrickModelSummarizer","commit_stats":null,"previous_names":["bbartling/my-own-llm","bbartling/hvacgpt","bbartling/brickmodelsummarizer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bbartling/BrickModelSummarizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2FBrickModelSummarizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2FBrickModelSummarizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2FBrickModelSummarizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2FBrickModelSummarizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bbartling","download_url":"https://codeload.github.com/bbartling/BrickModelSummarizer/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbartling%2FBrickModelSummarizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29604790,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T05:11:50.834Z","status":"ssl_error","status_checked_at":"2026-02-19T05:11:38.921Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-22T11:19:38.441Z","updated_at":"2026-02-19T06:32:15.749Z","avatar_url":"https://github.com/bbartling.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BRICK Model Summarizer\n\n[![PyPI version](https://badge.fury.io/py/brick-model-summarizer.svg)](https://pypi.org/project/brick-model-summarizer/)\n[![Tests](https://github.com/bbartling/BrickModelSummarizer/actions/workflows/tests.yml/badge.svg)](https://github.com/bbartling/BrickModelSummarizer/actions)\n\n\n![BRICK Model Summarizer Interface](https://github.com/bbartling/BrickModelSummarizer/blob/develop/flask_snip.png)\n\n\n**BRICK Model Summarizer** is a Python tool designed to validate and benchmark AI-generated BRICK models against reference models. It transforms complex BRICK schema TTL files into concise, human-readable summaries of HVAC systems, zones, meters, and central plants. By leveraging [reference BRICK models](https://brickschema.org/resources/#reference-brick-models), this tool enables users to validate AI-created models for consistency, accuracy, and adherence to expected standards.\n\n## Purpose\n\nThe primary purpose of this repository is to provide a framework for summarizing BRICK models into HVAC-centric insights. This is especially useful for:\n- **Benchmarking AI-generated BRICK models** against reference models.\n- **Validating BRICK schemas** for completeness and alignment with building system expectations.\n- **Empowering building engineers, analysts, and AI developers** with clear summaries of mechanical systems and operational data.\n\n## Key Features\n\n- **HVAC-Focused Summarization**: Extracts key details about AHUs, VAVs, meters, and central plant equipment.\n- **Model Validation**: Provides a framework for benchmarking AI-created BRICK models.\n- **Scalable Processing**: Processes individual or multiple BRICK schema TTL files.\n\n\n## Installation\nTested in Linux and Windows Subsystem for Linux\n```bash\npip install brick-model-summarizer\n```\n\n### Local Installation for development purposes\n\n1. **Clone the repository**:\n   ```bash\n   git clone https://github.com/bbartling/brick-model-summarizer.git\n   cd brick-model-summarizer\n   ```\n\n2. **Set up a virtual environment** (optional but recommended):\n   ```bash\n   python -m venv env\n   source env/bin/activate\n   ```\n\n3. **Install the package locally**:\n   ```bash\n   pip install -e .\n   pytest\n   ```\n\n---\n\n## Usage\n\nThe package includes functions for summarizing BRICK models and generating detailed outputs. Below is an example of how to use the tool in Python to generate JSON-style data.\n\n\n### Example: Processing a BRICK Model\n\n```python\nimport os\nfrom brick_model_summarizer import (\n    load_graph_once,\n    get_class_tag_summary,\n    get_ahu_information,\n    get_zone_information,\n    get_building_information,\n    get_meter_information,\n    get_central_plant_information,\n    get_vav_boxes_per_ahu,\n)\n\n# Get the absolute path of the project root\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nproject_root = os.path.dirname(script_dir)\n\n# Construct the relative path to the BRICK model\nbrick_model_path = os.path.join(project_root, \"sample_brick_models\", \"diggs.ttl\")\n\nprint(\"Resolved Brick Model Path:\", brick_model_path)\n\n# Load the RDF graph once\ngraph = load_graph_once(brick_model_path)\n\n# Get the individual data components\nahu_data = get_ahu_information(graph)\nprint(\"ahu_data \\n\", ahu_data)\n\nzone_info = get_zone_information(graph)\nprint(\"zone_info \\n\", zone_info)\n\nclass_tag_sum = get_class_tag_summary(graph)\nprint(\"class_tag_sum \\n\", class_tag_sum)\n\nbuilding_data = get_building_information(graph)\nprint(\"building_data \\n\", building_data)\n\nmeter_data = get_meter_information(graph)\nprint(\"meter_data \\n\", meter_data)\n\ncentral_plant_data = get_central_plant_information(graph)\nprint(\"central_plant_data \\n\", central_plant_data)\n\nvav_boxes_per_ahu = get_vav_boxes_per_ahu(graph)\nprint(\"vav_boxes_per_ahu \\n\", vav_boxes_per_ahu)\n\n```\n\n### Example Output\n\n```python\n=== AHU DEBUG Summary ===\nProcessed AHU's: 0\n\nahu_data\n {'total_ahus': 0, 'constant_volume_ahus': 0, 'variable_air_volume_ahus': 0, 'ahus_with_cooling_coil': 0, 'ahus_with_heating_coil': 0, 'ahus_with_return_fans': 0, 'ahus_with_supply_fans': 0, 'ahus_with_return_air_temp_sensors': 0, 'ahus_with_mixing_air_temp_sensors': 0, 'ahus_with_supply_air_temp_sensors': 0, 'ahus_with_supply_air_temp_setpoints': 0, 'ahus_with_static_pressure_sensors': 0, 'ahus_with_static_pressure_setpoints': 0, 'ahus_with_air_flow_sensors': 0, 'ahus_with_air_flow_setpoints': 0, 'ahus_with_active_chilled_beams': 0, 'ahus_with_chilled_beams': 0, 'ahus_with_passive_chilled_beams': 0, 'ahus_with_heat_wheels': 0, 'ahus_with_heat_wheel_vfds': 0}\nzone_info \n {'zone_air_temperature_setpoints_found': False, 'total_variable_air_volume_boxes': 59, 'total_variable_air_volume_boxes_with_reheat': 0, 'number_of_vav_boxes_per_ahu': {}, 'vav_boxes_with_reheat_valve_command': 0, 'vav_boxes_with_air_flow_sensors': 0, 'vav_boxes_with_supply_air_temp_sensors': 0, 'vav_boxes_with_air_flow_setpoints': 0, 'co2_sensor_count': 0, 'co2_setpoint_count': 0, 'zone_air_conditioning_mode_status_count': 0, 'cooling_temp_setpoint_count': 0, 'dewpoint_sensor_count': 0, 'heating_temp_setpoint_count': 0, 'humidity_sensor_count': 0, 'humidity_setpoint_count': 0, 'temperature_sensor_count': 0, 'temperature_setpoint_count': 0, 'zone_count': 0, 'reheat_command_count': 0, 'reheat_hot_water_system_count': 0, 'reheat_valve_count': 0}\n\nClass Similarities:\nclass_tag_sum\n {'class_mismatches': [], 'tag_mismatches': []}\nbuilding_data \n {'building_area': 'not_available', 'number_of_floors': 'not_available', 'hvac_equipment_count': 9, 'hvac_zone_count': 0}\nmeter_data \n {'chilled_water_meter_present': False, 'hot_water_meter_present': False, 'building_electrical_meter_present': False, 'building_gas_meter_present': False, 'building_water_meter_present': False, 'electric_energy_sensor_count': 0, 'electric_power_sensor_count': 0, 'active_power_sensor_count': 0, 'ev_charging_hub_count': 0, 'ev_charging_port_count': 0, 'ev_charging_station_count': 0, 'electrical_energy_usage_sensor_count': 0, 'pv_generation_system_count': 0, 'pv_panel_count': 0, 'photovoltaic_array_count': 0, 'photovoltaic_current_output_sensor_count': 0, 'photovoltaic_inverter_count': 0, 'peak_demand_sensor_count': 0, 'people_count_sensor_count': 0}\ncentral_plant_data \n {'chiller_count': 0, 'water_cooled_chiller_count': 0, 'air_cooled_chiller_count': 0, 'centrifugal_chiller_count': 0, 'absorption_chiller_count': 0, 'boiler_count': 0, 'natural_gas_boiler_count': 0, 'noncondensing_natural_gas_boiler_count': 0, 'condensing_natural_gas_boiler_count': 0, 'electric_boiler_count': 0, 'cooling_tower_count': 0, 'cooling_tower_fan_count': 0, 'heat_exchanger_count': 0, 'heat_exchanger_discharge_temp_sensor_count': 0, 'heat_exchanger_leaving_temp_sensor_count': 0, 'heat_exchanger_supply_temp_sensor_count': 0, 'heat_exchanger_system_enable_status_count': 0, 'heat_pump_air_source_condensing_unit_count': 0, 'heat_pump_condensing_unit_count': 0, 'heat_pump_ground_source_condensing_unit_count': 0, 'heat_pump_water_source_condensing_unit_count': 0, 'heat_recovery_air_source_condensing_unit_count': 0, 'heat_recovery_condensing_unit_count': 0, 'heat_recovery_hot_water_system_count': 0, 'heat_recovery_water_source_condensing_unit_count': 0, 'hot_water_system_count': 0, 'water_pump_count': 0, 'chilled_water_system_count': 0, 'condenser_water_loop_count': 0, 'condenser_water_pump_count': 0, 'condenser_water_system_count': 0, 'domestic_hot_water_system_count': 0, 'preheat_hot_water_system_count': 0, 'radiation_hot_water_system_count': 0, 'reheat_hot_water_system_count': 0, 'water_system_count': 0, 'water_system': 1, 'water_pump': 4, 'hot_water_system': 1, 'chiller_water_flow_count': 0, 'boiler_water_flow_count': 0, 'cooling_tower_temp_count': 0}\nvav_boxes_per_ahu \n {}\n```\n\nOne note on the output of the  `Class Similarities` is it finds mismatched BRICK classes and tags by comparing them to the most current standard. If a mismatch is found, it returns a dictionary like data in the format of `('custom_tag', 'standard_tag', 0.90)`:  \n\n```python\n{\n    'class_mismatches': [('Air_Handler_Unit', 'Air_Handling_Unit', 0.85)],\n    'tag_mismatches': [('custom_tag', 'standard_tag', 0.90)]\n}\n```\nHere, **0.85 and 0.90** are similarity scores from `SequenceMatcher`, which measure how close the custom class or tag is to the standard one. These values provide a **statistical similarity percentage** from the Python `difflib` package, helping you assess how much a custom class deviates from the standard. \n---\n\n\n\n### New in v0.5.0 – Integrity Checks and SPARQL Queries\n\nThe Flask web application now includes an **Integrity \u0026 SPARQL Queries** section.  After uploading a TTL file you can:\n\n- **Find Orphan Points**: detect point entities (e.g., sensors, setpoints) that are not linked to any equipment via `brick:isPointOf`.  This helps identify incomplete or inconsistent models.\n- **Run SPARQL Queries**: enter your own SPARQL `SELECT` queries or choose from several example queries.  If `rdflib` is installed, full SPARQL is supported; otherwise, a simplified query engine handles basic patterns (see the documentation in `brick_model_summarizer.simple_graph`).\n\nExample query to list all variable air volume boxes:\n\n```sparql\nSELECT ?box WHERE { ?box a brick:Variable_Air_Volume_Box . }\n```\n\nExample query to see which VAV boxes belong to which AHU:\n\n```sparql\nSELECT ?box ?ahu WHERE { ?box brick:isPartOf ?ahu . }\n```\n\nThese capabilities enhance the model exploration experience without requiring any additional dependencies.\n\nRun Flask App with:\n```bash\npython -m brick_model_summarizer.flask_app.app\n```\n\n## Contributing\n\nWe welcome contributions to improve the repository. Please submit issues or pull requests to discuss new features, bug fixes, or enhancements.\n\n## Roadmap\n\n### Planned Enhancements\n- **ECM and KPI Suggestions**: Develop functionality to recommend energy conservation measures (ECMs) based on model summaries.\n- **Advanced Validation**: Add checks for missing or inconsistent relationships in AI-generated models.\n- **PyPI Distribution**: Prepare the package for publication on PyPI.\n\n## License\n\nThis project is licensed under the MIT License. See the LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbartling%2Fbrickmodelsummarizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbbartling%2Fbrickmodelsummarizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbartling%2Fbrickmodelsummarizer/lists"}