schedules in brick - let's just use schema.org

88 views
Skip to first unread message

Erik Paulson

unread,
Jul 1, 2021, 6:06:53 PM7/1/21
to Brick User Forum (Unified Building Metadata Schema)
I’ve been looking at schedules, and I think what we should do in Brick is adopt Schema.org’s ‘Schedule’ type as our recommended practice:
https://schema.org/Schedule
https://github.com/schemaorg/schemaorg/issues/1457 - main discussion
https://github.com/schemaorg/schemaorg/pull/2389 - important extension

Schema.org in turn stole from ISO-8601 and iCal for time formats and for recurrence rules, which are things we don’t want to have to reinvent. That lets us say useful things, like “two hours starting at 10am every 3rd Monday of the month”. Using that same format would help with interoperability - imagine where we want to be able to exchange a building’s schedule to or from iCal and the various building subsystems.

The main use case is just to store a “schedule” but not try to directly interpret that schedule. In this use case, we would not (directly) be able to fire off a SPARQL query to find all buildings that are scheduled as “Open” right now - SPARQL doesn’t know how to interpret the ‘RRULE’ (example - Weekly on Tuesday and Thursday for five weeks:   DTSTART;TZID=America/New_York:19970902T090000
 RRULE:FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH  )
( see here for more: https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html )

This is roughly analogous to the BACnet ‘Calendar’ object, which in turn can be used by a BACnet ‘SCHED’ object for some automatic control. The BACnet ‘Calendar’ object is just a list of time ranges, and is either ‘True’ if the current system time is included in one of the time ranges described by the ‘Calendar’ object, or False otherwise. The BACnet ‘SCHED’ object contains more information about what to do when that ‘Calendar’ object is ‘True’ - what other objects should have their values changed, what to do when there are multiple ‘Calendar’ objects that might be ‘True’ right now, so you can override on the holidays, etc. (For now, Brick punts* on encoding the rest of what's needed for BACnet 'SCHED' objects)

The iCal RRULEs can say most of the things that a BACnet DatePattern can, though the BACnet DatePattern has some cool features, like ‘Even Days’ or ‘Odd Days’, or ‘Last 7 days of the month’, which means when translating between Brick RDF and BACnet you’d need some software to materialize/express it in something common (ie actually enumerate the last 7 days of each month) and periodically run a task to refresh/generate dates for future months. 

Schema.org calendars have some support for 'Exceptions' to schedules. If what they have isn't enough, schema.org moves reasonably quick and we could probably get an extension included quickly. 

The downside of just storing Schema.org calendars is that queries can’t use the schedule data without some additional software - but I think the most common scenarios will be cases where the users do need to load a schedule and run some computation on it anyway. In this case, Brick/Schema.org having a recommended way to find a schedule is enough to do for now. The big win is being able to share a common schedule across different building silos, so by keeping the scope for the Brick part somewhat limited, we’re actually increasing interoperability.

We could include a recommended ‘materialization’ of the RRULEs/time intervals/etc into RDF literals that would be more queryable - I think it’d be fine to use owl:time?  

The main artifact would be documentation in our expanding “best practices/how to use Brick” docs.

Some things to think about:
- We don’t need to add new entity types to Brick for schedules, but do we want a new Brick relationship for schedules, or is ‘hasPart’ good enough?
- If an entity doesn’t have a schedule, does it just get the schedule of some enclosing/parent/upstream entity?
- Keep an eye on the new Javascript Date library: https://tc39.es/proposal-temporal/docs/  
- *For the BACnet 'SCHED' object, eventually we want to think more about being able to express what to do when a control decision is needed/states change. For now, we'll leave that up to the upcoming BACnet RDF model, but someday we'll want to think about how to help translate 'the state is now Brick:buildingOpen' into something different building subsystems can act on

J Li

unread,
Jul 4, 2021, 5:32:36 AM7/4/21
to Brick User Forum (Unified Building Metadata Schema)
Cool,
I think it's more than storing a schedule, the schedule links to the class of status. For instance, if a room is scheduled with a meeting on Wednesday, the Fan Status, Occupancy Status, On_Off Status need to change. This goes both ways,  the status also affects room status. If an occupied room is not in the schedule, then an update is needed. Maybe define Schedule with the concepts of Zone and merge some concepts from Status, like
(Schedule_1, A, BRICK.Schedule),
(Schedule_1_Point, A, BRICK.Point),
(Status_1, A, BRICK.Point)
(Schedule_1, hasPoint, Schedule_1_Point)
( Status_1, isControlledBy, Schedule_1_Point)

Gabe Fierro

unread,
Jul 5, 2021, 11:07:37 PM7/5/21
to brick...@googlegroups.com

Hi Erik:

Thanks for putting this together! I really like the idea of adoption schema.org's Schedule.

I think the choice to store but not interpret the schedule is a reasonable one, and is in-line with our treatment of timeseries data and ISO8601 durations (for representing aggregations of point data). It is nice that the Schedule in schema.org is represented in RDF, so it would be possible to query some parts of the schedule even without parsing the RRULE or ISO8601 strings. I also really like the ability to capture Exceptions.

If we decide to move forward with the Schedule representation, we could produce a Python library that produces the materialization like you mentioned. The materialization should be able to be produced in multiple formats: the OWL time ontology is one option, but a JSON or CSV representation could also be helpful.

I will answer your questions at the end with *another* question!

What are the relationships between Brick entities and schedules that we want to capture?

If we relate schedules to Points, then that suggests that the relationship encodes that the value of the Point is dictated or informed by the Schedule. In schema.org, Schedules are related to Events, but we don't really have an equivalent of Events in Brick. Maybe we could create an Event subclass in Brick that captures the value of the Point at the Schedule epoch?

If we relate schedules to Location, then that suggests that the relationship encodes the occupancy or use of the Location at the Schedule epoch. Maybe we create another subclass of Event that captures the use of a Location? We could also borrow "type of event" or a similar concept from schema.org if that is equivalent. Prof Kjaergaard at SDU was working on defining uses/states of locations for buildings, so we can maybe build on that work.

I can't conceptualize the relationship of a Schedule to Equipment other than the schedule dictates the behavior of the equipment entity. However, I think this may be redundant with the Points idea above.

Best,

Gabe

--
You received this message because you are subscribed to the Google Groups "Brick User Forum (Unified Building Metadata Schema)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brickschema...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/brickschema/3b848ff0-8024-4cc2-b3d6-ac712ae263acn%40googlegroups.com.

Erik Paulson

unread,
Jul 6, 2021, 2:24:19 PM7/6/21
to Gabe Fierro, Brick User Forum (Unified Building Metadata Schema)
Right - there's a question of "what does it mean when the current time falls into an interval specified by the schedule?", which I guess you could also split up into two parts: 
"when the current time falls into this range the schedule is 'True' and is 'False' otherwise"
and
"do 'X' when this schedule is 'True'"

Schema.org has it kinda easy - the 'eventSchedule' property of an 'event' is just implicit "this event is happening when this schedule is "True"

My impression is that the schema.org 'schedule' object started out as being meant for events, but is sufficiently generic that it can be used on things other than 'events' - see this comment on how the 'schedule' type could replace the different 'opening hours' types that are the bread and butter of schema.org (ie can power the nice UI in google maps that says what a store's hours are,etc)
https://github.com/schemaorg/schemaorg/issues/1457#issuecomment-314069702 

similarly, Dan B anticipated that the schedule object could fit into IoT-like applications

What I liked about the BACnet 'SCHED' object, if I'm reading it the correct way, is that  the 'SCHED' object can be separate from its 'Calendar' object, and is like a 'Point'. The 'SCHED' object contains a list of other objects that should change when the related 'Calendar' object becomes 'True' and what values those objects should take on. (You can orchestrate fancier changes downstream from that, e.g. use the 'SCHED' object to set a space to 'INACTIVE' - and then have other logic in your BMS that turns 'OFF' when the space is 'INACTIVE') 

There's part of me that doesn't want to do anything with the schedule object in Brick, and just leave it to downstream to figure it out. Or maybe we take it one tiny step further and just have some Brick 'enums' along with the other scalar types and just say 'The Schedule object takes on this value when the current time falls into this interval' rather than just saying 'the schedule is True' and then leave it to downstream to figure out. 

-Erik


Erik Paulson

unread,
Jul 6, 2021, 5:07:17 PM7/6/21
to Gabe Fierro, Brick User Forum (Unified Building Metadata Schema)
BTW - I was curious about the BACnet date patterns <-> RRULES mappings, and some of the things BACnet can say are easier to say with RRULES than I thought. It's not quite as compact as the BACnet version but you leave it open-ended and run forever.  

BACnet has a cool feature for saying "Week of the month" - it's an integer, and maps like this:
1: Days 1-7
2: Days 8-14
3: Days 15-21
4: Day 22-28
5: Day 29-31
6: Last 7 days of the month

The 'bymonthday' specifier for the RRULES can say all of these. Here's a rule that covers option 5:
RRULE:FREQ=DAILY;WKST=MO;BYMONTHDAY=29,30,31
and here's a rule that covers option 6:
(I don't think 'Daily' or 'monthly' matter here?)

You can try them out on this site:

BACnet also has a shorthand for even and odd days - BACnet can say for a "Day of the month"
1-31: As expected
32: Last Day of the month
33: Odd days of the month
34: Even days of the month

'bymonthday' helps here too - this rule generates the odd days - note that it creates a date for both Sat July 31st and Sunday August 1st:
https://jakubroztocil.github.io/rrule/#/rfc/RRULE:FREQ=DAILY;INTERVAL=1;WKST=MO;BYMONTHDAY=1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
and this generates the last day of each month:

Again the BACnet representation is more compact, but it's super-clear how to go from BACnet to RRULE, and I think you could add in some logic to look at an RRULE and decide if it's safe to go to the BACnet compact representation.  Joel mentioned off-list that the BACnet RDF representation was going to keep the BACnet time encodings (which is what you'd expect) but I think it won't be too hard to go between the representations. 

-Erik

ps one bummer is that non-gregorian calendars aren't well-supported yet, e.g run this once a year on Chinese New Year. There's RSCALE but I don't think it's widely implemented yet: https://datatracker.ietf.org/doc/html/rfc7529
Reply all
Reply to author
Forward
0 new messages