6 Commits

Author SHA1 Message Date
dependabot[bot] 9874d29cd3 Bump actions/setup-python from 5 to 6
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 22:14:26 +00:00
NLSA 83876e7898 Update README.md
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2025-03-20 14:28:08 +01:00
NLSA 76d6c1c72a Update Level
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2025-03-18 10:00:23 +01:00
NLSA 61b632cb4b Update Inputs as Optional
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2025-03-06 09:11:09 +01:00
NLSA 7e4e29c365 Update main.py
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2025-03-03 17:11:12 +01:00
NLSA c6f425c9b3 Update README.md
build and deploy Speckle functions / publish-automate-function-version (push) Has been cancelled
2025-03-03 15:27:09 +01:00
4 changed files with 70 additions and 97 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4.1.7 - uses: actions/checkout@v4.1.7
- uses: actions/setup-python@v5 - uses: actions/setup-python@v6
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install poetry - name: Install poetry
+41 -75
View File
@@ -1,100 +1,66 @@
# Speckle Automate function template - Python
This template repository is for a Speckle Automate function written in Python ![Blog Image_1920x1080 (3)](https://github.com/user-attachments/assets/b8f93e45-595e-4cad-bfc2-5fc830948e03)
using the [specklepy](https://pypi.org/project/specklepy/) SDK to interact with Speckle data.
This template contains the full scaffolding required to publish a function to the Automate environment. # 🚀 Automate Revit Rooms and Areas Scheduling No Coding Required
It also has some sane defaults for development environment setups.
## Getting started Easily export all **Rooms** and **Areas** by Level into an Excel file in seconds, ensuring **accurate and up-to-date project data**. This automation **eliminates manual effort**, **reduces errors**, and provides a **structured format** for further analysis.
1. Use this template repository to create a new repository in your own / organization's profile. Seamlessly integrate the exported data with **reporting tools** or **dashboards** to enhance project tracking and decision-making.
Register the function ---
### Add new dependencies ## 📏 Follow Your Standards
To add new Python package dependencies to the project, use the following: Define **Area KPI metrics** based on your companys standards to ensure **consistency and accuracy** across all projects.
`$ poetry add pandas`
### Change launch variables With clear benchmarks, you can:
✅ Track performance
✅ Optimize space utilization
✅ Make data-driven decisions
Describe how the launch.json should be edited. By automating this process, each **new model version** can be compared against predefined criteria—ensuring compliance and efficiency.
### Github Codespaces ---
Create a new repo from this template, and use the create new code. ## 🔎 Never Miss a Detail
### Using this Speckle Function Every time a **new model version** is published from Revit, all **Rooms and/or Areas** are **automatically exported** into an Excel file.
1. [Create](https://automate.speckle.dev/) a new Speckle Automation. This guarantees that:
1. Select your Speckle Project and Speckle Model. ✔ No data is missed
1. Select the deployed Speckle Function. ✔ You have a reliable record of spatial changes over time
1. Enter a phrase to use in the comment. ✔ Your project data remains structured and up to date
1. Click `Create Automation`.
## Getting Started with Creating Your Own Speckle Function ---
1. [Register](https://automate.speckle.dev/) your Function with [Speckle Automate](https://automate.speckle.dev/) and select the Python template. ## 📊 **See Results Clearly**
1. A new repository will be created in your GitHub account.
1. Make changes to your Function in `main.py`. See below for the Developer Requirements and instructions on how to test.
1. To create a new version of your Function, create a new [GitHub release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) in your repository.
## Developer Requirements Each time a **new model version** is published, Revit will export **all Rooms and/or Areas** for each Level into an Excel file, providing a **clear and structured** dataset for analysis.
1. Install the following: ### ✨ **Optional: Set Up KPI Metrics**
- [Python 3](https://www.python.org/downloads/)
- [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer)
1. Run `poetry shell && poetry install` to install the required Python packages.
## Building and Testing You can track key **Area KPI metrics** such as:
The code can be tested locally by running `poetry run pytest`. - **NUA** Net Usable Area
- **NIA** Net Internal Area
- **NLA** Net Leasable Area
- **GIA** Gross Internal Area
- **GEA** Gross External Area
- **GLA** Gross Leasable Area
- **GBA** Gross Building Area
### Building and running the Docker Container Image ### ⚡ How to Define KPI Metrics
Running and testing your code on your machine is a great way to develop your Function; the following instructions are a bit more in-depth and only required if you are having issues with your Function in GitHub Actions or on Speckle Automate. ⚠️To calculate a KPI metric, use the **exact names** of the **Rooms** and/or **Areas** you want to combine.
#### Building the Docker Container Image #### Example: **Office Building Net Internal Area (NIA)**
In an office building, **NIA** is typically calculated by summing up the areas for:
- **Office**
- **Amenities**
- **Storage**
- **Primary Circulation**
The GitHub Action packages your code into the format required by Speckle Automate. This is done by building a Docker Image, which Speckle Automate runs. You can attempt to build the Docker Image locally to test the building process. Simply separate these names with commas when defining your metric.
To build the Docker Container Image, you must have [Docker](https://docs.docker.com/get-docker/) installed.
Once you have Docker running on your local machine: ![image (3)](https://github.com/user-attachments/assets/6468f1ed-9b99-46d8-934c-eb6f55085b5d)
1. Open a terminal
1. Navigate to the directory in which you cloned this repository
1. Run the following command:
```bash
docker build -f ./Dockerfile -t speckle_automate_python_example .
```
#### Running the Docker Container Image
Once the GitHub Action has built the image, it is sent to Speckle Automate. When Speckle Automate runs your Function as part of an Automation, it will run the Docker Container Image. You can test that your Docker Container Image runs correctly locally.
1. To then run the Docker Container Image, run the following command:
```bash
docker run --rm speckle_automate_python_example \
python -u main.py run \
'{"projectId": "1234", "modelId": "1234", "branchName": "myBranch", "versionId": "1234", "speckleServerUrl": "https://speckle.xyz", "automationId": "1234", "automationRevisionId": "1234", "automationRunId": "1234", "functionId": "1234", "functionName": "my function", "functionLogo": "base64EncodedPng"}' \
'{}' \
yourSpeckleServerAuthenticationToken
```
Let's explain this in more detail:
`docker run—-rm speckle_automate_python_example` tells Docker to run the Docker Container Image we built earlier. `speckle_automate_python_example` is the name of the Docker Container Image. The `--rm` flag tells Docker to remove the container after it has finished running, freeing up space on your machine.
The line `python -u main.py run` is the command run inside the Docker Container Image. The rest of the command is the arguments passed to the command. The arguments are:
- `'{"projectId": "1234", "modelId": "1234", "branchName": "myBranch", "versionId": "1234", "speckleServerUrl": "https://speckle.xyz", "automationId": "1234", "automationRevisionId": "1234", "automationRunId": "1234", "functionId": "1234", "functionName": "my function", "functionLogo": "base64EncodedPng"}'` - the metadata that describes the automation and the function.
- `{}` - the input parameters for the function the Automation creator can set. Here, they are blank, but you can add your parameters to test your function.
- `yourSpeckleServerAuthenticationToken`—the authentication token for the Speckle Server that the Automation can connect to. This is required to interact with the Speckle Server, for example, to get data from the Model.
## Resources
- [Learn](https://speckle.guide/dev/python.html) more about SpecklePy and interacting with Speckle from Python.
+24 -19
View File
@@ -27,7 +27,7 @@ class FunctionInputs(AutomateBase):
file_name: str = Field( file_name: str = Field(
title="File Name", title="File Name",
description="The name of the Excel file.", description="The name of the Excel file to export.",
) )
inlcude_areas: bool = Field( inlcude_areas: bool = Field(
@@ -43,38 +43,45 @@ class FunctionInputs(AutomateBase):
) )
nua_list: str = Field( nua_list: str = Field(
title="NUA (Nett Usable Area)", title="NUA (Optional)",
strict= False description="Nett Usable Area",
default= ""
) )
nia_list: str = Field( nia_list: str = Field(
title="NIA (Nett Internal Area)", title="NIA (Optional)",
strict= False description="Nett Internal Area",
default= ""
) )
nla_list: str = Field( nla_list: str = Field(
title="NLA (Nett Leasable Area)", title="NLA (Optional)",
strict= False description="Nett Leasable Area",
default= ""
) )
gia_list: str = Field( gia_list: str = Field(
title="GIA (Gross Internal Area)", title="GIA (Optional)",
strict= False description="Gross Internal Area",
default= ""
) )
gea_list: str = Field( gea_list: str = Field(
title="GEA (Gross External Area)", title="GEA (Optional)",
strict= False description="Gross External Area",
default= ""
) )
gla_list: str = Field( gla_list: str = Field(
title="GLA (Gross Leasable Area)", title="GLA (Optional)",
strict= False description="Gross Leasable Area",
default= ""
) )
gba_list: str = Field( gba_list: str = Field(
title="GBA (Gross Building Area)", title="GBA (Optional)",
strict= False description="Gross Building Area",
default= ""
) )
@@ -122,20 +129,18 @@ def automate_function(
return return
items = [] items = []
id_lists = []
for i in all_objects: for i in all_objects:
if hasattr(i, "category"): # Check if the object has the "category" attribute if hasattr(i, "category"): # Check if the object has the "category" attribute
if i.category in filter_categories: # Check if the category matches the filter list if i.category in filter_categories: # Check if the category matches the filter list
items.append(i) # Append the whole object to the items list items.append(i) # Append the whole object to the items list
id_lists.append(i.id)
else: else:
continue # Skip if "category" does not exist continue # Skip if "category" does not exist
# List of properties # List of properties
list_prop = [ list_prop = [
"category", "category",
"level.name", "level",
"properties.Parameters.Instance Parameters.Identity Data.Name.value", "properties.Parameters.Instance Parameters.Identity Data.Name.value",
"properties.Parameters.Instance Parameters.Dimensions.Area.value", "properties.Parameters.Instance Parameters.Dimensions.Area.value",
] ]
@@ -187,7 +192,7 @@ def automate_function(
automate_context.store_file_result(f"./{output_file}") automate_context.store_file_result(f"./{output_file}")
automate_context.mark_run_success("All data sent successfully! Download your file below.") automate_context.mark_run_success("All data sent successfully! Download your file below.")
except: except:
automate_context.mark_run_failed("An error occurred while writing to the file. Ensure that the parameters 'Level,' 'Name,' and 'Area' exist. Additionally, verify that the area/room names are correctly typed and separated by commas.") automate_context.mark_run_failed("An error occurred while writing to the file. Ensure that the parameters Areas or Rooms category exist. Additionally, verify that the area/room names are correctly typed and separated by commas.")
# Function to sum area for each group, ensuring missing levels return 0 # Function to sum area for each group, ensuring missing levels return 0
+4 -2
View File
@@ -22,9 +22,11 @@ def test_function_run(test_automation_run_data: AutomationRunData, test_automati
automate_sdk = run_function( automate_sdk = run_function(
automation_context, automation_context,
automate_function, automate_function,
#These are test inputs, only work when testing localy.
FunctionInputs( FunctionInputs(
file_name="TestNameABC", file_name="TestName",
inlcude_areas= True, inlcude_areas= False,
inlcude_rooms= True, inlcude_rooms= True,
nua_list = "Elevator E1, Level 5 Gross, Live/Work Unit, Machine RM", nua_list = "Elevator E1, Level 5 Gross, Live/Work Unit, Machine RM",
nia_list = "", nia_list = "",