Protos

Overview

Prototypes or simply protos are dict templates. A proto is just a normal dict of name/value pairs along with a special tag expansion mechanism.

Protos are primarily used to declare typical sub-parts of an entity via the children tag. For example we use protos to answer questions such as "what points might be contained by a chiller?" Protos are generated into Project Haystack documentation. They also used to power menu options in vendor tools.

Format

By convention protos are formatted on a line per prototype using Zinc. Blank lines or lines starting with "//" are ignored. Each line is parsed as a dict. Example:

def: ^pipe
children:
  valve actuator equip
  flow point
  temp point

In this example we would parse each line into the following children protos:

{valve, actuator, equip}
{flow, point}
{temp, point}

You can see these children protos in the docs for pipe.

Flattening

Entities with children protos can specify that specific tags are flattened into their children. For example, Haystack convention dictates that points within a specific pipe include tags to indicate the pipe section and the fluid being sensed:

// parent pipe
steam leaving pipe equip

// child points
steam leaving valve actuator equip
steam leaving temp sensor point
steam leaving flow sensor point

This convention makes it easy to query points using tag combinations without regard to if or how parent pipes are modeled.

We use the childrenFlatten tag to indicate that these tags should be flattened into their children. In our pipe example:

def: ^pipe
conveys: ^fluid
pipeSection: ^pipeSectionType
childrenFlatten: [^fluid, ^pipeSectionType]
children:
  valve actuator equip
  flow point
  temp point

Flattening occurs when we are given an instance of a parent pipe and want to generate the children protos. We walk each symbol in the childrenFlattens list and if the parent implements the def, then it is flattened into each child proto. Lets look at some concrete examples:

First lets look at a parent pipe that implements neither a fluid term nor a pipeSectionType term:

// parent pipe
pipe equip

// children protos, no tags to flatten
valve actuator equip
flow point
temp point

In the following example, the parent pipe implements the fluid subtype of hot-water

// parent pipe
hot water pipe equip

// children protos include hot-water conjunct
hot water valve actuator equip
hot water flow point
hot water temp point

In the following example, the parent pipe implements both fluid via the subtype naturalGas and also pipeSectionType via the subtype entering:

// parent pipe
leaving naturalGas pipe equip

// children protos include both leaving and naturalGas
leaving naturalGas valve actuator equip
leaving naturalGas flow point
leaving naturalGas temp point

This technique becomes a powerful tool to auto-expand tag combinations when used with equipment containing known children:

def: ^chiller
children:
  chilled water leaving pipe equip
  chilled water entering pipe equip
  condenser water leaving pipe equip
  condenser water entering pipe equip

In the chiller example above it is not necessary to enumerate every possible combination of chiller point. Rather we declare that chiller's have four specific pipes. Using indirection we can then derive the various points by flattening the generic pipe definition.