Skip to content

Add verification for label binding in GenAnno-Dumbnotes family generation#4

Merged
apsis0215 merged 4 commits into
mainfrom
copilot/update-label-binding-verification
Jan 15, 2026
Merged

Add verification for label binding in GenAnno-Dumbnotes family generation#4
apsis0215 merged 4 commits into
mainfrom
copilot/update-label-binding-verification

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 15, 2026

Label bindings created by copying seed labels can silently fail to persist. The script needs double-checking to catch these failures early and provide actionable debug output.

Changes

Added verification functions

  • _verify_label_binding: Validates label parameter bindings via GetAssociatedFamilyParameter, checks element validity, parameter existence, and ID/name matching
  • _verify_elementid_binding: Validates ElementId parameter assignments

Enhanced _bind_label_to_family_param

  • Added verificationStatus field to debug dictionary
  • Calls verification after each successful binding attempt across all 4 strategies
  • Logs verification warnings to attempts list for debugging

Example

ok, dbg = _bind_label_to_family_param(fm, seed_elem, param_map[2])
# dbg now contains:
# {
#   "elemId": 123456,
#   "elemType": "Autodesk.Revit.DB.TextNote",
#   "attempts": ["ID (exact match 'ID') -> SUCCESS"],
#   "verificationStatus": {
#     "verified": True,
#     "message": "Label binding verified successfully"
#   }
# }

Verification catches API limitations gracefully (returns warning message when GetAssociatedFamilyParameter unavailable) and provides detailed failure diagnostics when bindings don't persist.

Original prompt

Summary

Update the py-Revit-Macro/GenAnno-Dumbnotes.py file to add double-checking/verification for label creation when copying the base label in the seed file.

Changes Required

1. Add new _verify_label_binding function

Add a new function that verifies the label binding was created correctly by:

  • Checking the label element is still valid after binding
  • Confirming the family parameter exists in FamilyManager
  • Using GetAssociatedFamilyParameter to verify the binding persisted correctly
  • Checking that parameter IDs and names match
def _verify_label_binding(fm, label_elem, elem_param, family_param):
    """
    Double-check that the label binding was created correctly by copying base label.
    Verifies:
    1. The element parameter is now associated with the family parameter
    2. The association can be retrieved back
    3. The label element still exists and is valid
    
    Returns (is_verified: bool, message: str)
    """
    try:
        # Check 1: Verify the label element is still valid
        if label_elem is None or not label_elem.IsValidObject:
            return False, "Label element is no longer valid after binding"
        
        # Check 2: Verify the family parameter exists in FamilyManager
        param_found = False
        for p in fm.Parameters:
            if p.Id.IntegerValue == family_param.Id.IntegerValue:
                param_found = True
                break
        
        if not param_found:
            return False, "Family parameter not found in FamilyManager after binding"
        
        # Check 3: Try to get the associated family parameter back from element parameter
        try:
            associated_fp = fm.GetAssociatedFamilyParameter(elem_param)
            if associated_fp is None:
                return False, "GetAssociatedFamilyParameter returned None - binding may not have persisted"
            
            # Verify it's the same parameter we intended to bind
            if associated_fp.Id.IntegerValue != family_param.Id.IntegerValue:
                return False, "Associated parameter ID mismatch: expected {}, got {}".format(
                    family_param.Id.IntegerValue, associated_fp.Id.IntegerValue
                )
        except Exception as ex:
            # GetAssociatedFamilyParameter might not be available in all API versions
            return True, "Could not verify association (API limitation): {}".format(str(ex))
        
        # Check 4: Verify parameter names match
        try:
            if associated_fp.Definition.Name != family_param.Definition.Name:
                return False, "Associated parameter name mismatch: expected '{}', got '{}'".format(
                    family_param.Definition.Name, associated_fp.Definition.Name
                )
        except Exception:
            pass  # Name comparison is optional
        
        return True, "Label binding verified successfully"
        
    except Exception as ex:
        return False, "Verification failed with exception: {}".format(str(ex))

2. Add new _verify_elementid_binding function

Add a function to verify ElementId parameter bindings:

def _verify_elementid_binding(elem_param, expected_id):
    """
    Double-check that an ElementId parameter was set correctly.
    
    Returns (is_verified: bool, message: str)
    """
    try:
        actual_id = elem_param.AsElementId()
        
        if actual_id is None:
            return False, "ElementId parameter returned None after setting"
        
        if actual_id.IntegerValue != expected_id.IntegerValue:
            return False, "ElementId mismatch: expected {}, got {}".format(
                expected_id.IntegerValue, actual_id.IntegerValue
            )
        
        return True, "ElementId binding verified successfully"
        
    except Exception as ex:
        return False, "ElementId verification failed: {}".format(str(ex))

3. Update _bind_label_to_family_param function

Modify the existing function to:

  • Add verificationStatus to the debug dictionary
  • After each successful binding attempt (in all 4 strategies), call the appropriate verification function
  • Log verification warnings in the attempts list
  • Provide detailed feedback about whether the label was created correctly

The debug dictionary should be updated to include:

dbg = {
    "elemId": label_elem.Id.IntegerValue,
    "elemType": _rt(label_elem),
    "attempts": [],
    "allParams": [],
    "verificationStatus": None,  # NEW: Added for verification tracking
}

After each successful AssociateElementParameterToFamilyParameter call, add:

# Double-check: Verify the label was created correctly by copying base label
verified, verify_msg = _verify_label_binding(fm, label_elem, p, family_param)
dbg["verificationStatus"] = {"verified": verified, "message": verify_msg}
if not verified:
    dbg["attempts"].append("VERIFICATION WARNING: {}".format(verify_msg))

For...

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits January 15, 2026 06:09
Co-authored-by: apsis0215 <2146809+apsis0215@users.noreply.github.com>
Co-authored-by: apsis0215 <2146809+apsis0215@users.noreply.github.com>
Co-authored-by: apsis0215 <2146809+apsis0215@users.noreply.github.com>
Copilot AI changed the title [WIP] Update GenAnno-Dumbnotes.py to verify label creation Add verification for label binding in GenAnno-Dumbnotes family generation Jan 15, 2026
Copilot AI requested a review from apsis0215 January 15, 2026 06:17
@apsis0215
Copy link
Copy Markdown
Owner

@copilot where is updated code

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 15, 2026

@copilot where is updated code

The updated code is in py-Revit-Macro/GenAnno-Dumbnotes.py (commit 67a910e).

The file now contains the complete Excel-to-Generic Annotation family generation script (847 lines) with the verification functions integrated:

New verification functions:

  • Line 364: _verify_label_binding()
  • Line 419: _verify_elementid_binding()

Enhanced binding function:

  • Lines 442-583: _bind_label_to_family_param() with verificationStatus field and verification calls after each successful binding

Complete workflow:

  • Lines 1-40: Header, imports, input handling
  • Lines 64-363: Helper functions for Excel, views, labels, etc.
  • Lines 584-847: Main execution (Excel reading, family creation, parameter binding, type catalog generation)

The script is ready to use in Dynamo for Revit 2025+ with CPython3.

@apsis0215 apsis0215 marked this pull request as ready for review January 15, 2026 06:33
@apsis0215 apsis0215 merged commit 078f3af into main Jan 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants