Ingresses#

Ingresses are BuildingMOTIF’s mechanism for importing metadata from external sources. The Ingress APIs are deliberately general so that they can be easily extended to new metadata sources.

IngressHandler has two abstract subclasses:

  • RecordIngressHandler, which produces Records

  • GraphIngressHandler, which produces Graphs

Every concrete IngressHandler should inherit from one of these two classes.

Ingress Types#

Record Ingress Handler#

RecordIngressHandler defines one method: records() -> List[Record].

A Record is a simple Python data structure:

@dataclass
class Record:
    # a "type hint" or other identifier for an application-defined category of Records
    rtype: str
    # key-value pairs of data from the underlying source. Application-defined structure
    fields: dict

The choice of values for the Record is up to each RecordIngressHandler instance:

  • the BACnetIngressHandler uses the rtype field to differentiate between BACnet Devices and BACnet Objects. The fields field contains key-value pairs of different BACnet properties like name and units

  • the CSVIngressHandler uses the rtype field to denote the CSV filename, and uses the fields field to store column-cell values from each row of the CSV file

Graph Ingress Handler#

GraphIngressHandler defines one method: graph(ns: rdflib.Namespace) -> rdflib.Graph.

The rdflib.Graph returned by this method contains RDF data (inferred, translated, computed, etc) from some underlying source. GraphIngressHandlers source their metadata from either an upstream RecordIngressHandler or any other source provided in the instantiation of the GraphIngressHandler subclass.

Any new entities/URIs/etc created or inferred by the GraphIngressHandler should be placed into the provided namespace (ns). An instance of GraphIngressHandler is typically at the end of a pipeline of IngressHandlers.

Useful Built-in Ingress Handlers#

BuildingMOTIF provides several built-in ingress handlers. The full list can be found here.

BACnet Networks#

The BACnetIngressHandler takes an IP subnet as an argument (e.g. 10.0.0.1/24) and generates a set of Records corresponding to the BACnet devices and objects found on that subnet.

  • rtype: “object” if the Record represents a BACnet Object, else “device” if the Record represents a BACnet Device

  • fields: key-value pairs that differ based on rtype:

    • BACnet devices: address and device_id for BACnet devices

    • BACnet objects: device_id (for owning BACnet device) and all properties on the object

CSV Files#

The CSVIngressHandler takes a CSV filename as an argument (e.g. mydata.csv) and generates a set of Records corresponding to each row in the file.

  • rtype: the filename that contained the row

  • fields: key-value pairs for the row. The key is the column name; the value is the value of that column at the given row

Calling generate_csv on a Template will create an empty csv with headers. A CSVIngress made with this csv can be passed to TemplateIngress with that Template.

XLSX / Spreadsheet Files#

The XLSXIngressHandler takes a path to an .xlsx file as an argument and generates a set of Records for each row for each sheet in the spreadsheet file.

  • rtype: the sheet name containing the row

  • fields: key-value pairs for each row; the keys are the names of the columns and the values are the cell values at that column for the given row

Template Instantiation#

The TemplateIngress class instantiates a given Template with each of the Records generated by an upstream RecordIngressHandler. Instantiating TemplateIngress requires a Template instance (probably from a Library), an optional “mapper”, and an upstream RecordIngressHandler.

A “mapper” is a function which maps the column names of the CSV file to the parameters of a template. If “mapper” is left as None, then the TemplateIngress will use the column names as the parameter names.

There is also a TemplateIngressWithChooser class which acts essentially the same as TemplateIngress, but uses an additional function to dynamically choose the Template to be instantiated for each Record.

Examples#

BACnet to Brick#

See the BACnet to Brick guide

CSV Import#

See the CSV import guide