Naming conventions
Integrators map a building by working out its naming convention, for
example AHU{n}-{point} or VAV-{flr}-{n}-{pt}, usually in a spreadsheet.
In Baler you do this once, in Ops → Mapping review → Naming conventions.
You mark up one label, preview the result over every point, and apply it.
It's the idea behind NREL BuildingMOTIF's label parser, reimplemented here
without the dependency. Code: src/baler/conventions.py.
Annotating
Write out a real label and wrap the parts that vary in {role:text}:
Code
| Role | What it is |
|---|---|
equip_type | the equipment kind's code, e.g. ahu or chw-pump |
equip_id | its number or name within the kind |
point | the point's code, e.g. DIS-AIR-TEM or SAT |
ignore | something that varies but means nothing, such as an instance number |
Everything outside the braces is literal. The annotation compiles to an anchored pattern and runs against each point's source topic. A site with two label styles needs two annotations. They are tried in order, so list the more specific one first.
Codes are normalised to lower case, letters and digits only. That makes
Discharge_Air_Temp, discharge_air_temp and DischargeAirTemp the same
code.
Saying what codes mean
You list codes with their Brick class: SAT = Supply_Air_Temperature_Sensor
for points, and AHU = Air_Handling_Unit for equipment. Each name is
checked against Brick, and an unknown one is refused. One entry covers
every point with that code, and that is where the leverage is.
Preview writes nothing. It shows:
- how many points match a template, and how many would be classified;
- the unknown codes ranked by how many points each would settle, with examples, so the next code to add is always the most useful one;
- the equipment codes that are still unknown;
- a sample of labels no template matched.
By default it counts only points Baler hasn't classified yet.
Applying
Apply classifies every point whose code is known and that has no class yet. A convention never overrides an existing class.
- Each class is written the same way as a hand edit and logged in
record_editswith actionconvention. - The point's equipment gets the equip code's class when all of its matched points agree.
The summary counts these points as "By a naming convention".
Saved conventions are also rung 2 of the ladder: python -m baler.autotag
runs them before the rules. A matching point with a known code becomes
convention-classified, and only the points that are left go on to the
rules, memory and the model.
A convention's scope prefix (fbf/hospital-a) limits it to one site's
topics.
Measured
The mapping eval simulates an integrator:
Code
The simulated integrator writes 2 annotations for the mock hospital's
two label styles (fbf/vav-12/DAM-POS-345 and fbf/vav-3/DamperPos). It
then gives a code for each of the 8 equipment kinds. After that it answers
point codes one at a time, in the order the preview ranks them, until the
budget runs out. Each answer is the code's true class; a person would get
these from the drawings.
| Point codes answered | Points exact | Points left for review | Settled by the convention | Equipment exact |
|---|---|---|---|---|
| none (rules only) | 48.4% | 30.9% | n/a | 0% |
| 0 (only templates and 8 equip codes) | 48.4% | 30.9% | 0 | 100% |
| 5 | 64.8% | 16.3% | 119 | 100% |
| 10 | 79.1% | 12.2% | 214 | 100% |
| 20 | 85.2% | 6.1% | 295 | 100% |
| all 40 | 99.6% | 0.4% | 430 | 100% |
Auto-accepted but wrong stays at 0 in every row.
What this shows, and what it doesn't:
- The answers are correct by construction, because the simulated person doesn't make mistakes. The table measures effort against coverage: 2 annotations plus 28 short answers (8 equipment codes and 20 point codes) settled 295 points and all 88 pieces of equipment.
- It doesn't measure accuracy on a messy real site. There, codes collide
(
Tmeaning temperature on one controller and a timer on another), and conventions drift between integrators. - At "all 40", the 2 points left are the boilers' firing rate, which has no Brick class. As intended, the person leaves those.
openhay#7's shared tokenizer and abbreviation lexicon aren't built yet.
Once they are, the preview can pre-fill unknown codes such as SAT and
RAT from the lexicon instead of leaving them blank.

