BrickSchema / Brick

Uniform metadata schema for buildings
http://brickschema.org/
BSD 3-Clause "New" or "Revised" License
290 stars 78 forks source link

RFC: Units #26

Closed jbkoh closed 4 years ago

jbkoh commented 7 years ago

How should Brick represent units?

This RFC continues this

  1. Introduction Unit is a primary metadata to interpret/process data modeled with Brick. There was multiple requests to integrate units with Brick and there is no reason not to adopt it. However, designing every possible unit is not a feasible way as there are i) numerous units, ii) variations for same property (C vs F), and iii) various standards. Along the line I propose below:

  2. Proposal brick_unit 2

    (1) Structure: We limit only Point to have a unit. As discussed in the thread, Points directly having a unit is sufficient enough for systems we modeled. (2) Vocabularies: The vocabularies are adopted from QUDT.

    • Examples: FT2, MilliA, A, VOLT, KW, PowerFactor, KiloW-HR, HZ, ReletiveHumidity, DEG_C, DEG_F, HR, MIN, SEC, FT-PER-MIN, Parts-per-million, PERCENT, MegaW-HR, BTU-PER-FT2, PPM
  3. Required tasks (1) Add hasUnit property to BrickFram.ttl (2) Select units from QUDT (especially related to BACNet) and include them in Brick.ttl (or BrickUnit.ttl if necessary.) (3) Write units not defined in QUDT but in BACNet by using the related existing units. E.g., FT3-PER-MIN given FT-PER-MIN. (We could also add explicit definition of FT3-PER-MIN in the ontology.)

  4. Discussions (1) Unit changes across time: It is not included in the current proposal, but we could specify a unit to have a valid prediod (but needs another instantiation.) E.g., "DEG_F-1 begins 2017/1/1" and "DEG_F-1 ends 2017/1/31". It's a possibility with the current structure but again not included in this RFC. (2) There can be an argument that we should use less ambiguous words (e.g., Fahrenheit) to represent units and directly adopting QUDT vocabularies. However, some ambiguity is unavoidable unless we use full sentences to express units. I suggest to let QUDT community to handle it and we use them directly. In fact, there is no common standard for all kinds of units and any unit standard has similar problem. (3) Same argument for consistency issue as (2). Not all of QUDT vocabularies are consistent. E.g., KW and KillW-HR. I would let QUDT (4) QUDT version 2 is under revision so not all of the vocabularies are (4) Alternative vocabularies: UCUM: more consistent but less comprehensive and less expressive.

bbalaji-ucsd commented 7 years ago

Thanks Jason for starting this.

Suggestions:

Regards, Bharath

On Tue, Jul 18, 2017 at 2:11 PM, Jason Beomkyu Koh <notifications@github.com

wrote:

How should Brick represent units?

This discussion continues this https://groups.google.com/d/topic/brickschema/qmDxQi8LM5o/discussion

1.

Introduction Unit is a primary metadata to interpret/process data modeled with Brick. There was multiple requests to integrate units with Brick and there is no reason not to adopt it. However, designing every possible unit is not a feasible way as there are i) numerous units, ii) variations for same property (C vs F), and iii) various standards. Along the line I propose below: 2.

Proposal [image: brick_unit 2] https://user-images.githubusercontent.com/1572627/28339994-ff6f1082-6bc2-11e7-875c-1ff8d1e44645.png

(1) Structure: We limit only Point to have a unit. As discussed in the thread https://groups.google.com/d/topic/brickschema/qmDxQi8LM5o/discussion, Points directly having a unit is sufficient enough for systems we modeled. (2) Vocabularies: The vocabularies are adopted from QUDT.

  • Examples: FT2, MilliA, A, VOLT, KW, PowerFactor, KiloW-HR, HZ, ReletiveHumidity, DEG_C, DEG_F, HR, MIN, SEC, FT-PER-MIN, Parts-per-million, PERCENT, MegaW-HR, BTU-PER-FT2, PPM

    1.

    Required tasks (1) Add hasUnit property to BrickFram.ttl (2) Select units from QUDT (especially related to BACNet) and include them in Brick.ttl (or BrickUnit.ttl if necessary.) (3) Write units not defined in QUDT but in BACNet by using the related existing units. E.g., FT3-PER-MIN given FT-PER-MIN. (We could also add explicit definition of FT3-PER-MIN in the ontology.) 2.

    Discussions (1) Unit changes across time: It is not included in the current proposal, but we could specify a unit to have a valid prediod (but needs another instantiation.) E.g., "DEG_F-1 begins 2017/1/1" and "DEG_F-1 ends 2017/1/31". It's a possibility with the current structure but again not included in this RFC. (2) There can be an argument that we should use less ambiguous words (e.g., Fahrenheit) to represent units and directly adopting QUDT vocabularies. However, some ambiguity is unavoidable unless we use full sentences to express units. I suggest to let QUDT community to handle it and we use them directly. In fact, there is no common standard for all kinds of units and any unit standard has similar problem. (3) Same argument for consistency issue as (2). Not all of QUDT vocabularies are consistent. E.g., KW and KillW-HR. I would let QUDT (4) QUDT version 2 is under revision so not all of the vocabularies are (4) Alternative vocabularies: UCUM http://unitsofmeasure.org/ucum-essence.xml: more consistent but less comprehensive and less expressive.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQnxJEDyK4fLZnlAWqA4yq_R0Agzdks5sPR-MgaJpZM4Ob7gK .

jbkoh commented 7 years ago

Choosing the right vocabularies is the difficult problem. I am against adopting non-standard vocabularies if there are corresponding standard vocabularies. People can use them internally and map them to standard vocabularies, but we as a Brick should not suggest using them for interoperability. What is the boundary of non-standard convenient vocabularies and the others? We do not know. No matter what vocabularies we use, people need to look up our documentation. In that case, suggesting synonyms in documentations would be enough.

bbalaji-ucsd commented 7 years ago

Yes, that’s a valid point. If I were to have Fahrenheit and DEG_F, I’ll have to write “sameAs” (I forget the exact term we use) in my SPARQL every single time I use them. So, there is both a convenience and performance penalty. On the flip side, if people choose to use Fahrenheit internally, then they need to handle the transition somehow, we just remove it from our scope. I think the standards choice will still win out in terms of performance though.

However if we go with “no alternative names” way, the philosophy would need to be corrected in rest of Brick too. So should we remove alternative names such as “discharge air” and “supply air”?

What about abbreviations like AHU and F? Has a similar argument as above.

If we do go with the standards way, I would prefer something that is easy to understand rather than something I have to look up documentation for.

Regards, Bharath

On Tue, Jul 18, 2017 at 3:05 PM, Jason Beomkyu Koh <notifications@github.com

wrote:

Choosing the right vocabularies is the difficult problem. I am against adopting non-standard vocabularies if there are corresponding standard vocabularies. People can use them internally and map them to standard vocabularies, but we as a Brick should not suggest using them for interoperability. What is the boundary of non-standard convenient vocabularies and the others? We do not know. No matter what vocabularies we use, people need to look up our documentation. In that case, suggesting synonyms in documentations would be enough.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-316212090, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQm17dsN81FWvcAKyeFhbjJlItfDpks5sPSwigaJpZM4Ob7gK .

jbkoh commented 7 years ago

I agree with the philosophy of synonyms in Brick. Though we do not have to encourage it, we have to embrace it when it is needed.

Then, the problem would be how to decide what to include and what not to. It would be time-consuming and difficult for us to agree upon. That's the main reason that I just want to adopt predefined vocabularies (mainly from a source if possible.) But I am still open to ideas about it.

And whatever naming convention is adopted, people need to look up a documentation. Even if we use "Fahrenheit" (say it is the most straightforward vocab), users should confirm it from our documentation, which looks unavoidable to me.

bbalaji-ucsd commented 7 years ago

Agree with the problem that deciding on the standard nomenclature might be hard, and going through a discussion for each unit is perhaps wasteful given a standard.

Going by the examples you gave earlier:

This list is quite non-intuitive to me:

May be there is an explanation for these. I’m just reporting my observations.

My suggestions for the units:

The above things still doesn’t solve the problem you raised. Where will we get such a list of standardized units? I think BACnet and BMS data we have would be a good start. At least we know they are used by domain experts.

Regards, Bharath

On Wed, Jul 19, 2017 at 5:28 PM, Jason Beomkyu Koh <notifications@github.com

wrote:

I agree with the philosophy of synonyms in Brick. Though we do not have to encourage it, we have to embrace it when it is needed.

Then, the problem would be how to decide what to include and what not to. It would be time-consuming and difficult for us to agree upon. That's the main reason that I just want to adopt predefined vocabularies (mainly from a source if possible.) But I am still open to ideas about it.

And whatever naming convention is adopted, people need to look up a documentation. Even if we use "Fahrenheit" (say it is the most straightforward vocab), users should confirm it from our documentation, which looks unavoidable to me.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-316561327, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQliywcsI1MG9niL2ZL4nOy4Cxh9wks5sPp85gaJpZM4Ob7gK .

berkoben commented 7 years ago

Thinking out loud a bit here...

Naming:
I'm not sure I understand why there needs to be a replication of unit names in Brick. I would Imagine that a device in Brick would have a tag Like AHU1_FLOW_RATE_UNITCODE rdfs:instanceof qudt:code. Internally the graph might also have AHU1_FLOW_RATE_UNIT rdfs:instanceof qudt:someunit to make he linkage explicit

So a particular control system might have AHU1_FLOW_RATE_SETPOINT AHU1_FLOW_RATE_SENSOR AHU1_FLOW_RATE_UNIT[Code]

This implies the constraint that your setpoint and your sensor are in the same units, which is probably reasonable?

History: Any system that deals with dimensional quantities should standardize internally on a single system of measurement (I hope). This eliminates the need to understand the history of a unit. If Brick "compliance" were to be baked into a device, part of this should be the ability to convert to/from its own units to the Brick standard unit (Say, SI). This constraint makes client-server communication simple.

For devices that cannot communicate their unit to the server (either they don't know it or the data format does not support transmitting it), we can't really create any sort of quality control, even with history. The schema would just have to attach a unit to the device and we cross our fingers.

For devices that can communicate their units, the read case is simple. The write case would have to either have to do a read-write-read, or devices would have to reject commands that come with the wrong units.

Adding any sort of temporal statefulness seems fraught with problems.

bbalaji-ucsd commented 7 years ago

Thanks Keith.

For the uninitiated, can you please explain what qudt code is? I know it would be easy to look it up, but it would help every person who is following this thread to get some background on qudt.

We are having a separate discussion on where does Brick fit from a system perspective. We were imagining the use case where all of the Brick info is stored in some database, and the system handles the rest. Your use case of embedded system use case is something we haven’t considered at all. We also haven’t gotten deep into read and write capabilities, as we have considered the handling of timeseries as separate from Brick metadata. Can you illustrate more on this? We can take this discussion to a separate thread if appropriate.

Regards, Bharath

On Thu, Jul 20, 2017 at 3:49 PM, berkoben notifications@github.com wrote:

Thinking out loud a bit here...

Naming: I'm not sure I understand why there needs to be a replication of unit names in Brick. I would Imagine that a device in Brick would have a tag Like AHU1_FLOW_RATE_UNITCODE rdfs:instanceof qudt:code. Internally the graph might also have AHU1_FLOW_RATE_UNIT rdfs:instanceof qudt: to make he linkage explicit

So a particular control system might have AHU1_FLOW_RATE_SETPOINT AHU1_FLOW_RATE_SENSOR AHU1_FLOW_RATE_UNIT[Code]

This implies the constraint that your setpoint and your sensor are in the same units, which is probably reasonable?

History: Any system that deals with dimensional quantities should standardize internally on a single system of measurement (I hope). This eliminates the need to understand the history of a unit. If Brick "compliance" were to be baked into a device, part of this should be the ability to convert to/from its own units to the Brick standard unit (Say, SI). This constraint makes client-server communication simple.

For devices that cannot communicate their unit to the server (either they don't know it or the data format does not support transmitting it), we can't really create any sort of quality control, even with history. The schema would just have to attach a unit to the device and we cross our fingers.

For devices that can communicate their units, the read case is simple. The write case would have to either have to do a read-write-read, or devices would have to reject commands that come with the wrong units.

Adding any sort of temporal statefulness seems fraught with problems.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-316852078, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQi79HHCX1V9M3WmYi0bCvN-Pgmbsks5sP9lugaJpZM4Ob7gK .

berkoben commented 7 years ago

Let me know if this clarifies:

qudt:code rdf:type owl:DatatypeProperty ; qudt:description "A code is a string that uniquely identifies a QUDT concept. (from http://qudt.org/2.0/schema/SCHEMA_QUDT-v2.0.ttl)

Every unit in QUDT has a unique unit code. For instance: unit:DEG_F qudt:code "0525" ; (from http://qudt.org/2.0/vocab/VOCAB_QUDT-UNITS-THERMODYNAMICS-v2.0.ttl)

From my perspective as a systems designer, the ability to use Brick point names directly in representing and storing time series information is a major benefit because it maps extremely well to sparse no-SQL storage systems such as Cloud Bigtable. A schema like this allows the system to store any entity without changes to the underlying storage topology, yet still do intelligent things with the data absent any significant relational capability. Then you have a table keyed by the name of the device class instance [+timestamp], with columns representing each point for that device. Because points have very specific semantic meaning, you can do a whole lot with this not having any other information.

To achieve tidy schema agnostic storage like this, one would naturally eliminate the need to know units for each device from the timeseries storage (because they're represented as separate properties in Brick and make the storage story a lot messier). This is done simply by picking the measurement system that everything is stored in. (note that QUDT has the concept of measurement systems built in already).

Devices: in the long term the idea of a Brick-native device makes sense. Such a device would use proper point names when sending data:

DEVICE1234 { ZONE_TEMPERATURE_SENSOR: 73 ZONE_TEMPERATURE_SENSOR_SETPOINT: 72 ZONE_TEMPERATURE_SENSOR_UNITCODE: 0525 }

Note how it's easy to decompose the tagset here to separate out the device classname. Then the child tagsets are 1:1 mappable to columns in storage (for this reason I think synonyms should be discouraged). Non-compatible devices could have their data payloads translated to/from this format trivially.

A device doesn't need to know anything about the schema other than what points it has. Write is just a matter of patching the state. Different devices would have different methods of doing this, and the expectations for how a compliant device would behave are another topic (but completely tractable).

At present I'm not thinking about much more embedded processing on an individual device beyond being able to convert units it cares about.

Static Metadata: (my opinion) Brick itself should be responsible for enforcing things about what capabilities (points) a particular entity type should have, and what properties (unit types, min/max values, etc) points should have. For example, I want to know that when I have something of Type AHU, it will have INPUT_AIR_TEMP_SENSOR and that the units for this will always be rdf:type qudt:TemperatureUnit. This allows me to catch mis-configurations programmatically. (since Brick is extensible, this doesn't really impose any constraints on the user).

Building Graph (installation-specific metadata): This is the area Brick was originally focused on. A system should be able to understand both physical and control relationships as defined with the Brick ontology. If i'm writing a program, I want to be able to get a piece of sensor data for DEVICE1234 where a field is ZONE_TEMPERATURE_SENSOR, then make the appropriate graph query "what brick:location contains DEVICE1234" and find the room for which I can say something about temperature.

On Prem processing: Maybe this is what you meant by embedded processing?

I see on-prem processing as an extension of cloud processing. The natural way to do this would be to have a small amount of local time-series storage and then a replica of the relevant portions of the building graph closer to the edge. Functionality would degrade gracefully based on what devices, historical data and graph entities the on-prem device could see.

On Thu, Jul 20, 2017 at 4:00 PM, bbalaji-ucsd notifications@github.com wrote:

Thanks Keith.

For the uninitiated, can you please explain what qudt code is? I know it would be easy to look it up, but it would help every person who is following this thread to get some background on qudt.

We are having a separate discussion on where does Brick fit from a system perspective. We were imagining the use case where all of the Brick info is stored in some database, and the system handles the rest. Your use case of embedded system use case is something we haven’t considered at all. We also haven’t gotten deep into read and write capabilities, as we have considered the handling of timeseries as separate from Brick metadata. Can you illustrate more on this? We can take this discussion to a separate thread if appropriate.

Regards, Bharath

On Thu, Jul 20, 2017 at 3:49 PM, berkoben notifications@github.com wrote:

Thinking out loud a bit here...

Naming: I'm not sure I understand why there needs to be a replication of unit names in Brick. I would Imagine that a device in Brick would have a tag Like AHU1_FLOW_RATE_UNITCODE rdfs:instanceof qudt:code. Internally the graph might also have AHU1_FLOW_RATE_UNIT rdfs:instanceof qudt: to make he linkage explicit

So a particular control system might have AHU1_FLOW_RATE_SETPOINT AHU1_FLOW_RATE_SENSOR AHU1_FLOW_RATE_UNIT[Code]

This implies the constraint that your setpoint and your sensor are in the same units, which is probably reasonable?

History: Any system that deals with dimensional quantities should standardize internally on a single system of measurement (I hope). This eliminates the need to understand the history of a unit. If Brick "compliance" were to be baked into a device, part of this should be the ability to convert to/from its own units to the Brick standard unit (Say, SI). This constraint makes client-server communication simple.

For devices that cannot communicate their unit to the server (either they don't know it or the data format does not support transmitting it), we can't really create any sort of quality control, even with history. The schema would just have to attach a unit to the device and we cross our fingers.

For devices that can communicate their units, the read case is simple. The write case would have to either have to do a read-write-read, or devices would have to reject commands that come with the wrong units.

Adding any sort of temporal statefulness seems fraught with problems.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/ issues/26#issuecomment-316852078, or mute the thread https://github.com/notifications/unsubscribe-auth/ ADFqQi79HHCX1V9M3WmYi0bCvN-Pgmbsks5sP9lugaJpZM4Ob7gK .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-316854060, or mute the thread https://github.com/notifications/unsubscribe-auth/AZuyYlXqR4aZFVLKMzlIwu3Z_iPKFcXtks5sP9wDgaJpZM4Ob7gK .

bbalaji-ucsd commented 7 years ago

Thanks for the explanation Keith.

High level point:

Storage:

Devices: (This is what I meant by embedded systems processing)

Building Graph:

Back to units:

Regards, Bharath

On Thu, Jul 20, 2017 at 5:33 PM, berkoben notifications@github.com wrote:

Let me know if this clarifies:

qudt:code rdf:type owl:DatatypeProperty ; qudt:description "A code is a string that uniquely identifies a QUDT concept. (from http://qudt.org/2.0/schema/SCHEMA_QUDT-v2.0.ttl)

Every unit in QUDT has a unique unit code. For instance: unit:DEG_F qudt:code "0525" ; (from http://qudt.org/2.0/vocab/VOCAB_QUDT-UNITS-THERMODYNAMICS-v2.0.ttl)

From my perspective as a systems designer, the ability to use Brick point names directly in representing and storing time series information is a major benefit because it maps extremely well to sparse no-SQL storage systems such as Cloud Bigtable. A schema like this allows the system to store any entity without changes to the underlying storage topology, yet still do intelligent things with the data absent any significant relational capability. Then you have a table keyed by the name of the device class instance [+timestamp], with columns representing each point for that device. Because points have very specific semantic meaning, you can do a whole lot with this not having any other information.

To achieve tidy schema agnostic storage like this, one would naturally eliminate the need to know units for each device from the timeseries storage (because they're represented as separate properties in Brick and make the storage story a lot messier). This is done simply by picking the measurement system that everything is stored in. (note that QUDT has the concept of measurement systems built in already).

Devices: in the long term the idea of a Brick-native device makes sense. Such a device would use proper point names when sending data:

DEVICE1234 { ZONE_TEMPERATURE_SENSOR: 73 ZONE_TEMPERATURE_SENSOR_SETPOINT: 72 ZONE_TEMPERATURE_SENSOR_UNITCODE: 0525 }

Note how it's easy to decompose the tagset here to separate out the device classname. Then the child tagsets are directly mappable to columns in storage. Non-compatible devices could have their data payloads translated to/from this format trivially.

A device doesn't need to know anything about the schema other than what points it has. Write is just a matter of patching the state. Different devices would have different methods of doing this, and the expectations for how a compliant device would behave are another topic (but completely tractable).

At present I'm not thinking about much more embedded processing on an individual device beyond being able to convert units it cares about.

Static Metadata: (my opinion) Brick itself should be responsible for enforcing things about what capabilities (points) a particular entity type should have, and what properties (unit types, min/max values, etc) points should have. For example, I want to know that when I have something of Type AHU, it will have INPUT_AIR_TEMP_SENSOR and that the units for this will always be rdf:type qudt:TemperatureUnit. This allows me to catch mis-configurations programmatically. (since Brick is extensible, this doesn't really impose any constraints on the user).

Building Graph (installation-specific metadata): This is the area Brick was originally focused on. A system should be able to understand both physical and control relationships as defined with he Brick ontology. If i'm writing a program, I want to be able to get a piece of sensor data for DEVICE1234 where a field is ZONE_TEMPERATURE_SENSOR, then make the appropriate graph query "what brick:location contains DEVICE1234" and find the room for which I can say something about temperature.

On Prem processing: Maybe this is what you meant by embedded processing?

I see on-prem processing as an extension of cloud processing. The natural way to do this would be to have a small amount of local time-series storage and then a replica of the relevant portions of the building graph closer to the edge. Functionality would degrade gracefully based on what devices, historical data and graph entities the on-prem device could see.

On Thu, Jul 20, 2017 at 4:00 PM, bbalaji-ucsd notifications@github.com wrote:

Thanks Keith.

For the uninitiated, can you please explain what qudt code is? I know it would be easy to look it up, but it would help every person who is following this thread to get some background on qudt.

We are having a separate discussion on where does Brick fit from a system perspective. We were imagining the use case where all of the Brick info is stored in some database, and the system handles the rest. Your use case of embedded system use case is something we haven’t considered at all. We also haven’t gotten deep into read and write capabilities, as we have considered the handling of timeseries as separate from Brick metadata. Can you illustrate more on this? We can take this discussion to a separate thread if appropriate.

Regards, Bharath

On Thu, Jul 20, 2017 at 3:49 PM, berkoben notifications@github.com wrote:

Thinking out loud a bit here...

Naming: I'm not sure I understand why there needs to be a replication of unit names in Brick. I would Imagine that a device in Brick would have a tag Like AHU1_FLOW_RATE_UNITCODE rdfs:instanceof qudt:code. Internally the graph might also have AHU1_FLOW_RATE_UNIT rdfs:instanceof qudt: to make he linkage explicit

So a particular control system might have AHU1_FLOW_RATE_SETPOINT AHU1_FLOW_RATE_SENSOR AHU1_FLOW_RATE_UNIT[Code]

This implies the constraint that your setpoint and your sensor are in the same units, which is probably reasonable?

History: Any system that deals with dimensional quantities should standardize internally on a single system of measurement (I hope). This eliminates the need to understand the history of a unit. If Brick "compliance" were to be baked into a device, part of this should be the ability to convert to/from its own units to the Brick standard unit (Say, SI). This constraint makes client-server communication simple.

For devices that cannot communicate their unit to the server (either they don't know it or the data format does not support transmitting it), we can't really create any sort of quality control, even with history. The schema would just have to attach a unit to the device and we cross our fingers.

For devices that can communicate their units, the read case is simple. The write case would have to either have to do a read-write-read, or devices would have to reject commands that come with the wrong units.

Adding any sort of temporal statefulness seems fraught with problems.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/ issues/26#issuecomment-316852078, or mute the thread https://github.com/notifications/unsubscribe-auth/ ADFqQi79HHCX1V9M3WmYi0bCvN-Pgmbsks5sP9lugaJpZM4Ob7gK .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/ issues/26#issuecomment-316854060, or mute the thread https://github.com/notifications/unsubscribe- auth/AZuyYlXqR4aZFVLKMzlIwu3Z_iPKFcXtks5sP9wDgaJpZM4Ob7gK

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-316868284, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQgnsAPSlDM0rYWgWahfKmZLI_h9Rks5sP_HmgaJpZM4Ob7gK .

jbkoh commented 7 years ago

About QUDT's inconsistency: It is very unfortunate that some of its vocabularies are inconsistent. I would like to use a source for all units instead of us mapping or creating different units sources. If there is a better choice, I would like to use it.

A paper analyzed unit ontologies with 16 use cases: https://www.w3.org/community/owled/files/2016/11/OWLED-ORE-2016_paper_5.pdf Among the use cases I think following would make sense for us: UC 1: Manual annotation: requires consistent names. UC 2: Automatic annotation: requires textual descriptions. UC 3: Automatic translation: F -> C UC 10: Consistency between kind of quantity and unit of measurement: Temperature should have either F or C UC 16: Unit reference

OM is received best score among unit ontologies according to the paper: http://www.wurvoc.org/vocabularies/om-1.8/ https://github.com/HajoRijgersberg/OM However, its primary target is food research.

schema.org uses UN/CEFACT Common Codes for Units of Measurement: http://wiki.goodrelations-vocabulary.org/Documentation/UN/CEFACT_Common_Codes It's more verbose, but at least consistent. However, it's not an ontology that one can exploit for more than just annotation.

If any of you have suggestion (other than us creating vocabularies), I will take a look.

I would say to adopt QUDT and let QUDT community to handler consistencies as time goes on. And again, look-up is unavoidable. Even with consistent vocabularies, a user needs to check if the vocabulary is correct or not before using it though it will be easier.

bbalaji-ucsd commented 7 years ago

Spent some time reading through qudt, OM, and BACnet units ( http://bacowl.sourceforge.net/2012/bacnet.ttl).

For the first time, the last message (thanks Jason!) came out with reasons for why we should use qudt instead of saying it is a standard. And looking into it deeper at qudt.org, I can see that is a well designed system that’s focused on machine translation and consistency. The reason the units look so weird is that they follow some convention of relating different units. It also seems to be popular among semantic web enthusiasts.

However, I do think qudt is complex: http://www.qudt.org/release2/qudt-catalog.html Even finding a single unit took quite a bit of time. I’m not sure how we will convince users to pick the right units and use it correctly. I do think the lookup problem will be a barrier for adoption, especially given the current state of our documentation.

My vote will still go to BACnet units, given it covers the domain adequately and is an accepted standard in the community. However, given this long discussion, I don’t think this is as important as long as there is some consistent way to express units. If users push back, we can change it in the future.

Regards, Bharath

On Wed, Jul 26, 2017 at 7:37 PM, Jason Beomkyu Koh <notifications@github.com

wrote:

About QUDT's inconsistency: It is very unfortunate that some of its vocabularies are inconsistent. I would like to use a source for all units instead of us mapping or creating different units sources. If there is a better choice, I would like to use it.

A paper analyzed unit ontologies with 16 use cases: https://www.w3.org/community/owled/files/2016/11/OWLED-ORE- 2016_paper_5.pdf Among the use cases I think following would make sense for us: UC 1: Manual annotation: requires consistent names. UC 2: Automatic annotation: requires textual descriptions. UC 3: Automatic translation: F -> C UC 10: Consistency between kind of quantity and unit of measurement: Temperature should have either F or C UC 16: Unit reference

OM is received best score among unit ontologies according to the paper: http://www.wurvoc.org/vocabularies/om-1.8/ https://github.com/HajoRijgersberg/OM However, its primary target is food research.

schema.org uses UN/CEFACT Common Codes for Units of Measurement: http://wiki.goodrelations-vocabulary.org/Documentation/ UN/CEFACT_Common_Codes It's more verbose, but at least consistent. However, it's not an ontology that one can exploit for more than just annotation.

I would say to adopt QUDT and let QUDT community to handler consistencies as time goes on. And again, look-up is unavoidable. Even with consistent vocabularies, a user needs to check if the vocabulary is correct or not before using it though it will be easier.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318241636, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQnn568Hg0BCzjF-V3-3G9PyqmGaPks5sR_fZgaJpZM4Ob7gK .

jbkoh commented 7 years ago

My proposal for QUDT is not letting people to look up the entire QUDT but we adopt some of its vocabularies into our space so that users do not have to look-up all the vocabularies in QUDT.

If nobody likes it, BACNet standard should be considered instead of BACNet ontology (which is not a standard.) Here's the list I found: https://www.ccontrols.com/pdf/BACnet_Units.pdf

I personally do not see the benefit of using BACNet units much, but I already put enough effort to push a semantic model. If it did not work, I am fine with BACNet units.

bbalaji-ucsd commented 7 years ago

Replying inline.

On Thu, Jul 27, 2017 at 11:05 PM, Jason Beomkyu Koh < notifications@github.com> wrote:

My proposal for QUDT is not letting people to look up the entire QUDT but we adopt some of its vocabularies into our space so that users do not have to look-up all the vocabularies in QUDT.

I’m fine with this option. How would you do it? I’m assuming it is not a copy-paste of DEG_F, as all the benefits of ontology would be lost.

If nobody likes it, BACNet standards should be considered instead of BACNet ontology (which is not a standard.) Here's the list I found: https://www.ccontrols.com/pdf/BACnet_Units.pdf

I personally do not see the benefit of using BACNet units much, but I already put enough effort to push a semantic model. If it did not work, I am fine with BACNet units.

It would be good to highlight why an option is good/bad. Even better if there are examples. I’m picking the simplest option, i.e. BACnet units and the only reason is domain experts are familiar with it.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318568429, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQmU_f0nkhr6M2QE7eAU4xnw7wjCBks5sSXopgaJpZM4Ob7gK .

jbkoh commented 7 years ago

The pros and cons I think are:

BACNet units:

  1. Pros (1) Vocabularies are consistent. (2) Vocabularies are familiar to building experts.
  2. Cons (1) Vocabularies are limited. (2) Semantic conversion is not possible (though it could be possible through manual mapping to a semantic model.) (3) Not sure about its license. BACNet is a proprietary standard.

QUDT (or other semantic models.)

  1. Pros (1) Various vocabularies. (2) Conversion across different units / standards are possible. (3) CC license (copy-left opensource) (4) One can compose units with existing units.
  2. Cons (1) Vocabularies are inconsistent. (2) Vocabularies may not be familiar to building experts.

I think there is no common solution for everybody, but everybody has different philosophies. I said my stance a bit harsh but I totally understand the other side too.

bbalaji-ucsd commented 7 years ago

Okay, this makes sense.

Questions:

Regards, Bharath

On Fri, Jul 28, 2017 at 1:16 AM, Jason Beomkyu Koh <notifications@github.com

wrote:

  • I actually meant the copy-paste of DEG_F with its namespace. So we are sort of suggesting vocabularies in QUDT although users can try to find one or compose one directly from QUDT. If one uses qudt:DEG_F, it just works for both who just wants to annotate it and who wants to exploit the QUDT's semantics.

The pros and cons I think are: BACNet units:

  1. Pros (1) Vocabularies are consistent. (2) Vocabularies are familiar to building experts.
  2. Cons (1) Vocabularies are limited. (2) Semantic conversion is not possible (though it could be possible through manual mapping to a semantic model.) (3) Not sure about its license. BACNet is a proprietary standard.

QUDT (or other semantic models.)

  1. Pros (1) Various vocabularies. (2) Conversion across different units / standards are possible. (3) CC license (copy-left opensource) (4) One can compose units with existing units.
  2. Cons (1) Vocabularies are inconsistent. (2) Vocabularies may not be familiar to building experts.

I think there is no common solution for everybody, but everybody has different philosophies. I said my stance a bit harsh but I totally understand the other side too.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318591155, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQoxivbDXHYkOFoE6Fa6MfL4eOKOgks5sSZjdgaJpZM4Ob7gK .

gtfierro commented 7 years ago

I don't see this as really changing Brick; if you are aware of the units then you can add the annotation to the points w/n your Brick model. Adding units to Brick models should be encouraged, but we can't really make it necessary (other than adding a "best guess").

If a user wants to add new units, they can follow the same process as they always can when Brick is missing something: add it! With feedback, we can incorporate those units into Brick at a future date, but we should make an effort to have the set of units be as complete as possible.

I'm with Bharath in being in favor of using the BACnet units: they're straightforward, fairly complete (presumably if they needed more units, they'd add them) and don't have all the complex cruft of a large ontology that's trying to be "correct" and "semantically complete". QUDT is intimidating, and its not clear to me that we'd need all the rest of what it offers. The "units" w/n the Brick ontology do not need to capture the translations between units; all they need to do is capture what units belong to each point.

jbkoh commented 7 years ago

I see. All the semantic things could be deferred to be done by mapping at needs, which may not be significant efforts. I will just check with ASHRAE if we can use the terminologies directly.

berkoben commented 7 years ago

do BACnet units define conversion factors or group by systems of units? This is a very useful feature of QUDT for application development.

Similarly, if one wanted to be very strict (recommended) one could set a constraint to limit what family of units a :MeasurementProperty_PhysicalProperties subclass could have (ex: qudt:TemperatureUnit).

gtfierro commented 7 years ago

Conversion factors are helpful, to be sure, but do these need to be part of the ontology?

An important exercise, which we haven't done yet, is list what we need to use units for. Then, we can choose a solution based on whether or not it can accomplish what we need of a units system.

I can think of

any others?

berkoben commented 7 years ago

I would think of the actual engineering unit like the value of a point. As such, you could decouple the two ontologies by simply referring to the unit:

in the graph:

:ZONE_TEMPERATURE_SENSOR_UNITCODE a owl:class rdfs:subclassof qudt:code

:ZONE_TEMPERATURE_SENSOR a owl:class rdfs:subclassof :temperature_sensor bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

In your actual data:

ZONE_TEMPERATURE_SENSOR: 72 ZONE_TEMPERATURE_SENSOR_UNITCODE: 0525

Make sense?

On Fri, Jul 28, 2017 at 1:50 PM, Gabe Fierro notifications@github.com wrote:

Conversion factors are helpful, to be sure, but do these need to be part of the ontology?

An important exercise, which we haven't done yet, is list what we need to use units for. Then, we can choose a solution based on whether or not it can accomplish what we need of a units system.

I can think of

  • associate engineering units with a "point" (e.g. sensor, meter, command, setpoint)
  • convert a stream from one unit to another unit (e.g. wireless sensors in C vs a thermostat in F)

any others?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318758752, or mute the thread https://github.com/notifications/unsubscribe-auth/AZuyYssmxM3QFEKp5upRIAc0PrDaky44ks5sSkmigaJpZM4Ob7gK .

gtfierro commented 7 years ago

Almost makes sense to me, but not quite. There's no instances in your example, and instead we're attaching units (and numerical values?) to classes. Ignoring the numerical values (which are not part of this discussion), we'd probably have:

:ZONE_TEMPERATURE_SENSOR_UNITCODE a owl:class rdfs:subclassof qudt:code

:ZONE_TEMPERATURE_SENSOR a owl:class rdfs:subclassof :temperature_sensor bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR :sensor_123 bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

Is that what you mean? I do not believe we should have actual timeseries values modeled in Brick. This is the role of a different system; most likely a timeseries database. Brick can point to those streams w/n the database, but shouldn't represent the values itself.


What's the value of decoupling the ontologies through an opaque UNITCODE? The UNITCODE could just as easily be a BACnet-style unit name, which could then point to the QUDT ontology if we decide that's necessary. Again, I think this needs to be driven by use cases. Can we think of any other use cases besides those in https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318758752 ?

bbalaji-ucsd commented 7 years ago

I’m not sure this needs to be in the requirement list. If the user can identify that two sensors are in C and F respectively, then they can handle the conversion between them? What role can Brick play here?

For requirements: I would add that users should be able to extend Brick units if they don’t find one in the standard. I’m bringing focus to this because this extension is not straightforward if we use QUDT. They will have to ensure it is compatible to every other unit, etc.

I agree with Gabe and still side with using BACnet units. I don’t quite understand what the license issue is. They are just unit vocabularies right? Technically we don’t even need to mention BACnet if need be.

Regards, Bharath

On Fri, Jul 28, 2017 at 3:11 PM, Gabe Fierro notifications@github.com wrote:

Almost makes sense to me, but not quite. There's no instances in your example, and instead we're attaching units (and numerical values?) to classes. Ignoring the numerical values (which are not part of this discussion), we'd probably have:

:ZONE_TEMPERATURE_SENSOR_UNITCODE a owl:class rdfs:subclassof qudt:code

:ZONE_TEMPERATURE_SENSOR a owl:class rdfs:subclassof :temperature_sensor bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR :sensor_123 bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

Is that what you mean? I do not believe we should have actual timeseries models in Brick. This is the role of a different system; most likely a timeseries database. Brick can point to those streams w/n the database, but shouldn't represent the values itself.

What's the value of decoupling the ontologies through an opaque UNITCODE? The UNITCODE could just as easily be a BACnet-style unit name, which could then point to the QUDT ontology if we decide that's necessary. Again, I think this needs to be driven by use cases. Can we think of any other use cases besides those in #26 (comment) https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318758752 ?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318773789, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQgHDKNpK-cekC13YL5Dq0PKP6zbXks5sSlyEgaJpZM4Ob7gK .

jbkoh commented 7 years ago

@bbalaji-ucsd

All of the things we talked can be done manually even without Brick or any other standards. We wish adopting any standards could reduce the effort to do any processing, which is Brick's goal. Brick's role is not converting units, but Brick can let users to automate the process by adopting a well-defined semantic model, which is Brick's role (== choosing right standards to integrate.) Annotation capability which you are arguing is the minimal goal. I believe the disagreement comes from if a candidate (=QUDT) supports annotation capability well or not. A disagreement point should not be we don't need other than that. F->C conversion is the same story as why we need to use Brick instead of using any other vocabularies. Any other vocabularies can function same as Brick for a system.

About license issue: They defined the vocabularies, which is a part of standard. We cannot quote a sentence from any paper, right? Same in standards. We made significant effort to summarize what vocabularies are best in Brick. Though we made Brick with BSD, I don't think it does not have a license.

jbkoh commented 7 years ago

@gtfierro

I summarized use cases here.

There are more possible but not required use cases in the paper.

jbkoh commented 7 years ago

I don't know why UNITCODE is good to use as Gabe already mentioned. Is there any benefit of using UNITCODE other than they are shorter?

bbalaji-ucsd commented 7 years ago

If we are going with qudt, can we please discuss a concrete example? All of the automated translation and well-defined semantic model are too abstract to me. Examples can clarify how they add value compared to a simple vocabulary.

We can start with the example that Keith gave:

:ZONE_TEMPERATURE_SENSOR_UNITCODE a owl:class rdfs:subclassof qudt:code

:ZONE_TEMPERATURE_SENSOR a owl:class rdfs:subclassof :temperature_sensor bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR :sensor_123 bf:hasUnit :ZONE_TEMPERATURE_SENSOR_UNITCODE

On Fri, Jul 28, 2017 at 10:24 PM, Jason Beomkyu Koh < notifications@github.com> wrote:

I don't know why UNITCODE is good to use. Is there any benefit of using UNITCODE other than they are shorter?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-318805502, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQtEUHahJKkew8K44fkPLgGmxLxUOks5sSsIUgaJpZM4Ob7gK .

jbkoh commented 7 years ago

You are right. I will make some examples for the case after the paper.

gtfierro commented 7 years ago

Jason, those are use cases from another paper, which aren't necessarily our use cases, and some of them conflict with each other.

It seems like the only thing we need units for is to annotate the kind of units a particular point has, e.g.

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR :sensor_123 bf:hasUnit :DEGREES_FAHRENHEIT :DEGREES_FAHRENHEIT rdfs:subClassOf :TEMPERATURE_UNIT

So there's my pitch for the "BACnet" units. I think it covers all of the use cases we need.

berkoben commented 7 years ago

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR :sensor_123 bf:hasUnit :DEGREES_FAHRENHEIT

This is a reasonable way to describe soemthing for which you have statically defined units, but for the purposes of writing applications, having more than a unique name behind the unit is important. Critically, unit conversion factors to a standard system are particularly useful. Do you know if BacNET gives you the same conversion capability? Adopting something like QUDT solves this part without any additional work:

s/DEGREES_FAHRENHEIT/unit:DEG_f/

The use case I was trying to explain previously with _UNITCODE is the common case where a device will communicate its units directly as a separate field (ex: in BacNET it is a nested field within the point object). This value behaves like a setpoint, in the sense that it is a user-writable point value, but is coupled much more tightly to the related sensor and setpoint values. how would you propose to handle this case?

:property_123 rdf:type :TEMPERATURE_UNIT_SETTING? :property_123 bf:usedBy :sensor_123

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR // don't describe units explicitly?

~Keith

bbalaji-ucsd commented 7 years ago

Hi Keith,

Can you please explain with an example how would QUDT help with automated conversion of units?

I’m not sure I understood the second part.

Regards, Bharath

On Mon, Jul 31, 2017 at 10:38 AM, berkoben notifications@github.com wrote:

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR :sensor_123 bf:hasUnit :DEGREES_FAHRENHEIT

This is a reasonable way to describe soemthing for which you have statically defined units, but for the purposes of writing applications, having more than a unique name behind the unit is important. Critically, unit conversion factors to a standard system are particularly useful. Do you know if BacNET gives you the same conversion capability? Adopting something like QUDT solves this part without any additional work:

s/DEGREES_FAHRENHEIT/unit:DEG_f/

The use case I was trying to explain previously with _UNITCODE is the common case where a device will communicate its units directly as a separate field (ex: in BacNET it is a nested field within the point object). This value behaves like a setpoint, in the sense that it is a user-writable point value, but is coupled much more tightly to the related sensor and setpoint values. how would you propose to handle this case?

:property_123 rdf:type :TEMPERATURE_UNIT_SETTING? :property_123 bf:usedBy :sensor_123

:sensor_123 rdf:type :ZONE_TEMPERATURE_SENSOR // don't describe units explicitly?

~Keith

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-319140671, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQlP1G_r8UYxhA-rTivIQewHcoaRmks5sThEngaJpZM4Ob7gK .

gtfierro commented 7 years ago

I think there's two different issues here: 1) how do we represent units of a sensor within a Brick model, and 2) how does a device present/describe itself to a Brick model, which may include units

I don't want us to get confused in trying to optimize Brick for embedded and/or constrained devices. We can always implement some other mechanism in that device's communication that either explicitly or implicitly presents the units. From the perspective of Brick design, its much more important to have a clear representation of the units for a device. Coupling how a device presents/describes itself with Brick will lead us down the path of making assumptions about how those devices should work and communicate, which I don't believe is Brick's role here. Brick describes those resources; how those resources actually interact with a Brick model is an implementation detail, and not part of the conversation here.

I think regarding "automated" conversion, the question is how much of that resides within Brick, and how much of that is external (and perhaps obvious) information.

For example, if we are representing temperature units using QUDT, we'd have conversionMultiplier and conversionOffset edges off of a DEGREES_FAHRENHEIT node that describe the 5/9 and 32 involved converting between F and C. A script could query for those edges and generate the code necessary to convert.

Alternatively, knowing that DEGREES_FAHRENHEIT means Fahrenheit, and DEGREES_CELSIUS means Celsius, a program could do the conversion itself.

A more fundamental discussion is: what do we actually need out of a units system in Brick.

So far we have:

Are there any other use cases? I'm not counting the paper that Jason cited, because we're not sure that those use cases align with ours.

berkoben commented 7 years ago

Replying to Bharath,

If I understand QUDT correctly, the ontology defines a rdf:type qudt:BaseUnit (SI/Kelvin) as a common set of units through which to convert units and provides conversion factors from each defined unit into base units. Therefore, if you have any two compatible units (QUDT also defines unit types in such a way that one would automatically know if two units were compatible), you can convert between them with the provided factor by going through the common unit. A system can perform conversions generally for any two units with only the information provided in the ontology. Example (omitting unnecessary fields):

unit:DEG_F qudt:conversionMultiplier 0.5555555555555555556E0 ; qudt:conversionOffset 255.37037037037037037E0 ; qudt:quantityKind quantity:ThermodynamicTemperature ; ;

unit:DEG_R qudt:conversionMultiplier 0.5555555555555555556E0 ; qudt:conversionOffset "0.0"^^xsd:double ; qudt:quantityKind quantity:ThermodynamicTemperature ;

unit:DEG_R-HR qudt:quantityKind quantity:ThermalResistivity ;

If I have three different points with each of the three different units above, I know mechanically that DEG_F and DEG_R units are compatible because they have the same qudt:quantityKind. Similarly I know that I can't convert between those two and DEG_R-HR. As long as I have compatible units, converting between them is mechanical as well. Apply the conversion factors for one unit in one direction to get to the base units, then apply the conversion factor for the other unit in the opposite direction to get to that unit.

((100DEG_F * 0.5555) + 255.37 = Base Unit (310.93K) (Base Unit - 0) / 0.55 = 559.67 DEG_R

*Note: I think QUDT has an incorrect quantityKind in the DEG_C description , which is why it is not used above, but a DEG_F to deg_C conversion would be similar:

unit:DEG_C qudt:conversionMultiplier "1"^^xsd:double ; qudt:conversionOffset "273.15"^^xsd:double ;

((212DEG_F * 0.5555) + 255.37 = base unit (373.15K) (Base Unit - 273.15) / 1 = 100C

bbalaji-ucsd commented 7 years ago

Thanks Gabe, Keith! It is finally clear (to me at least) what QUDT provides w.r.t conversion of units.

I second Gabe that we need to establish the role of units in Brick to finalize this discussion. This would set the tone for future extensions to Brick as well. I agree with the first requirement, but not so convinced about the second.

I have the following points of discussion:

  1. In our current version of Brick, we have stayed away from quantifying relationships. For example, we stayed away from specifying how exactly a control system works, i.e. the logic behind impact of temperature setpoint change on supply air flow. We’ve also stayed away from specifying schedule of a setpoint. We made these design decisions as we decided that an ontology was not appropriate to capture this logic, and it would be better to delegate this to code. We have to revisit this design decision if we are encoding logic of converting units in Brick.

  2. We’ve stayed away from tying Brick to any “Brick reasoner”, i.e., a piece of software that needs to run with Brick for using the schema. The schema is complete in on itself. A reasoner/linter can be built using the schema, but the schema is independent of this reasoner. We have to revisit this design decision if we want to have “automated conversion”.

  3. If a user wants to add a unit that is not part of Brick yet, then our current suggestion is they simply create the unit in their namespace (e.g. myunits: exotic_unit). If I understand the suggestion of using QUDT correctly, we would require the user to add this unit in a way that is compatible with the rest of the units, and presumably has conversion factors to SI units. This is a daunting task for a building domain expert. I would admit it is actually a daunting task for me too. If this task were “easy”, how do we ensure the unit added does not break Brick use or it’s associated reasoner that would perform automated conversion? We need to seriously think about this extensibility issue, as this can happen frequently from my experience with BMSes.

Regards, Bharath

On Thu, Aug 3, 2017 at 6:08 PM, berkoben notifications@github.com wrote:

Replying to Bharath,

If I understand QUDT correctly, the ontology defines a rdf:type qudt:BaseUnit (SI/Kelvin) as a common set of units through which to convert units and provides conversion factors from each defined unit into base units. Therefore, if you have any two compatible units (QUDT also defines unit types in such a way that one would automatically know if two units were compatible), you can convert between them with the provided factor by going through the common unit. A system can perform conversions generally for any two units with only the information provided in the ontology. Example (omitting unnecessary fields):

unit:DEG_F qudt:conversionMultiplier 0.5555555555555555556E0 ; qudt:conversionOffset 255.37037037037037037E0 ; qudt:quantityKind quantity:ThermodynamicTemperature ; ;

unit:DEG_R qudt:conversionMultiplier 0.5555555555555555556E0 ; qudt:conversionOffset "0.0"^^xsd:double ; qudt:quantityKind quantity:ThermodynamicTemperature ;

unit:DEG_R-HR qudt:quantityKind quantity:ThermalResistivity ;

If I have three different points with each of the three different units above, I know mechanically that DEG_F and DEG_R units are compatible because they have the same qudt:quantityKind. Similarly I know that I can't convert between those two and DEG_R-HR. As long as I have compatible units, converting between them is mechanical as well. Apply the conversion factors for one unit in one direction to get to the base units, then apply the conversion factor for the other unit in the opposite direction to get to that unit.

((100DEG_F * 0.5555) + 255.37 = Base Unit (310.93K) (Base Unit - 0) / 0.55 = 559.67 DEG_R

*Note: I think QUDT has an incorrect quantityKind in the DEG_C description , which is why it is not used above, but a DEG_F to deg_C conversion would be similar:

unit:DEG_C qudt:conversionMultiplier "1"^^xsd:double ; qudt:conversionOffset "273.15"^^xsd:double ;

((212DEG_F * 0.5555) + 255.37 = base unit (373.15K) (Base Unit - 273.15) / 1 = 100C

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-320129660, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQhMv6kuhl_lCUzS8XnP_zSlEYI0Iks5sUm8jgaJpZM4Ob7gK .

berkoben commented 7 years ago

Responses by number:

  1. I think there's still a logical leap between unit conversions and control logic. Unit conversions are essentially static and universal. The conversion factor of a unit to another unit is a fundamental property of that unit that is inextricably tied to the semantics. This is different than a control relationship, which is user/manufacturer defined behavior. Knowing the unit of a point is essential to understanding its meaning, and once you know the unit you also know the type of unit and conversion factor by definition. Including the conversions and quantityKinds explicitly makes the ontology makes it much more powerful and useful without deviating from its fundamental purpose.

  2. I'm not sure I understand this. It seems to me that a completely described/constrained ontology could be validated by a generic RDF validator (which I assume exists somewhere in the universe). No custom "reasoner" would be required. Could you provide an example of what you mean by a reasoner?

  3. It seems like a reasonable constraint to expect someone using a unit that is not described already in a relatively complete ontology like QUDT (or equivalent) would be competent enough to describe this unit in the correct terms. By the time a user is extending the Brick schema, he/she is already pretty deep in the weeds and would need to be pretty sophisticated. A regular "domain expert" typically doesn't even touch BacNET directly, nevermind build semantic graphs without some tooling.

bbalaji-ucsd commented 7 years ago

Replying inline.

On Fri, Aug 4, 2017 at 10:02 AM, berkoben notifications@github.com wrote:

Responses by number:

1.

I think there's still a logical leap between unit conversions and control logic. Unit conversions are essentially static and universal. The conversion factor of a unit to another unit is a fundamental property of that unit that is inextricably tied to the semantics. This is different than a control relationship, which is user/manufacturer defined behavior. Knowing the unit of a point is essential to understanding its meaning, and once you know the unit you also know the type of unit and conversion factor by definition. Including the conversions and quantityKinds explicitly makes the ontology makes it much more powerful and useful without deviating from its fundamental purpose. 2.

I'm not sure I understand this. It seems to me that a completely described/constrained ontology could be validated by a generic RDF validator (which I assume exists somewhere in the universe). No custom "reasoner" would be required. Could you provide an example of what you mean by a reasoner?

Valid points. By a “reasoner” I meant the calculations w.r.t unit conversion. I’m not aware of any RDF validator that performs such conversions, but I admit I’m not familiar with them. So it comes down to delegating unit conversion to Brick and QUDT instead of a separate program that the user manages. If we go QUDT way, this comes with some sort of compute API to convert my units correct? What does this API look like? Is this part of Brick or QUDT? A simple example will help.

1.

It seems like a reasonable constraint to expect someone using a unit that is not described already in a relatively complete ontology like QUDT (or equivalent) would be competent enough to describe this unit in the correct terms. By the time a user is extending the Brick schema, he/she is already pretty deep in the weeds and would ned to be pretty sophisticated. A regular "domain expert" typically doesn't even touch BacNET directly, nevermind build semantic graphs without some tooling.

I disagree to this point. a) A user may simply want to use a unit that is already in their BMS. They are just using Brick to make things easier for them. By adding the responsibility of extending the Brick schema “in a proper way” for satisfying their use case is burdensome IMO. We should not impose them to know internals of Brick for them to use Brick in their buildings. b) I’ve done a proper user study of building managers and domain experts at various levels (attached report). I assure you that they deal with BACnet and a myriad of other system internals directly. And just because they know BACnet does not mean they understand RDF, ontologies and Brick, these require a different skill level. Usability aspects matter, and one of the most important requirements IMO. c) QUDT does not extensively cover building point units as Jason pointed out earlier.

You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-320300874, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQkY6wky6M4dDeTwrlkKAmiDQoybwks5sU054gaJpZM4Ob7gK .

jbkoh commented 7 years ago

Sorry I have been off from this discussion. I will try to answer below. Hope it is not repetitive. I listed use cases from the paper for Brick. Some of them might be an overkill while some of them are essential for Brick. We can discuss role of units in Brick with the following use cases.

  1. We need a reference of unit meaning. Who should map all of them? BACNet unit is just a vocabulary but does not have a reference to its meanings. Without definition, it's less useful. We could add all of them manually. But you know what happened for vocabulary definition documentation of Brick TagSets.

  2. Unit constraints for Points: As Bharath mentioned, we want to have constrainsts for sensors to have certain units. It is a desired feature for system developers as also Keith mentioned. ZNT should have a temperature related unit only. This is similar to what we wanna do with VAV mightHave ZoneTemperatureSensor. Here's an implementation with QUDT+Brick:

    SELECT ?s ?unit WHERE {
    ?s rdf:type brick:Sensor .
    ?s bf:hasTag ?m (or ?s bf:usesTag ?m)
    ?m rdfs:subClassOf* ?tagType.
    ?tagType owl:sameAs ?quantityType . (this should be known but it's better than us mapping units 
    to measurement tags.)
    ?quantityKind rdf:type qudt:QuantityKind .
    ?unit qudt:hasKind ?quantityType.
    }

    It returns possible units that each sensor can have. This query also can be modified to inference to generate units rules automation and/or unit validation. Another alternative is manually mapping all units to sensors. I would like to avoid any mundane jobs. This is also beneficial when we add a new unit. When we add a new unit, we can specify it is related to Temperature instead of adding this unit to all temperature-related sensors' restrictions.

  3. Systematic construction of new units: Providing a framework to construct a unit not in Brick instead of a user to write a arbitrary string. There can't be 'the' standard with complete vocabularies. A user should be able to construct her own units systematically. When there is a new unit unseen from Brick, it would be great if still we can calculate it if it is related to existing units.

  4. Unit conversion: as discussed above. An implementation is already given by Keith. FYI, an additional thing is that we could do it in a SPARQL query also. (Yeah I know we do not store data in our triple store.) I can't say it is an essential feature, but desirable if it does not compromise anything. How to implement this is not clear with QUDT in my head at the moment though it provides 'baseUnitDimensions' as explained in the conversion example.

bbalaji-ucsd commented 7 years ago

This SPIN stuff is wonderful (Thanks Jason!). A quick tutorial for those new to it: https://www.slideshare.net/HolgerKnublauch/spin-in-five-slides To summarize, SPIN is an extension of SPARQL that can be used to convert units automatically. The API looks similar to SPARQL. It is supported by many vendors, but not yet a W3C standard. I finally have a concrete answer on how unit conversion can work, with an API that makes sense.

SPIN also impacts our discussions on function blocks, constraints/rules, reuse, composable libraries. I won’t derail this conversation with SPIN, just leave a short comment here.

On users and usability:

Questions:

Jason: I don’t understand your SPARQL query on point (2). Is it running on Brick.ttl? Or a “Bricked” building model? How is it adding constraints?

Regards, Bharath

On Sat, Aug 5, 2017 at 5:31 PM, Jason Beomkyu Koh notifications@github.com wrote:

Sorry I have been off from this discussion. I will try to answer below. Hope it is not repetitive. I listed use cases from the paper for Brick. Some of them might be an overkill while some of them are essential for Brick. We can discuss role of units in Brick with the following use cases.

1.

We need a reference of unit meaning. Who should map all of them? BACNet unit is just a vocabulary but does not have a reference to its meanings. Without definition, it's less useful. We could add all of them manually. But you know what happened for vocabulary definition documentation of Brick TagSets. 2.

As also Bharath mentioned, we want to have constrainsts for sensors to have certain units. It is a desired feature for system developers as also Keith mentioned. This is similar to what we wanna do with VAV mightHave ZoneTemperatureSensor. Here's an implementation with QUDT+Brick:

SELECT ?s ?unit WHERE {?s rdf:type brick:Sensor .?s bf:hasTag ?m (or ?s bf:usesTag ?m)?m rdfs:subClassOf* ?tagType.?tagType owl:sameAs ?quantityType . (this should be known but such better than us mapping units to measurement tags.)?quantityKind rdf:type qudt:QuantityKind .?unit qudt:hasKind ?quantityType. }

It returns possible units that each sensor can have. This query also can be modified to inference to generate units rules automation and/or unit validation. Another alternative is manually mapping all units to sensors. I would like to avoid any mundane jobs. This is also beneficial when we add a new unit. When we add a new unit, we can specify it is related to Temperature instead of adding this unit to all temperature-related sensors' restrictions. 3.

Systematic construction of new units: Providing a framework to construct a unit not in Brick instead of a user to write a arbitrary string. There can't be 'the' standard with complete vocabularies. A user should be able to construct her own units systematically. When there is a new unit unseen from Brick, it would be great if still we can calculate it if it is related to existing units. 4.

Unit conversion: as discussed above. An implementation is already given by Keith. FYI, an additional thing is that we could do it in a SPARQL query also. (Yeah I know we do not store data in our triple store.) I can't say it is an essential feature, but desirable if it does not compromise anything. 5.

Constraints of units with measurement types: If we have a temperature sensor, we can restrict what units the temperature can have. We already have MeasurementType Tags. We can add unit restriction easily as system developers want. This is something like VAV can have a temperature sensor (but unit would be not suggestions but restrictions.) How to implement this is not clear with QUDT in my head at the moment though it provides 'baseUnitDimensions' as explained in the conversion example.

-

About complexity 1: We do not add anything but just adopting vocabularies. Nothing gets complicated but just different vocabularies whether we use BACNet or QUDT for users who just want to annotate.

About complexity 2: I personally think Brick should not target for building managers. Building managers do not understand anything related to metadata schema at all. It does not matter how much Brick is simple enough (building managers would not understand the current minimal version of Brick anyway.) Usability aspects is important but the usability should not defined in the information model level but at user-level (documentation, abstraction/tools, application). It is like source code and APIs. Source code does not have to be minimized with compromising performance. APIs should be usable enough. The reason why Google and Tridium like Brick is, which I heard, its expressivity but not its simplicity. If they needed simplicity they must have been satisfied with Haystack (such as the building application developers in industry usually do in my experience.) I argue that if there is a useful feature we should adopt it if it is not deviated from the original goal. Users should see abstraction of Brick such as documentation. The reason why people currently look into the ttl file directly is we have no proper documentations. In summary, I argue that we need rules encoded in Brick as an information model (no matter if it is a file or files) instead of us providing just an implementation.

About the decision of separating out rules outside an information model: I did not back up that decision. Rules are a part of information models though whether it is contained in a file or a few is unimportant. An information should be self-contained. If one wants to develop his own db/reasoner/shim/etc on top of Brick, Brick should follow all standards in RDF, where rules are defined. We can't alone construct a ecosystem. And the same philosophy as the above section applies here. Brick.ttl is not the target for usability optimization.

Reasoner vs external validators: SPARQL can be used for construction and other validation queries but not just for WHERE clauses if all information exist in the ontology. I admit that I haven't looked into an actual implementation, but here's an simple example of using SPARQL for reasoning (== inference): http://composing-the-semantic- web.blogspot.com.au/2009/09/currency-conversion-with- units-ontology.html http://composing-the-semantic-web.blogspot.com.au/2009/09/currency-conversion-with-units-ontology.html It is unfortunate there is no 'the' standard implementation of reasoning and validations (there are a few here and there including Jena and Blazegraph.) However, it is still important to follow standards to represent restrictions so that anybody can make their implementations. I don't think we want to force users to use our tools only. If there is a possibility of representing rules or conversions in a standard way without compromising the others, it should be considered.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-320478206, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQmiifbXUU-x95EkcWbPSvGou753Qks5sVQl_gaJpZM4Ob7gK .

jbkoh commented 7 years ago
bbalaji-ucsd commented 7 years ago

I wasn’t calling anyone a feature creep. It’s a technical term, I explained what it means and I linked the Wikipedia article: https://en.wikipedia.org/wiki/Feature_creep

I’ll excuse myself from this conversation.

Regards, Bharath

On Mon, Aug 7, 2017 at 3:52 PM, Jason Beomkyu Koh notifications@github.com wrote:

-

SPIN

  • The painful part of SPIN is that there is only one opensource implementation in Java, and there is no SPARQL endpoint implementation supporting SPIN other than TopQuadrant's commercial one (expensive.) That's why I was cautious to say using a reasoner engine (and SPIN) and probably that's one of the reasons why Gabe wants to implement his own version.
    • In case of you have not recognized, SHACL is kinda successor of SPIN from the same company and there is a more standardization movement of it (Danbri at schema.org looked using it.). It has various functionalities but validation would be the most compelling use case.
  • About defining users:

  • I don't argue to add features as much as possible and you don't have to call me a feature creep. The point here is that we should not sacrifice necessary features to make the ttl file look more clean. If you don't think a feature is necessary, that would be a good discussion point.
    • I think there is very low possibility that building managers instantiate Brick without tools by themselves. I saw a bunch of system integration vendors at IBCon. Building managers will purchase There needs to be a responsible integrator of Brick for building managers. They would not take the responsibility of converting their BMSes to use Brick (maybe possible as a proof-of-concept but not more than that.) Building managers will see Brick with a tool such as visualization tool like you developed before or BuildingDepot.
    • Building managers are definitely our target for application design. And Brick needs to be able to support that applications. I argue that there needs to be an abstraction between application and the managers for Brick but Brick itself should not be targeted directly for building managers but should cover all of building operations and system developments. If any feature goes beyond the scope of applications that building managers or operators or developers want, that feature is bad. If you reason a feature is not necessary, I'd listen to.
    • If you think we need a longer discussion on this, we can instantiate a new thread to discuss use cases more concretely.
  • Unit extension: I agree that we need to have a mechanism for users to add new units.

  • Effects on Brick schema:

  • We are discussing what the right vocabularies are. I was arguing QUDT vocabularies are better than BACNet vocabularies. Adopting means that we will include the vocabularies inside our schema file.

    • There can be various way of implementing adoption at schema level:

      • Adding vocabularies under Brick namespace: (here unit is QUDT's unit namespace.)

        brick:DEG_F owl:sameAs unit:DEG_F.

      • Just listing units

        unit:DEG_F rdf:type qudt:Unit.

      • Just documentation without writing into the schema file. Saying "Possible unit vocabularies are unit:DEG_F, unit:DEG_C, etc.

      • At instance level, either

      • With Brick name space,

        :ZNT-1 hasUnit brick:DEG_F

      • With QUDT name space,

        :ZNT-1 hasUnit unit:DEG_F

    The validation example

  • It can be either instance-level or schema-level depending on our decision. If we decide to include the possible units inside our schema file, we can run the query and add them to the schema, which reduces our mapping effort for development. We can do the same thing on an instance level with a linter or a reasoner.
    • I was giving the example as a query to show what units a point can has as an example instead of constructing a rule with it. if a point has another unit than the found valid units, we can mark them as invalid. It could be either implemented as a linter or reasoner with a similar syntax to the example. I don't have a concrete example of validation at the moment but I can make an example later (maybe with SHACL.)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-320802136, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQmtEOW4KzW5gCBI-pC3jk0qFuIK2ks5sV5UsgaJpZM4Ob7gK .

jbkoh commented 7 years ago

Sorry that I misunderstood the terminology. The link was broken and I did not look it up by myself. I thought it was a kind of slang indicating a person who pushing features without reasons. My apology.

Along the line, I would like to clarify what I said. I was not saying we should not consider building managers. I was saying there should be no sacrifices of features needed by building developers because of building managers because applications are the abstractions building managers will see (not raw Brick.).

jbkoh commented 7 years ago

Revitalizing the unit discussion, I summarize the features I think we need in Brick with units. (Let's defer what are best for the features.)

  1. Unit definition reference: Users should be able to find the definition of the unit (like with a link to the definition.)
  2. Rule checking: Whether a user assigned a proper unit for temperature sensor.
  3. Unified way of composing new units: Like composing new tagsets from existing tags.

Let me know if we want to add or subtract features.

berkoben commented 7 years ago

can you provide an example of what you mean by composing a new unit?

On Sat, Sep 2, 2017 at 6:31 PM, Jason Beomkyu Koh notifications@github.com wrote:

Revitalizing the unit discussion, I summarize the features I think we need in Brick with units. (Let's defer what are best for the features.)

  1. Unit definition reference: Users should be able to find the definition of the unit (like with a link to the definition.)
  2. Rule checking: Whether a user assigned a proper unit for temperature sensor.
  3. Unified way of composing new units: Like composing new tagsets from existing tags.

Let me know if we want to add or subtract features.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-326778688, or mute the thread https://github.com/notifications/unsubscribe-auth/AZuyYuo5w2oBcJE51XgyWPsEXUBjyt9gks5segF2gaJpZM4Ob7gK .

jbkoh commented 7 years ago

@berkoben
Sorry for the late reply. I was summarizing our necessities, but not sure if there is a perfect implementation of all the features. Here's what I was thinking of for composing new units.

Given basic units such as DEG_F and HR, many units would be composable with multiplication and divisions. Let's us say if we enumerate units (connected by hyphen), it means multiplication. And PER means division. Then, we could say DEG_F-HR == DEG_F multiplied by HR. If we say DEG_F-PER-HR, the unit means DEG_F divided by HR. In the case, a user can use "DEG_F-HR" if necessary even though it is not defined inside our system.

Numeric prefixes might be complicated as abbreviations are widely used for them. For example, ML = millimeter, but MBTU == million BTU. However, we can stick to conventions for each unit at least.

Irrelevant to me, QUDT had the same thought and internally decided to follow some rules as follows:

Rule 1: Underscore: qualifier of concepts
GAL_IMP

Rule 2: Numeric prefixes not separated from the unit
MilliJOULE should be as is
KG should be KiloGRAM

Rule 3: Hyphen
a) - separates units that should be multiplied together
b) -PER- separates numerator units from denominator units

Rule 4: Power
Number directly after a unit denotes that unit raised to the power of the
number

(@steveraysteveray, I am sharing the rules from your description at qudt-dev repository before. Let me know if this is not appropriate to share.)

There can be complex units that such convention cannot cover, but it would suffice most cases if base units are defined well. QUDT seemed to try to achieve such purpose with "conversionMultiplier" and "conversionOffset" but it looks not much useful without exact equations.

steveraysteveray commented 7 years ago

Jason,

        I’m fine with your sharing those naming rules for the qnames. Of course, these are just naming conventions to make things easier for humans. The formal relationships are in the model itself.

the conversionMultiplier and conversionOffset approach is the same as used in most of the units models.

(Removing noise texts by Jason)

jbkoh commented 7 years ago

@steveraysteveray Thanks for the prompt response. I totally agree that the naming convention is only for human. I definitely would like to use the explicit way of composing units. I have questions related to that, but will continue that discussion in a QUDT thread later.

berkoben commented 7 years ago

If we want to programmatically ensure compatibility between units, then quantityKinds would need to also be composable to allow for truly composable units. Absent this you'd have to require that every unit be explicitly defined. (though even in this case a standard for how things are named would be useful)

bbalaji-ucsd commented 7 years ago

Couple of things I noticed:

  1. How do you standardize between “Watt-second” and “second-Watt”. Seems like both are fair game by the above rules.
  2. “Watt-second” is actually already covered as “Joule”. How do you clear this ambiguity?

Regards, Bharath

On Thu, Sep 21, 2017 at 1:01 PM, berkoben notifications@github.com wrote:

If we want to programmatically ensure compatibility between units, then quantityKinds would need to also be composable to allow for truly composable units. Absent this you'd have to require that every unit be explicitly defined. (though even in this case a standard for how things are named would be useful)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-331265407, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFqQrJ8eWqiFt9iS9xhbJplBjcyVZg3ks5sksCfgaJpZM4Ob7gK .

jbkoh commented 6 years ago

@bbalaji-ucsd

steveraysteveray commented 6 years ago

I agree. The important things are the defined model relations, not what the URI actually looks like. In principle, the URIs could be serial numbers. There could be multiple rdfs:labels if you really wanted that. When searching for something that has dimensionality of (power x time) or of (time x power), it won’t matter.

(Removing noise texts by Jason)

jbkoh commented 6 years ago

@berkoben Sorry, could you elaborate more about the relationship between unit and quantityKind? I think having composition rules for quantityKind may be useful, but would like to understand its influence on units.

If you are talking about "Temperature should have Celsius or Fahrenheit as a unit", that's the second feature I mentioned in https://github.com/BuildSysUniformMetadata/Brick/issues/26#issuecomment-326778688 . I would like to rely on external sources for such features if possible.