#878 equipFunction and process suggestions

Mike Melillo Wed 23 Dec 2020

Edit: Revisions for clarity. After re-reading my notes here, I think what I'm ultimately suggesting is some sort of "equipFunction" and "process" reciprocalOf relationship, which is more than what I've put together as of yet. If anyone thinks there's something worth exploring more of here, I welcome the input.

I want to make some suggestions to flesh out the equipFunction and process defs more. The end-goal is to have them better describe the whole of an equip's sequence of operations when properly applied.

The major issue I run into right now is that these defs only describe the phenomenon affected and not the quantity. When drawing inferences between equipment that is related to another one's function or has a similar function, both the phenomenon and the quantity are crucial. I also think the verbiage of how several equipFunctions and processes are currently written lend themselves to my point. I have a few pasted below with my general summary statement of what an equipFunction or process actually is. However, to avoid needing to make process a subtype of choice as well, I think several processes can be reciprocalOf the same equipFunction -- I don't know if reciprocalOf is really the right def to apply though. Basically an equip can achieve the equipFunction cools: air-temp through several different processes (chilledWaterCooling, airCooling, dxCooling, etc) ... so having some relationship between those defs would allow making deeper inferences into what equipment is doing and how it is doing it.

Equipment conveys a substance or phenomenon

Equipment removes heat from a substance

Equipment removes moisture from air to decrease humidity

Equipment "equipFunction"s upon a "phenomenon"s "quantity"

Cooling by dissipating heat into the surrounding air

Cooling using transfer of heat to chilled water

"process" modifies "quantity" of target "phenomenon"

There are some exceptions, convey is the most straightforward one, although I suppose that could be overcome just by saying "elec-circuit conveys elec-power", but that feels like short-selling the whole thing. I'm not sure what to do in that instance.

Returning to the main point, I think the defs for all equipFunctions and processes should be modified like such:

def: cools
doc: Equipment removes heat from a substance
is: equipFunction
lib: phIoT
of: substance-quantity

def: chilledWaterCooling
doc: Cooling using transfer of heat to chilled water
is: coolingProcessType, chilled-water-input
lib: phIoT

Additionally, there should be a "twin" process that pairs with every equipFunction. The ideal scenario is that every equip could fully describe how its children points relate to its operation by having an equipFunction and process that somehow would relate to the points it contains. Take the following example, note flowProcess would be a child of choice, and damperModulation would be a child of an imaginary "flowProcessType" which is itself a child of process like coolingProcessType.

{id: @vav1, coolingProcess: airCooling, coolingOnly, cools: air-temp, regulates: air-flow, flowProcess: damperModulation}
{id: @sensor1, equipRef: @vav1, zone, air, temp, sensor}
{id: @sensor2, equipRef: @vav1, zone, air, temp, sp}
{id: @sensor3, equipRef: @vav1, zone, air, humidity}
{id: @sensor4, equipRef: @vav1, discharge, air, damper, cmd}
{id: @sensor5, equipRef: @vav1, discharge, air, flow, sensor}
{id: @sensor6, equipRef: @vav1, effective, discharge, air, flow sp}

If my interest is looking at issues on this VAV box, the current model is no issue, but if my desire is to find things related to this equipment's temperature or flow control processes, I have an issue. For instance, if I want to relate something that occurs between this vav box's Zone Temp & Zone Setpoint, I have to do some extra lifting to figure out that the only points I want to find on the related AHU are air-temp points, otherwise I end up with all form of sensors dealing with pressure, humidity, and who knows what else.

If my functions and processes already scope down to the phenomenon and quantity, it's a much more straightforward lift inferring what are the related up or downstream points (take the reverse example, I find an AHU problem and want to know which zones are affected in what way). I also think this has interesting implications for additional defs that can play together to fully describe an equips sequence of operations. If people are interested in this sort of idea, I could take a stab at fully fleshing out what I think process and equipFunction would look like.

Brian Frank Mon 4 Jan

These are good thoughts, thanks for your comments.

I am not sure the current design is quite right, because there definitely seems like there should be more of an ontological relationship between equipFunction and process. They are very close. What core ideas we are trying to capture is "what" and "how". For example an AHU cools air (what) using a process such as chilledWaterCooling (how). Or a boiler heats water (what) using a process such as fuelOilHeating (how).

But I think your core suggestion was along these lines:

// currently ahu
cools: ^air

// your suggestion
cools: ^air-temp

But by definition heats and cools is a process effecting temp. If anything we would want to move that into the equipFunction itself using some new association:

def: ^cools
is: ^equipFunction
of: ^substance
affectsQuantity: ^temp
doc: "Equipment removes heat from a substance."

Here I've added a tag named "affectsQuantity" to illustrate (but I'm not sure what we would call that). Both cool and heat affect temp. And dehumidifies and humidifies would affect humidity. However I'm not sure how else we might apply that. I guess you could say ventilates affects airQuality (which is the supertype of co, co2, pm10, pm25, and tvoc).

I'm almost thinking that maybe we should use the "good name" process for what is currently equipFunction.

Other thoughts?

Mike Melillo Mon 4 Jan

Thanks for the feedback, and yes regarding the core suggestion. I'm not sure you mean by "good name" process.

But taking the idea of a new association a bit further, I think there should be something like affectsQuantity and processUsed (using this for discussion's sake) to fully describe an equipFunction. My basic argument being an equipFunction is fully described when you can look at any implementation and fill in these blanks:

equipFunction: Performs this {{processUsed}} which modifies this 
{{quantity}} of this {{phenomenon}} using this {{input}}

Input would have to be inferred by the process. And the trick then is how to implement an equipProcess and associate it to the implemented processUsed. The resulting problem I can't wrap my head around is how to reshape the cools def so that when implemented it provides an association to say, a chilledWaterCooling process.

def: ^cools
is: ^equipFunction
of: ^substance
affectsQuantity: ^temp
processUsed: ^process
doc: "Equipment removes heat from a substance."

Implemented, that just lets me know my equipFunction requires some kind of process. Actually getting to the next step would require equipFunction being a choice of: ^substance-^process which sounds... super clunky? I'm not sure.

def: ^cools
is: ^equipFunction
of: ^substance-^process
affectsQuantity: ^temp
doc: "Equipment removes heat from a substance."
cools: air-chilledWaterCooling

At the end of the day it's just another conjunct. Maybe it wouldn't feel as rough if the process name was leaner and I'm getting too caught up in that.

Curious to hear more though. I think this being fully fleshed out leads to a lot of interesting inference based applications.

Mike Melillo Wed 20 Jan

Okay, back for another round... been playing with this idea and a few different structures in demo and on the back end of a few projects, going to add the latest round of thoughts.

equipFunction as the top level choice is the start of most problems I'm running into. So, with this round equipFunction is moved under the process def I suggest below. Additionally several current equipFunctions get moved up to that process level.

Put another way, some processes do more than influence a single phenomenon via mechanical or electrical action. These processes typically involve some kind of thermodynamic energy transfer. I'm suggesting the following structure to model them.

Also, defining these processes fully at implementation is too cumbersome. It is more effective to define each possibility within the ontology (within reason), and also maintain an extensible structure so custom applications do not have to break the mold.

The fully defined defs further below would simply be applied as marker tags to the equips that implement that process. This should allow for the removal of the current process subtypes (everything in coolingProcessType and heatingProcessType).

Additionally, these defs will define the input, output, quantity affected, and the direction that quantity flows.

doc:"Industrial or HVAC Process"

doc:"The quantity directly altered by some thermodynamic process or control strategy."



The above tags model the top level structure for a process which always output some phenomenon and affected quantity. In the case of heatTransfer we require both an input and an output because the heat has to flow from somewhere to somewhere else. From here a few things have to be done on some sort of convention.

The next tier of defs specifically calls out the output of that particular instance of the process. The next tier down defines the input.

This basically means the fully qualified process name is inputToOutputProcess, e.g. airToAirCooling indicating there is a thermodynamic flow from this entity to that entity (positive or negative).

It might be possible to make this less bloated by removing defs that call out the direction of heat or energy transfer (e.g. heatTransfer vs. heating + cooling)... not sure though.

The next set takes heatTransfer and then cooling to (most of) its logical conclusions.

doc:"Thermodynamic process where heat flows from the output to the input."

doc:"Thermodynamic process where heat flows from the input to the output."






is[^cooling, ^condenser-water-output]

is:[^cwCooling, ^air-input]

is[^cwCooling, ^refrig-input]









From there heating builds up pretty similarly. I put some work into humidityControl but not totally happy yet, but I'd like to hear what other people think.

Brian Frank Sun 31 Jan

Mike, these are fantastic thoughts and I'm glad you are thinking so deeply on this stuff. With the Haystack 4 ontology we can capture this stuff "behind the scenes" once the appropriate tags are applied. I've been mulling over your post, and here is what I'm thinking...

I think you are probably onto something with that the equipFunction and process taxonomies should align more.

Lets take this example: a natural gas fired steam boiler. In Haystack 4 we would tag that entity as follows:

naturalGasHeating steam boiler equip

Based on the current ontology we could infer:

  • the equip heats steam
  • the equip outputs steam
  • the equip inputs natural gas
  • the equip has a heating process using natural gas

So I do believe we are inferring the most salient points. Do you think something is lacking here? If so then the question is what? And if not, then the question is can we do more elegantly?

This brings us a key philosophical point: is it worth modeling the process of using natural gas to generate steam independent of the boiler equip? Or is by definition anything that implements that process a naturalGasHeating-steam-boiler?

While it is a somewhat academic question, it does frame how equipment focused the ontology design is versus conceptual. Without a doubt, we currently have the model completely designed around equip.

The main problems going down the path you suggest is the #1 problem we face for all modeling: the explosion of combinations. There is a wide variety of ways to combine input substance, output substance, and a process together. The question is that modeled through the equip taxonomy or independently through the process taxonomy?

But there are also equip functions like stores and conveys which don't really fit the model of energy conversion processes.

Another thing that I've struggled with resulting in an overly complicated "choice" design for exclusive/disjoint relationships is the gray line between ontology and instances. For example a conduit conveys something. A duct by definition always conveys air, therefore instances do not need to specify what they convey (its inferred from the ontology). However a pipe conveys any fluid, so you must specify on the pipe instance what it conveys. And add to that the fluid taxonomy is open ended and being extended all the time. Anytime we add a new fluid, we potentially have a new "pipe type".

So questions we should explore:

  1. Is something missing we want to infer from the boiler example?
  2. Could we do it more elegantly?
  3. How important is to separate specific processes from the equipment taxonomy?
  4. How does stores, conveys fit into your thoughts?

Mike Melillo Sun 21 Feb

I'm going to answer slightly out of order.

4. How does stores, conveys fit into your thoughts?

These would subtype from process, as they are something that the equipment does, but they do not require subtyping from ioProcess as there is not input/output scheme. They would still have a processSubject for the target of whatever is being stored or conveyed.

1. Is something missing we want to infer from the boiler example

2. Could we do it more elegantly.

I'll tackle these together as I think they're heavily related.

First, yes I do think something is missing. The boiler does, in fact, output steam. But naturalGasHeating is deeper than just allowing the boiler to produce steam in this case. Yes, the boiler is producing steam via naturalGasHeating, but it also regulates: steam-pressure.

I think this is where my original post of wanting a process to extend from phenomenon to phenomenon-quantity comes back in -- and it's also where my last post maybe didn't go far enough in laying out the example. This could get even more problematic with an equip that has multiple sensors of the same kind where the process only affects one... how can we efficiently infer which of mixed, discharge, return sensors on an ahu is being affected by a chilledWaterCooling process? This rabbit hole goes deep enough that it makes me wonder if it's more efficient to have process be an entity-ish record of sorts... note on this and type explosion at the end.

But I want to go further into the AHU example, with multiple sensors attached, and then expand to different kinds of equipment. If I have an AHU defined under the current model, it might look like this:

ahu equip chilledWaterCooling
 discharge air temp sensor
 mixed air temp sensor
 return air temp sensor
 chilled water valve cmd

Glancing at the points, I can infer as a human that my airstream is MAT -> Cooling Coil -> DAT ... But what does my AHU know about itself? Inherently, it outputs air, so that's a good start, and it's reasonable to assume that my processes are responsible for that air output. But which air sensor? Discharge does say in its doc that its the air leaving the equipment, but there's nothing that can be inferred on the machine level. Maybe that starts a whole separate item about ductSectionType and pipeSectionType, not sure.

Let's go a step further. There are, in fact, examples of units with coils on the return section of the ductwork. Modelling my ahu this way almost completely breaks down now. Do I have a return chilled water valve cmd ? Do I know that a water valved tagged with return under an ahu means that return refers to its location? Haystack does make room for this by allowing for duct equips as children of the ahu (and then sticking my valve in its appropriate home). Now my return-duct is probably implementing the chilledWaterCooling process. That does work but I think this is the part that could be more elegant -- should going this far down be necessary? Can the process intrinsically point to what entities it is related to within an equip? Offering insight to what points must be functioning for this process to take place successfully, and so on?

Backing up, I'm coming to the table here with certain goals, and they're influencing my perspective on what this could/should look like. When I think about inferring information about equipment, I'm basically looking to prompt my system with a Tell me about this thing type of query.

In response, I would want answers about what, why and how. What does it do? Implements a process Why does it do it? To produce output How does it do it? Consumes an input

My end-all goal here is root-cause analysis leveraged by the ontology and not by complex rules that analyze every combination of electromechanical control system seen to date -- or have an ontology that can be implemented almost on the fly to get me there. I'm bringing this up because I can't tell if having the ontology discriminate in this way closes off other roads, or is especially unwieldy in some way. If it closes off essential roads in some way, then it's a nonstarter. That said, I really don't know what to do about the explosion of types even if the roads can stay open. Again, type explosion at the end.

3. How important is to separate specific processes from the equipment taxonomy?

With my goal on the table, the next question is why prefer the process centric vs equip centric approach. By leaning towards the process, there are very general queries that will always produce the desired information.

For instance, in SkySpark I could do something like

read(entity).colNames().toGrid().findAll(t => def(parseSymbol(t), false)["is"] == ^ioProcess)

Once I have an equip's processes, grabbing my what/why/how entities is quick recursion of the ioProcess->is to find which ones subtype from process/output/input. By consolidating all of that information into the process structure, I can always ask for an equip's processes and never worry about unneeded information. Similarly, I can use this information as a map to cross reference when I'm looking for things in my system that input x or output y.

The part I really like is that this would work for any kind of equipment/process combination, because they're all consolidated to that one tag-set.

Re: Type Explosion

I don't have a good way to handle type explosion. There's simply a myriad of valid combinations. If it's going to be handled at the ontology level, I'm not sure there's a way to get around it. Another way I could see this playing out is if the process itself subtypes from list, and then everything is handled at implementation.

def: cooling
is: heatTransfer (which is ioProcess -> is process -> is list)

def: heatTransfer
is: ioProcess
processSubject: temp

{ equip, ahu, cooling: [ {inputs: chilled-water}, {outputs: discharge(?)-air} ] }

This feels... super clunky to do properly? Maybe it even changes and process becomes like point and lives as an entity, with tag-sets indicating what it does and how it does it. Not sure, but hopefully I've at least handled your questions in a way that illustrates what I think are the problems of the current approach.

annie mroz Thu 1 Apr

My question is sort of tangential to most of this discussion, but also on the topic of equipFunction so I'll just add it here.

I see from the docs that equipFunction is intended to be added to the def. So for example, a generic ahu in Haystack has the following equipFunctions: cools:air, dehumidifies: air, heats: air, ventilates: air. My impression is those equipFunctions are then used to determine the options for things like coolingProcessType? If an equip by definition, cools:air, it automatically gets a coolingProcessType?

My question is "Is there a way to specify equipFunctions on a per-instance(an entity in Haystack?) ? " Not every ahu heats, cools, dehumidifies, AND ventilates air, and it would be handy to specify equipFunctions on a per-equipment basis so they could be queried that way as well.

Mike Melillo Tue 6 Apr

Answering in order, these are my interpretations, not necessarily the actual rule for applying equipFunction and process

My impression is those equipFunctions are then used to determine the options for things like coolingProcessType? If an equip by definition, cools:air, it automatically gets a coolingProcessType?

As I've seen it currently implemented, equipFunction does not force the options for coolingProcessType. Right now the two are disconnected (which is largely the reason for this thread). And in fact, they don't need to be connected for the current implementation to make sense. When an equip cools: air, I would argue it does need a coolingProcessType to sufficiently define how it cools ... but cooling air doesn't narrow down which coolingProcessType to select on its own.

My question is "Is there a way to specify equipFunctions on a per-instance(an entity in Haystack?) ?

Yes this part is possible. The def for ahu, as I understand it, just lists the potential equipFunctions that def might use, but all of those functions are not mandatory on every instance of that particular def.

I still don't have very many good ideas to consolidate any of my earlier ramblings, though I would still contend this is an important item to address. Given that def explosion is being considered for point entities, I would consider my process explosion solution to be a valid candidate, though it does require curating that whole scheme.

annie mroz Wed 7 Apr

Brian Frank Mon 12 Apr

My question is "Is there a way to specify equipFunctions on a per-instance(an entity in Haystack?)

The way its currently designed: not really. The fundamental problem we try to solve with choices is to bridge the spectrum between meta-model and instance-model. For example all pipes by definition convey a fluid. But a specific instance of a pipe conveys a specific fluid - such as a hot-water-pipe.

From a type system perspective this allows us to narrow the types down as we create more specific subtypes of an equipment, and then all the way down to the instance level:

  1. Conduits convey a phenomenon
  2. Pipes convey a fluid, Ducts convey air (narrow in meta-model)
  3. A given pipe conveys a specific fluid such as hot-water, etc. But by definition all ducts convey air and there is no specific subtype of air to determine on a per instance basis (air is a leaf type)

The way its currently designed though is once a def narrows a choice down to a leaf type, then the instance doesn't have a chance to make the choice. So in the case of ventilates for example, there really isn't mechanism on a per instance basis to tag an ahu as ventilates or not. Its purely an equipment function in the ontology meta-model.

So the current design is not perfect, although its a really tough problem so I'm not sure what the best solution might be.

Based on Mike's previous comments, I do think think at the very least that we should consider collapsing the equipFunction and xxxProcess choices into one taxonomy. And maybe consider beefing up the meta-model for inputs and outputs. I am not sure exactly how that should look yet. And it might be nice to think about this problem that you raised Annie.

Login or Signup to reply.