Extracting values with a shape map¶
A shape map returns the values that satisfied a shape’s property constraints. Use one to find sensors, build a configuration, or feed validated values into an application. Install Shifty as described in Install Shifty.
Describe the values to find¶
In this example, each VAV should have a temperature sensor and an airflow sensor. The shapes name those two slots. Save and run this Python script:
import shifty
shapes = """
@prefix ex: <http://example.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
ex:VavShape a sh:NodeShape ;
sh:targetClass ex:Vav ;
sh:property [
sh:path ex:hasPoint ;
sh:name "supply air temperature" ;
sh:qualifiedValueShape [ sh:class ex:SupplyAirTemperatureSensor ] ;
sh:qualifiedMinCount 1 ] ;
sh:property [
sh:path ex:hasPoint ;
sh:name "airflow" ;
sh:qualifiedValueShape [ sh:class ex:AirFlowSensor ] ;
sh:qualifiedMinCount 1 ] .
"""
data = """
@prefix ex: <http://example.org/> .
ex:vav-1 a ex:Vav ; ex:hasPoint ex:sat-1 .
ex:sat-1 a ex:SupplyAirTemperatureSensor .
ex:vav-2 a ex:Vav ; ex:hasPoint ex:sat-2, ex:flow-2 .
ex:sat-2 a ex:SupplyAirTemperatureSensor .
ex:flow-2 a ex:AirFlowSensor .
"""
smap = shifty.shape_map(data, shapes, infer=False)
for mapping in smap["http://example.org/VavShape"]:
print(mapping.focus, "conforms:", mapping.conforms)
for key, binding in mapping.successful:
print(" ", binding.name, binding.values)
<http://example.org/vav-1> conforms: False
supply air temperature [Iri(value='http://example.org/sat-1')]
<http://example.org/vav-2> conforms: True
airflow [Iri(value='http://example.org/flow-2')]
supply air temperature [Iri(value='http://example.org/sat-2')]
vav-2 satisfies both requirements. vav-1 lacks an airflow sensor, but
its temperature sensor is still available as a successful binding.
Use the bindings¶
Add this after the loop to build a dictionary for the conforming VAV:
mapping = next(
row for row in smap["http://example.org/VavShape"] if row.conforms
)
for name, values in sorted(mapping.value_map(by="name", python=True).items()):
print(name, values)
airflow ['http://example.org/flow-2']
supply air temperature ['http://example.org/sat-2']
The keys come from sh:name. Each value is a list because a property may
match several nodes. python=True converts RDF terms to Python values.
Failed bindings are omitted from this dictionary.
Continue with Extract bindings with a shape map to inspect missing values, annotate bindings, and serialize a map. The shape-map reference lists the available fields and methods.