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 producesRecord
sGraphIngressHandler
, which producesGraph
s
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 thertype
field to differentiate between BACnet Devices and BACnet Objects. Thefields
field contains key-value pairs of different BACnet properties likename
andunits
the
CSVIngressHandler
uses thertype
field to denote the CSV filename, and uses thefields
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.
GraphIngressHandler
s 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 IngressHandler
s.
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 Record
s corresponding to the BACnet devices and objects found on that subnet.
rtype
: “object” if theRecord
represents a BACnet Object, else “device” if theRecord
represents a BACnet Devicefields
: key-value pairs that differ based onrtype
:BACnet devices:
address
anddevice_id
for BACnet devicesBACnet 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 Record
s corresponding to each row in the file.
rtype
: the filename that contained the rowfields
: 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 rowfields
: 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 Record
s 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