Model > Data
Data Validator
Checks the model against BEP rules kept as JSON files in the team rules folder (every duct has a system name, every element a level, marks filled in, comments matching a pattern). Reports passes and failures per rule with element links, and can export to Excel and save a selection set per failing rule. Shift+Click for settings.
Status
Untested Never executed inside Navisworks. Passed the headless checks only.
The public ask
No public source is on record for this tool.
Events it listens to
None. It runs only when you click it.
Files
Paths are relative to the Playground.extension folder.
Model.tab/Data.panel/Data_Validator.pushbutton/bundle.yamlModel.tab/Data.panel/Data_Validator.pushbutton/config.pyModel.tab/Data.panel/Data_Validator.pushbutton/icon.dark.pngModel.tab/Data.panel/Data_Validator.pushbutton/icon.pngModel.tab/Data.panel/Data_Validator.pushbutton/icon.small.dark.pngModel.tab/Data.panel/Data_Validator.pushbutton/icon.small.pngModel.tab/Data.panel/Data_Validator.pushbutton/script.py
Install
- Only this tool. In Navisworks, click pyNavis > Playground, search for Data Validator, tick it and click Install.
- The whole extension. Download
Playground.extension.zip, unzip it, put thePlayground.extensionfolder in%APPDATA%\pyNavis\extensions\, and click pyNavis > Reload. Data Validator is on the Model tab, Data panel.
You need pyNavis 1.3.0 or later.
Tried it? Tell us whether it worked or not. That report is what moves a tool up the status ladder.
ReportSource
The tool's own files, word for word as published in pynavis/Playground. Paths are relative to the Playground.extension folder.
script.py
The script that runs on a click.
Model.tab/Data.panel/Data_Validator.pushbutton/script.py View on GitHub# -*- coding: utf-8 -*-
"""Validates model properties against the JSON rule files in the team rules folder."""
from pynavis import script, toast
from namo import data_common, progress, reports, ui, validator
DEFAULTS = {'rule_files': [], 'scope': 'model', 'level': 'objects', 'xlsx': False, 'sets': False}
def pick_files(rulesets, values):
rows = []
for ruleset in rulesets:
problems = len(ruleset.get('problems') or [])
rows.append({'cells': [ruleset['name'], len(ruleset['rules']), ruleset['file'],
'%d %s' % (problems, 'problem' if problems == 1 else 'problems') if problems else ''],
'value': ruleset['file']})
remembered = [f for f in values.get('rule_files') or [] if f in [r['file'] for r in rulesets]]
checked = remembered or [r['file'] for r in rulesets]
return ui.choose('Data Validator', rows, ['Rule set', 'Rules', 'File', 'Problems'], multiselect=True,
checked=checked, ok='Next',
prompt='Run which rule files? They live in %s (Shift+Click the button to open the folder).'
% validator.rules_folder())
def run():
if ui.is_runner():
result = reports.run('data_validation', script.get_config(DEFAULTS), interactive=False)
if not result.get('cancelled'):
toast.show(result['level'], result['message'], result['detail'])
return
doc = data_common.active_doc()
if not data_common.has_models(doc):
data_common.no_model_toast()
return
folder = validator.rules_folder()
created = validator.ensure_starter(folder)
rulesets = validator.load_folder(folder)
if not rulesets:
toast.warning('No rule files', 'Add .json rule files to %s, then run this again.' % folder)
return
values = script.get_config(DEFAULTS)
files = pick_files(rulesets, values)
if files is None:
return
has_selection = data_common.selected_count(doc) > 0
fields = data_common.scope_fields(has_selection, values.get('scope'), values.get('level'))
fields.append({'kind': 'check', 'key': 'xlsx', 'label': 'Also save an Excel workbook (every failure)',
'default': bool(values.get('xlsx'))})
fields.append({'kind': 'check', 'key': 'sets', 'label': 'Save a selection set per failing rule (in %s)'
% validator.SET_FOLDER,
'default': bool(values.get('sets'))})
intro = None
if created:
intro = 'A starter rule file was added to the rules folder; copy and edit it for your BEP.'
answer = ui.form('Data Validator', fields, intro=intro, ok='Validate')
if answer is None:
return
config = {'rule_files': files, 'scope': answer['scope'], 'level': answer['level'],
'xlsx': bool(answer['xlsx']), 'sets': bool(answer['sets'])}
script.save_config(config)
if config['xlsx']:
path = data_common.ask_save('{file} - Data validation - {date}', 'xlsx', 'Save the validation report', doc)
if path is None:
return
config['path'] = path
result = progress.run('Data Validator', lambda report: reports.run(
'data_validation', config, doc=doc, interactive=True, progress=report))
if result is progress.CANCELLED or result.get('cancelled'):
return
toast.show(result['level'], result['message'], result['detail'])
run()
config.py
The Shift+Click action.
Model.tab/Data.panel/Data_Validator.pushbutton/config.py View on GitHub# -*- coding: utf-8 -*-
"""Opens the validation rules folder, checks every rule file, or restores the starter rules."""
from pynavis import forms, output, toast
from namo import ui, validator
OPEN = 'Open the rules folder'
CHECK = 'Check the rule files'
RESTORE = 'Restore the starter rules'
def check(folder):
rulesets = validator.load_folder(folder)
if not rulesets:
toast.info('No rule files', 'The folder %s holds no .json files.' % folder)
return
problems = []
rules = 0
for ruleset in rulesets:
problems.extend(ruleset.get('problems') or [])
rules += len(ruleset['rules'])
if not problems:
toast.success('Every rule file reads cleanly', '%d %s, %d %s.' % (
len(rulesets), 'file' if len(rulesets) == 1 else 'files', rules, 'rule' if rules == 1 else 'rules'))
return
output.print_md('**Rule file problems** in %s' % folder)
output.print_table([[line] for line in problems], ['Problem'])
toast.warning('%d %s in the rule files' % (len(problems), 'problem' if len(problems) == 1 else 'problems'),
'Each one is listed with its line in the output window.')
def run():
if ui.is_runner():
toast.info('Settings need the Navisworks window', 'They cannot open under pynavis run.')
return
folder = validator.rules_folder()
validator.ensure_starter(folder)
choice = forms.ask_options('Validation rules live in %s.' % folder, [OPEN, CHECK, RESTORE],
title='Data Validator')
if choice is None:
return
if choice == OPEN:
ui.open_path(folder)
toast.success('Opened the rules folder', folder)
elif choice == CHECK:
check(folder)
else:
if not forms.confirm('Overwrite %s with the shipped starter rules? Your other rule files are kept.'
% validator.STARTER_FILE, title='Data Validator'):
return
try:
path = validator.restore_starter(folder)
except (IOError, OSError) as error:
toast.error('Could not write the starter rules', str(error))
return
toast.success('Starter rules restored', path)
run()
Library modules this tool uses
From the shared namo library, which installs with every tool. Each name opens the module on GitHub.
namo.data_commonShared plumbing for the Inspect and Data panel tools: progress stages, where files go by default, the scope dialog fields, and the small checks every button starts with.namo.progressGlue between pyNavis' cancellable progress window and Playground's progress callbacks.namo.reportsThe registry of automation-ready reports, and the helpers every report shares.namo.uiWPF building blocks for Playground tools, themed from the pyNavis design system.namo.validatorData Validator: BEP-style property checks from JSON rule files.
bundle.yaml
The bundle contract: the keys pyNavis reads for this tool.
Model.tab/Data.panel/Data_Validator.pushbutton/bundle.yaml View on GitHubtitle: Data\nValidator
tooltip: Checks the model against BEP rules kept as JSON files in the team rules folder (every duct has a system name, every element a level, marks filled in, comments matching a pattern). Reports passes and failures per rule with element links, and can export to Excel and save a selection set per failing rule. Shift+Click for settings.
context: doc