Skip to content

Instantly share code, notes, and snippets.

@kenwebb
Last active March 5, 2017 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenwebb/15846b39ba78a15491b351d6ef96bc65 to your computer and use it in GitHub Desktop.
Save kenwebb/15846b39ba78a15491b351d6ef96bc65 to your computer and use it in GitHub Desktop.
Shower and Tub
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Sun Mar 05 2017 06:32:54 GMT-0500 (EST)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: Shower and Tub
Description:
Url: http://www.primordion.com/Xholon/gwt/
InternalName: 15846b39ba78a15491b351d6ef96bc65
Keywords:
My Notes
--------
March 1, 2017
Model the various fixtures found in getting water to a shower and bathtub.
Possibly have active objects flowing through a system of pipes.
There are serial and parallel pathways.
Can I create a shower and tub system without needing any Xholon ports, where water always just flows to the next sibling, unless it's specified as a parallel pathway.
don't use any explicit ports
if an active object (a unit of water) reaches the end of a sibling chain, then it could mode to it's parent's next sibling
Maybe I need: OR pathway, AND parallel pathway, serial pathway
is there a basic theory about this?
some google queries, and other possibly-related topics/concepts/tools:
pipe and filter
household water simulation
UML activity diagrams
perhaps ports should be set up dynamically at run time
each node could have an entry and exit port
entry port does not need to be explicit
exit port could be changed, such as by a Diverter (OrNode)
TODO
- When a WaterUnit (an Avatar) moves into an OrNode, it should move immediately into the OrNode's onlyChild.
If it's a direct child of the OrNode, it's act() function will never be called.
For now, to get around this, WaterPressure calls WaterUnit.action() .
References
----------
() https://en.wikipedia.org/wiki/Tap_water
Everything in a building that uses water falls under one of two categories; fixture or appliance.
Fixtures are devices that use water without an additional source of power.
() https://en.wikipedia.org/wiki/Valve
A valve is a device that regulates, directs or controls the flow of a fluid (gases, liquids, fluidized solids, or slurries) by opening, closing, or partially obstructing various passageways. Valves are technically fittings, but are usually discussed as a separate category. In an open valve, fluid flows in a direction from higher pressure to lower pressure.
() https://en.wikipedia.org/wiki/Tap_(valve)
A tap (also spigot or faucet: see usage variations) is a valve controlling the release of a liquid or gas.
Faucet is the most common term in the US, similar in use to "tap" in British English.
Water for baths, sinks and basins can be provided by separate hot and cold taps; this arrangement is common in older installations, particularly in public washrooms/lavatories and utility rooms/laundries. In kitchens and bathrooms mixer taps are commonly used. In this case, hot and cold water from the two valves is mixed before reaching the outlet, allowing the water to emerge at any temperature between that of the hot and cold water supplies.
For baths and showers, mixer taps frequently incorporate some sort of pressure balancing feature so that the hot/cold mixture ratio will not be affected by transient changes in the pressure of one or the other of the supplies. This helps avoid scalding or uncomfortable chilling as other water loads occur (such as the flushing of a toilet). Rather than two separate valves, mixer taps frequently use a single, more complex, valve controlled by a single handle (single handle mixer). The handle moves up and down to control the amount of water flow and from side to side to control the temperature of the water. Especially for baths and showers, the latest designs do this using a built-in thermostat. These are known as thermostatic mixing valves, or TMVs, and can be mechanical or electronic. There are also faucets with color LEDs to show the temperature of the water.
() https://en.wikipedia.org/wiki/Shower
()
]]></Notes>
<_-.XholonClass>
<PhysicalSystem/>
<PipeSystem/>
<FluidUnit superClass="Avatar">
<WaterUnit/>
</FluidUnit>
<WaterPressure superClass="Script"/>
<Pipe/>
<Valve>
<Diverter superClass="OrNode"/> <!-- "A valve used to change the flow of fluid through a system of pipes" https://en.wiktionary.org/wiki/diverter; select tub or shower; an OrNode under user control -->
<Faucet/>
<MixerTap/> <!-- HotColdSelector -->
<VolumeSelector/>
<OnOffSelector/>
</Valve>
<ComboValve/> <!-- a serial pathway -->
<ParallelPathway superClass="OrNode"/> <!-- it will randomly change it's onlyChild reach timeStep -->
<ShowerHead/>
<Drain/>
</_-.XholonClass>
<xholonClassDetails>
<Pipe xhType="XhtypePureActiveObject">
<port name="port" index="0" connector="../../ComboValve"/>
</Pipe>
<Faucet xhType="XhtypePureActiveObject">
<port name="port" index="0" connector="../../Drain"/>
</Faucet>
<ShowerHead xhType="XhtypePureActiveObject">
<port name="port" index="0" connector="../../Drain"/>
</ShowerHead>
<MixerTap xhType="XhtypePureActiveObject">
<port name="port" index="0" connector="../VolumeSelector"/>
</MixerTap>
<VolumeSelector xhType="XhtypePureActiveObject">
<port name="port" index="0" connector="../../Diverter"/>
</VolumeSelector>
<WaterUnit>
<Color>rgba(0,0,255,0.8)</Color>
</WaterUnit>
</xholonClassDetails>
<PhysicalSystem>
<PipeSystem>
<WaterPressure><![CDATA[
var me, waterUnitArr, waterUnitIx, beh = {
postConfigure: function() {
me = this.cnode;
me.println(me.name());
//stepNum = 1;
waterUnitArr = [];
waterUnitIx = 0;
this.initWus();
//$wnd.xh.param("TimeStepInterval", "500");
},
act: function() {
if (Math.random() < 0.5) {return;}
var wu = waterUnitArr[waterUnitIx];
this.initWus();
if (wu == null) {waterUnitIx = 0; wu = waterUnitArr[waterUnitIx];}
if (wu == null) {return;}
me.println(wu.name());
switch (wu.stepNum) {
case 1: wu.action("enter parallelPathway"); break;
case 2: wu.action("go onlyChild"); if (wu.parent().role() == "HotWaterIntake") {wu.color("rgba(255,0,0,0.8)")}; break;
case 3: wu.action("go port0"); break;
case 4: wu.action("enter mixerTap"); break;
case 5: wu.action("go port0"); break;
case 6: wu.action("go port0"); break;
case 7: wu.action("go onlyChild"); break;
case 8: wu.action("go port0"); waterUnitArr.splice(waterUnitIx, 1); waterUnitIx--; break;
default: wu.action("where"); break;
}
wu.stepNum++;
waterUnitIx++;
if (waterUnitIx >= waterUnitArr.length) {
waterUnitIx = 0;
}
}, // end act()
// initialize WaterUnit nodes
initWus: function() {
var node = me.first();
var nextNode = null;
while (node) {
nextNode = node.next();
waterUnitArr.push(node);
var wu = node;
me.println(wu.name());
wu.stepNum = 1;
wu.action("who");
wu.action("where");
wu.action("exit");
wu.action("where");
node = nextNode;
}
}
}
]]><WaterUnit/><WaterUnit/><WaterUnit/><WaterUnit/><WaterUnit/></WaterPressure>
<!-- a parallel pathway; active object will randomly select one of these two paths -->
<ParallelPathway>
<Pipe roleName="ColdWaterIntake"/>
<Pipe roleName="HotWaterIntake"/>
</ParallelPathway>
<!-- a serial pathway -->
<ComboValve>
<MixerTap/>
<VolumeSelector/>
</ComboValve>
<!-- an OR pathway; an OrNode -->
<Diverter>
<!-- to tub -->
<Faucet/>
<!-- to shower -->
<ShowerHead/>
</Diverter>
<Drain/>
</PipeSystem>
<Animate duration="1" selection="#xhanim" tweenScript="xhSvgTween_exp" xpath="./PhysicalSystem/PipeSystem" cssStyle=".d3cpnode circle {stroke-width: 0px;}" efParams="{&quot;selection&quot;:&quot;#xhanim&quot;,&quot;shouldIncludeDecorations&quot;:true,&quot;useIcons&quot;:false,&quot;shape&quot;:&quot;circle&quot;, &quot;iconPos&quot;:&quot;outside&quot;,&quot;sort&quot;:&quot;disable&quot;,&quot;width&quot;:600,&quot;height&quot;:600,&quot;mode&quot;:&quot;tween&quot;,&quot;labelContainers&quot;:true,&quot;includeId&quot;:true,&quot;shape&quot;:&quot;circle&quot;,&quot;supportTouch&quot;:true,&quot;maxChars&quot;:3}"/>
</PhysicalSystem>
<ParallelPathwaybehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var me, childCount, beh = {
postConfigure: function() {
me = this.cnode.parent();
me.println(me.obj());
me.port(0, me.obj());
// move this behavior object so it's out of the way
me.parent().parent().append(this.cnode.remove());
// compute number of children
childCount = 0;
var node = me.first();
while (node) {
childCount++;
node = node.next();
}
me.println(childCount);
},
act: function() {
var index = Math.floor(Math.random() * childCount) + 1;
var onlyChild = me.xpath("*[" + index + "]");
me.obj(onlyChild);
me.port(0, onlyChild);
} // end act()
}
]]></ParallelPathwaybehavior>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>PipeSystem</title>
<rect id="PhysicalSystem/PipeSystem" fill="#98FB98" height="50" width="50" x="25" y="0"/>
<g>
<title>Diverter</title>
<rect id="PhysicalSystem/PipeSystem/Diverter" fill="#6AB06A" height="50" width="10" x="80" y="0"/>
</g>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment