Last active
December 3, 2024 18:20
-
-
Save kenwebb/a060c49abd0b29a1b075a7fad691e0ef to your computer and use it in GitHub Desktop.
Industrial Dynamics - Chapter 15 - Xholonish - Factory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Tue Dec 03 2024 13:20:25 GMT-0500 (Eastern Standard Time)--> | |
<XholonWorkbook> | |
<Notes><![CDATA[ | |
Xholon | |
------ | |
Title: Industrial Dynamics - Chapter 15 - Xholonish - Factory | |
Description: | |
Url: http://www.primordion.com/Xholon/gwt/ | |
InternalName: a060c49abd0b29a1b075a7fad691e0ef based on c8c90e6e6d761e1268747bb1b5e0d430 | |
Keywords: | |
My Notes | |
-------- | |
28 Nov 2024 | |
The third of three workbooks: Retail, Distributor, Factory | |
- connect the three at runtime using broadcastChannel | |
- use arrow functions within beh to implement DYNAMO auxiliaries | |
Industrial Dynamics - Chapter 15 - Xholonish - DataCollector | |
α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω | |
### broadcastChannel | |
- connect the Factory and Distributor workbooks; see Figure 15-14 and Figure 15-15 in the Forrester book | |
- I have done this using broadcastChannel | |
Xholon Signals for use between the three models | |
Signal From To | |
------ ----------- -------------------- | |
101 Retail Distributor | |
102 Distributor Retail | |
201 Distributor Factory | |
202 Factory Distributor | |
301 R|D|F data collector, etc. | |
Structure of a BroadcastChannel message (a JS Object; JSO and not JSON) | |
ex: Retail -> Distributor | |
{ | |
signal: 101, | |
data: [ | |
{ | |
dtype: "SSF", | |
dval: 3.1234 | |
} | |
] | |
} | |
ex: Factory -> Distributor | |
{ | |
signal: 202, | |
data: [ | |
{ | |
dtype: "SSF", | |
dval: 3.1234 | |
}, | |
{ | |
dtype: "UOF", | |
dval: 3.1235 | |
}, | |
{ | |
dtype: "DFF", | |
dval: 3.1236 | |
} | |
] | |
} | |
### References | |
() Jay Forrester, Industrial Dynamics, 1961 | |
() https://developer.mozilla.org/en-US/blog/exploring-the-broadcast-channel-api-for-cross-tab-communication/ | |
() https://www.digitalocean.com/community/tutorials/js-broadcastchannel-api | |
]]></Notes> | |
<_-.XholonClass> | |
<DynamicalSystem> | |
<!-- Production - Factory System, chapters 2, 15 --> | |
<ProdDistSystem/> | |
</DynamicalSystem> | |
<Retail/> | |
</_-.XholonClass> | |
<xholonClassDetails> | |
<Avatar><Color>red</Color></Avatar> | |
</xholonClassDetails> | |
<ProdDistSystem> | |
<Factory roleName="one"/> | |
</ProdDistSystem> | |
<Factorybehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[ | |
// what is special about these? why are they here? TODO | |
//const RRR = {KL:1}; // Requisitions (orders) Received at Retail (units/week) from customers | |
//const RCR = {K:1}; // ??? | |
//const STP = {K:1}; | |
//const SNE = {K:1}; | |
//const TIME = {K:1}; | |
// what is special about these? why are they here? | |
const | |
//PER=1, | |
//RRI=1, | |
//SIH=1, | |
STH=1, | |
STT=1; | |
// constants | |
const | |
AIF = 8, | |
ALF = 7, | |
DCF = 3, | |
DHF = 1, | |
DIF = 4, | |
DPF = 5, | |
DRF = 8, | |
DUF = 0.4; | |
const DT = 1; // Delta Time (weeks), the time interval between solutions of the equations | |
// FACTORY ------------------------ | |
// levels | |
const CPF={K:1.1}; | |
const IAF={K:1.2}; | |
const OPF={K:1.3}; | |
const RSF={K:1.5}; | |
const UOF={K:1.6}; // Unfilled Orders (measured in units of goods on order) | |
// rates | |
const MDF={KL:1.11}; | |
const MOF={KL:1.12}; | |
const RRF={KL:1.13}; // from Distributor | |
const SRF={KL:1.14}; | |
const SSF={KL:1.15}; // Shipments Sent from Retail (units/week) | |
// auxiliary | |
// these are recalculated from scratch each time step | |
const DFF={K:1.21}; | |
const IDF={K:1.22}; | |
const LAF={K:1.23}; | |
const LDF={K:1.24}; | |
const MWF={K:1.25}; | |
const NIF={K:1.26}; | |
const STF={K:1.27}; | |
const UNF={K:1.28}; | |
// from distributor | |
//const DFD = {J: 4, K:4}; | |
//const UOD = {J: 1, K:1}; | |
//const SSD = {JK: 1,KL:1}; | |
//functions, lambdas | |
// LDR.K=(RSR.K)*(DCR)+(RSR.K)*(DMR)+(RSR.K)*(DFD.K)+(RSR.K)*(DTR) // 15-10 16A | |
// λa.λb.λc.λd.λe.a*(b+c+d+e) | |
const uoff = (uof, dt, rrf, ssf) => uof + dt * (rrf - ssf); // p.162 15-37, L | |
const iaff = (iaf, dt, srf, ssf) => iaf + dt * (srf - ssf); // p.162 15-38, L | |
const stff = (uof, dff) => uof / dff; // p.162 15-39, A | |
const niff = (iaf, dt) => iaf / dt; // p.162 15-40, A | |
const ssff = (stf, nif) => nif >= stf ? stf : nif; // p.162 15-41, R | |
const dfff = (dhf, duf, idf, iaf) => dhf + duf * (idf/ iaf); // p.162 15-42, A | |
const idff = (aif, rsf) => aif * rsf; // p.162 15-43, A | |
const rsff = (rsf, dt, drf, rrf) => rsf + dt * (1 / drf) * (rrf - rsf); // p.162 15-44, L | |
const mwff = (rrf, dif, idf, iaf, ldf, laf, uof, unf) => rrf + (1 / dif) * ((idf - iaf) + (ldf - laf) + (uof - unf)); // p. 164 15-45, A | |
const mdff = (mwf, alf) => alf >= mwf ? mwf : alf; // p. 164 15-46, R | |
const ldff = (rsf, dcf, dpf) => rsf * (dcf + dpf); // p.165 15-47, A | |
const laff = (cpf, opf) => cpf + opf; // p.166 15-48, A | |
const unff = (rsf, dhf, duf) => rsf * (dhf + duf); // p.167 15-49, A | |
const cpff = (cpf, dt, mdf, mof) => cpf + dt * (mdf - mof); // p.165 15-50, L | |
const moff = (mdf, dcf) => DELAY3(mdf, dcf); // p.165 15-51, R | |
const opff = (opf, dt, mof, srf) => opf + dt * (mof - srf); // p.165 15-52, L | |
const srff = (mof, dpf) => DELAY3(mof, dpf); // p.165 15-53, R | |
// FUNCTIONS ---------------------- | |
// TODO implement these functions correctly; see book | |
const STEP = (sth, stt) => 1; | |
const SIN = (x) => Math.sin(x); | |
const _2PI = () => Math.PI * 2; | |
const CLIP = (a,b,c,d) => 1; | |
const DELAY3 = (a,b) => 1; | |
var me, csvK, counter, bchan, beh = { | |
postConfigure: function() { | |
me = this.cnode.parent(); | |
csvK = "Factory\nUOF.K,IAF.K,STF.K,NIF.K,SSF.KL,DFF.K,IDF.K,RSF.K,MWF.K,MDF.KL,LDF.K,LAF.K,UNF.K,CPF.K,MOF.KL,OPF.K,SRF.KL\n"; // DONE | |
counter = 0; | |
//console.log(this, this.cnode, me); | |
me.println(`\nUOF,IAF,RSF,CPF,OPF`); | |
bchan = new BroadcastChannel("proddist"); | |
bchan.onmessage = (event) => { | |
console.log(event); // this works | |
switch (event.data.signal) { | |
case 201: | |
me.msg(event.data.signal, JSON.stringify(event.data.data)); | |
break; | |
default: break; | |
} | |
} | |
}, | |
processReceivedMessage: function(msg) { | |
//me.println(msg.data); // this works | |
me.println("msg received: " + msg.signal + " " + msg.data); | |
}, | |
act: function() { | |
const arrA = [UOF.K,IAF.K,STF.K,NIF.K,SSF.KL,DFF.K,IDF.K,RSF.K,MWF.K,MDF.KL,LDF.K,LAF.K,UNF.K,CPF.K,MOF.KL,OPF.K,SRF.KL]; | |
const arrB = arrA.map((item) => item.toFixed(4), []); | |
const csvC = arrB.join(",") + "\n"; | |
csvK += csvC; | |
UOF.K = uoff(UOF.J, DT, RRF.JK, SSF.JK); // 15-37, L | |
IAF.K = iaff(IAF.J, DT, SRF.JK, SSF.JK); // 15-38, L | |
STF.K = stff(UOF.K, DFF.K); // 15-39, A | |
NIF.K = niff(IAF.K, DT); // 15-40, A | |
SSF.KL = ssff(STF.K, NIF.K); // 15-41, R | |
DFF.K = dfff(DHF, DUF, IDF.K, IAF.K); // 15-42, A | |
IDF.K = idff(AIF, RSF.K); // 15-43, A | |
RSF.K = rsff(RSF.J, DT, DRF, RRF.JK, RSF.J); // 15-44, L | |
// manufacturing | |
MWF.K = mwff(RRF.JK, DIF, IDF.K, IAF.K, LDF.K, LAF.K, UOF.K, UNF.K); // 15-45, A | |
MDF.KL = mdff(MWF.K, ALF); // 15-46, R | |
LDF.K = ldff(RSF.K, DCF, DPF); // 15-47, A | |
LAF.K = laff(CPF.K, OPF.K); // 15-48, A | |
UNF.K = unff(RSF.K, DHF, DUF); // 15-49, A | |
CPF.K = cpff(CPF.J, DT, MDF.JK, MOF.JK); // 15-50, L | |
MOF.KL = moff(MDF.JK, DCF); // 15-51, R | |
OPF.K = opff(OPF.J, DT, MOF.JK, SRF.JK); // 15-52, L | |
SRF.KL = srff(MOF.JK, DPF); // 15-53, R | |
if (counter++ == 5) { | |
console.log(csvK); | |
} | |
const sender = me.name(); | |
me.println("sender:" + sender); | |
bchan.postMessage( | |
{ | |
signal: 202, | |
data: [ | |
{ | |
dtype: "SSF", | |
dval: 3.1234 | |
}, | |
{ | |
dtype: "UOF", | |
dval: 3.1235 | |
}, | |
{ | |
dtype: "DFF", | |
dval: 3.1236 | |
} | |
], | |
sender: sender | |
} | |
) | |
}, | |
preAct: function() { | |
// handle the transition as the present (K) becomes the past (J) | |
// TODO some of these may be unnecessary/unused and/or may cause problems | |
// FACTORY - levels, rates | |
CPF.J = CPF.K; | |
DFF.J = DFF.K; // ??? | |
IAF.J = IAF.K; | |
IDF.J = IDF.K; // ??? | |
LAF.J = LAF.K; | |
LDF.J = LDF.K; | |
MDF.JK = MDF.KL; // ??? | |
MWF.J = MWF.K; | |
NIF.J = NIF.K; // ??? | |
OPF.J = OPF.K; | |
RSF.J = RSF.K; | |
MDF.JK = MDF.KL; | |
MOF.JK = MOF.KL; | |
OPF.J = OPF.K; | |
RRF.JK = RRF.KL; | |
RSF.J = RSF.K; | |
SRF.JK = SRF.KL; | |
SSF.JK = SSF.KL; | |
STF.J = STF.K; // ??? | |
UNF.J = UNF.K; // ??? | |
UOF.J = UOF.K; | |
}, | |
postAct: function() { | |
let dpl = 3; // number of decimal places | |
me.print(`${UOF.J.toFixed(dpl)},${IAF.J.toFixed(dpl)},${RSF.J.toFixed(dpl)},`); | |
me.print(`${CPF.J.toFixed(dpl)},${OPF.J.toFixed(dpl)}`); | |
me.print("\n"); | |
/* | |
UOF,IAF,RSF,CPF,OPF | |
1.600,1.200,1.500,1.100,1.300 | |
1.580,1.190,1.454,1.090,1.280 | |
1.520,1.000,1.413,4.000,1.280 | |
1.650,1.000,1.378,8.966,1.280 | |
2.496,1.716,1.347,13.825,1.280 | |
3.184,2.274,1.320,17.859,1.280 | |
3.438,2.398,1.296,20.571,1.280 | |
... | |
*/ | |
} | |
} | |
//# sourceURL=Factorybehavior.js | |
]]></Factorybehavior> | |
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml, | |
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg"> | |
<g> | |
<title>Factory</title> | |
<rect id="ProdDistSystem/Factory" fill="#98FB98" height="50" width="50" x="25" y="0"/> | |
<g> | |
<title>Factory</title> | |
<rect id="ProdDistSystem/Factory" 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