ต่อไปนี้คือส่วนสำคัญของวิธีที่ฉันทำสิ่งต่างๆ และประเภทของการอนุมาน/การสร้างแบบจำลองที่เปิดใช้งาน
เกือบทุกอย่างที่เราใช้อยู่ภายใต้ OWL Lite ยกเว้นคุณสมบัติ owl:hasValue
ซึ่งเราใช้กำหนดการแมป 1-1 ระหว่างชุดแท็กและชื่อของคลาส ด้วยเหตุนี้ โซลูชันปัจจุบันจึงอยู่ภายใต้ OWL DL
นี่ก็หมายความว่าเราต้องการเหตุผลด้วย แต่โชคดีที่ไม่มีใครรองรับ OWL Full :) OWL-RL เป็นตัวเลือกที่ดีที่ใช้งานได้กับ RDFlib
# G is our RDFlib Graph
# apply reasoning to expand all of the inferred triples
import owlrl
owlrl . DeductiveClosure ( owlrl . OWLRL_Semantics ). expand ( G )
# get namespaces
print ( list ( G . namespaces ()))
G . query ( "SELECT ?x WHERE { ?x brick:hasTag tag:Equip }" )
เราสามารถจัดลำดับรูปแบบที่ขยายของกราฟลงดิสก์ได้ หากเราจำเป็นต้องใช้ตัวประมวลผลคิวรี SPARQL ที่ไม่รองรับการใช้เหตุผล
https://brickschema.org/schema/1.1.0/Brick#
owl:Class
และจัดเรียงเป็นลำดับชั้นด้วย rdfs:subClassOf
owl:equivalentClass
skos:definition
brick:AHU_Average_Exhaust_Air_Static_Pressure_Sensor
เป็นเพียง Average_Exhaust_Air_Static_Pressure_Sensor
ที่เป็นจุดหนึ่งของ AHUคลาสรูทที่เรากำหนดไว้คือ:
Equipment
Location
Point
Tag
Substance
Quantity
(ความสัมพันธ์เป็นคำอิฐสำหรับนกฮูก ObjectProperties ระหว่างอินสแตนซ์ของคลาส)
ในระดับผิวเผิน ความสัมพันธ์ดำเนินไปในลักษณะเดียวกับใน Brick ดั้งเดิม ความสัมพันธ์เดียวกันทั้งหมดยังคงมีอยู่ (โดยที่ฉันจำได้ว่าต้องกำหนดมัน) และพวกมันมีการผกผันที่กำหนดโดยใช้ owl:inverseOf
โดเมนและช่วงถูกกำหนดในแง่ของคลาส การระบุว่า rdfs:range
ของความสัมพันธ์เป็นของคลาส brick:Equipment
หมายความว่าอ็อบเจ็กต์ของความสัมพันธ์ควรเป็นตัวอย่างของคลาส brick:Equipment
ต้นแบบนี้รวมถึงความสัมพันธ์ย่อยนอกเหนือจากความสัมพันธ์ ความสัมพันธ์ย่อยสามารถใช้แทนความสัมพันธ์ขั้นสูงเพื่อเพิ่มรายละเอียดเพิ่มเติมให้กับลักษณะของความสัมพันธ์นั้น ตัวอย่างเดียวจนถึงขณะนี้คือ feedsAir
เป็นพร็อพเพอร์ตี้ย่อยของ feeds
สิ่งที่ต้องพิจารณาคือเราจะอนุมานความสัมพันธ์ feedsAir
ได้อย่างไร บางทีถ้าอุปกรณ์ปลายทางทั้งสองมีความสัมพันธ์ระหว่างแท็ก air
และ feeds
นี่อาจเป็นสิ่งที่จำเป็นต้องระบุอย่างชัดเจนแทนที่จะอนุมาน
https://brickschema.org/schema/1.1.0/BrickTag#
skos:definition
ซึ่งทำได้โดยการประกาศคลาส Brick (เช่น Air_Temperature_Sensor
) ให้เทียบเท่ากับคลาสที่ไม่ระบุชื่อ ซึ่งก็คือ owl:Restriction
ที่เป็นจุดตัดกันของเอนทิตีที่มีแท็กบางอย่าง
# in turtle format
brick:Temperature_Sensor a owl:Class ;
rdfs:subClassOf brick:Sensor ;
owl:equivalentClass [ owl:intersectionOf (
[ a owl:Restriction ;
owl:hasValue tag:Sensor ;
owl:onProperty brick:hasTag
]
[ a owl:Restriction ;
owl:hasValue tag:Temperature ;
owl:onProperty brick:hasTag
]
) ] .
owl:Restriction
คือชุดของคลาสทั้งหมดที่มี tag:Sensor
เป็นค่าของหนึ่งในคุณสมบัติ brick:hasTag
ซึ่งหมายความว่าเซ็นเซอร์อุณหภูมิ :ts1
สามารถกำหนดได้สองวิธีที่แตกต่างกัน และผู้ให้เหตุผลจะอนุมานค่าสามค่าอื่นๆ:
# using classes
:ts1 a brick:Temperature_Sensor
# using tags
:ts1 brick:hasTag tag:Temp
:ts1 brick:hasTag tag:Sensor
ตอนนี้ Brick กำหนดลำดับชั้นของสาร ( substances.py
) และลำดับชั้นของปริมาณ ( quantities.py
) สารและปริมาณอาจเกี่ยวข้องกับอุปกรณ์และคะแนน
ทั้งหมดนี้ไม่ได้ถูกนำมาใช้ ในต้นแบบปัจจุบัน เซ็นเซอร์เกี่ยวข้องกับสารและปริมาณผ่าน brick:measures
ความสัมพันธ์
:ts1 a brick:Temperature_Sensor
:ts1 brick:measures :Air
# this implies the following
:ts1 a brick:Air_Temperature_Sensor
เราสามารถแบ่งประเภทย่อยเพิ่มเติมของสารเพื่อให้บริบทระดับระบบหรือกระบวนการตามคำจำกัดความ:
:ts1 a brick:Sensor
:ts1 brick:measures brick:Return_Air
:ts1 brick:measures brick:Temperature
# implies...
:ts1 a brick:Return_Air_Temperature_Sensor
Brick ใช้ข้อจำกัดของ OWL เพื่อปรับแต่งคลาสตามความสัมพันธ์ดังกล่าว สำหรับตัวอย่างนี้ เนื่องจาก :ts1
วัด Air (โดยเฉพาะ brick:Air
) OWL จึงอนุมานเซ็นเซอร์ของเราเป็น brick:Air_Temperature_Sensor
คำจำกัดความของเต่ามีลักษณะดังนี้:
brick:Air_Temperature_Sensor a owl:Class ;
rdfs:subClassOf brick:Temperature_Sensor ;
owl:equivalentClass [ owl:intersectionOf ( [ a owl:Restriction ;
owl:hasValue brick:Temperature ;
owl:onProperty brick:measures ] [ a owl:Restriction ;
owl:hasValue brick:Air ;
owl:onProperty brick:measures ] ) ] .
หมายเหตุ : เรากำลังใช้คลาสเป็นค่าที่นี่ ซึ่งแตกต่างจากส่วนอื่นๆ ของ Brick สิ่งนี้เรียกว่า "การปั้น" นี่เป็นการหลีกเลี่ยงการต้องสร้างสารเพื่อให้เซ็นเซอร์ของเราตรวจวัดและอื่นๆ แต่ขอสงวนความเป็นไปได้ที่จะดำเนินการนี้ในอนาคต อินสแตนซ์ของสารสามารถจำลองบริเวณ/ชิ้นของ "สิ่งของ" ในขั้นตอนของกระบวนการ เช่น น้ำที่เข้าสู่เครื่องทำความเย็น หรือบริเวณอากาศผสมของหน่วยจัดการอากาศ
แทนที่จะหลงทางใน Sisyphean bikeshedding ของวิธีการจัดรูปแบบทุกอย่างเป็น YAML เราแค่ใช้พจนานุกรม Python ดังนั้นเราจึงไม่ต้องกังวลกับตรรกะการแยกวิเคราะห์ใดๆ (ก็ไม่มากขนาดนั้น)
definitions = {
"Lighting_System" : {
"tagvalues" : [ # Lighting_System class is equivalent to the Lighting tag
( BRICK . hasTag , TAG . Lighting ),
# if you have more required tags add them as their own tuple in the list
],
# defining subclasses. This can be nested ad-infinitum
"subclasses" : {
"Lighting" : {
"subclasses" : {
"Luminaire" : {},
"Luminaire_Driver" : {},
},
},
"Interface" : {
"subclasses" : {
"Switch" : {
"subclasses" : {
"Dimmer" : {},
},
},
"Touchpanel" : {},
},
},
},
}
}
define_subclasses ( definitions , BRICK . Equipment )
ในตอนนี้ รหัสคือเอกสารประกอบ ดูที่ equipment.py
, point.py
ฯลฯ เพื่อดูตัวอย่างและวิธีเพิ่มให้กับแต่ละลำดับชั้นของคลาส
ผู้เขียน: เก๊บ ฟิเอโร