<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://nyejon.com/blog</id>
    <title>Uncommon sense Blog</title>
    <updated>2026-08-28T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://nyejon.com/blog"/>
    <subtitle>Uncommon sense Blog</subtitle>
    <icon>https://nyejon.com/img/favicon.ico</icon>
    <rights>Articles under &lt;a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;CC BY-NC-SA&lt;/a&gt;.</rights>
    <entry>
        <title type="html"><![CDATA[Building a factory model with ISA-95]]></title>
        <id>https://nyejon.com/blog/isa-95-factory-model</id>
        <link href="https://nyejon.com/blog/isa-95-factory-model"/>
        <updated>2026-08-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A practical approach to using ISA-95 as the foundation for a factory data model without trying to implement the entire standard at once.]]></summary>
        <content type="html"><![CDATA[<p>A factory has no shortage of data. The difficult part is knowing what the data describes and how it relates to everything else.</p>
<p>A tag called <code>Line1.Power</code> might be obvious to the engineer who created it. It is less obvious to a scheduling system trying to calculate the energy cost of a production order, or to someone comparing the same machine across five sites.</p>
<p>To answer those questions, one needs a model of the factory. ISA-95 is a good place to start.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-isa-95-gives-you">What ISA-95 gives you<a href="https://nyejon.com/blog/isa-95-factory-model#what-isa-95-gives-you" class="hash-link" aria-label="Direct link to What ISA-95 gives you" title="Direct link to What ISA-95 gives you" translate="no">​</a></h2>
<p><a href="https://www.isa.org/standards-and-publications/isa-standards/isa-95-standard" target="_blank" rel="noopener noreferrer" class="">ISA-95</a>, also published internationally as <a href="https://webstore.iec.ch/en/publication/6675" target="_blank" rel="noopener noreferrer" class="">IEC 62264</a>, is a set of standards for integrating manufacturing control systems with business systems. It defines common terminology, system boundaries, activities, and information models.</p>
<p>The familiar ISA-95 levels are:</p>
<ul>
<li class="">Level 0: the physical production process.</li>
<li class="">Level 1: sensing and manipulating the process.</li>
<li class="">Level 2: monitoring and supervisory control.</li>
<li class="">Level 3: manufacturing operations management.</li>
<li class="">Level 4: business planning and logistics.</li>
</ul>
<p>The standard mainly concerns the boundary between manufacturing operations at Level 3 and business systems at Level 4. This is where operations requests, schedules, resource requirements, and performance results have to move between systems without everyone inventing a different meaning for them.</p>
<p>The levels are useful, but they are not the main reason I use ISA-95 when building a factory model. The value is the vocabulary underneath them: equipment, materials, personnel, segments, requests, schedules, and performance.</p>
<p>ISA-95 gives us a shared language. It does not give us a PostgreSQL schema that should be copied table for table.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="start-with-the-questions">Start with the questions<a href="https://nyejon.com/blog/isa-95-factory-model#start-with-the-questions" class="hash-link" aria-label="Direct link to Start with the questions" title="Direct link to Start with the questions" translate="no">​</a></h2>
<p>It is tempting to begin by modeling the entire standard. This will produce a large and impressive schema before it produces anything useful.</p>
<p>I prefer starting with the questions the model needs to answer:</p>
<ul>
<li class="">Where is this machine in the factory?</li>
<li class="">What material or utility flows through it?</li>
<li class="">Which measurement belongs to which machine or flow?</li>
<li class="">What process is supposed to happen here?</li>
<li class="">Which production order was running at 10:30?</li>
<li class="">How much electricity did that order use?</li>
<li class="">Which input lots ended up in this finished product?</li>
<li class="">Why did the line miss its target?</li>
</ul>
<p>These questions quickly expose the concepts and relationships that are actually required. They also provide tests for the model. If the schema contains 40 tables but still cannot answer which machine consumed the most steam last Tuesday, the model is not finished.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-factory-is-more-than-one-graph">A factory is more than one graph<a href="https://nyejon.com/blog/isa-95-factory-model#a-factory-is-more-than-one-graph" class="hash-link" aria-label="Direct link to A factory is more than one graph" title="Direct link to A factory is more than one graph" translate="no">​</a></h2>
<p>I use “factory graph” as a description of the relationships, not as a requirement to use a graph database. A relational database handles most of this well.</p>
<p>The important part is recognizing that a factory contains several overlapping graphs:</p>
<!-- -->
<p>They are related, but they are not interchangeable.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-equipment-hierarchy">The equipment hierarchy<a href="https://nyejon.com/blog/isa-95-factory-model#the-equipment-hierarchy" class="hash-link" aria-label="Direct link to The equipment hierarchy" title="Direct link to The equipment hierarchy" translate="no">​</a></h3>
<p>The equipment hierarchy describes containment:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Enterprise</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└── Site</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    └── Area</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        └── Work Center</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            └── Work Unit</span><br></div></code></pre></div></div>
<p>This is the backbone of the model. A self-referencing <code>equipment</code> table is usually enough to represent it:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TYPE</span><span class="token plain"> equipment_level </span><span class="token keyword" style="color:#00009f">AS</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">ENUM</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">'Enterprise'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">'Site'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">'Area'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">'WorkCenter'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">'WorkUnit'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> equipment </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    id                  BIGSERIAL </span><span class="token keyword" style="color:#00009f">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">KEY</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ref_id              </span><span class="token keyword" style="color:#00009f">VARCHAR</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">64</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">UNIQUE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    name                </span><span class="token keyword" style="color:#00009f">VARCHAR</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">255</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">level</span><span class="token plain">               equipment_level </span><span class="token operator" style="color:#393A34">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    parent_equipment_id </span><span class="token keyword" style="color:#00009f">BIGINT</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">REFERENCES</span><span class="token plain"> equipment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>The application or additional database constraints should prevent cycles and invalid parent-child level combinations.</p>
<p>The hierarchy lets one aggregate measurements and production results from a machine to a line, area, site, or enterprise. It also gives every other object a stable location in the factory.</p>
<p>Do not confuse a logical equipment position with the physical asset currently installed there. “Filler 1” may be a permanent position in the process while the motor, meter, or complete machine occupying it changes over time. If replacement history matters, model physical assets separately and assign them to equipment with start and end timestamps.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-physical-topology">The physical topology<a href="https://nyejon.com/blog/isa-95-factory-model#the-physical-topology" class="hash-link" aria-label="Direct link to The physical topology" title="Direct link to The physical topology" translate="no">​</a></h3>
<p>Containment does not describe flow.</p>
<p>A boiler may sit in a utilities area while supplying steam to three production lines in another area. A buffer may receive material from two machines and feed a third. None of this can be inferred from the equipment hierarchy.</p>
<p>Represent those relationships explicitly:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">TABLE</span><span class="token plain"> flow_connection </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    id                BIGSERIAL </span><span class="token keyword" style="color:#00009f">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">KEY</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ref_id            </span><span class="token keyword" style="color:#00009f">VARCHAR</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">64</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">UNIQUE</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    from_equipment_id </span><span class="token keyword" style="color:#00009f">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">REFERENCES</span><span class="token plain"> equipment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    to_equipment_id   </span><span class="token keyword" style="color:#00009f">BIGINT</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">NULL</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">REFERENCES</span><span class="token plain"> equipment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    material_id       </span><span class="token keyword" style="color:#00009f">VARCHAR</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">64</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">REFERENCES</span><span class="token plain"> material</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">CHECK</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">from_equipment_id </span><span class="token operator" style="color:#393A34">&lt;&gt;</span><span class="token plain"> to_equipment_id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>This graph answers questions about material, energy, water, steam, compressed air, waste, and emissions. It should not also be forced to represent process sequence. A pipe between two machines and the rule that operation B follows operation A are different facts, even when they happen to point in the same direction.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="process-intent">Process intent<a href="https://nyejon.com/blog/isa-95-factory-model#process-intent" class="hash-link" aria-label="Direct link to Process intent" title="Direct link to Process intent" translate="no">​</a></h3>
<p>ISA-95 uses segments to describe reusable work and its resource requirements. In a production example, a segment can require:</p>
<ul>
<li class="">an equipment class or specific machine</li>
<li class="">input and output materials</li>
<li class="">personnel or a personnel class</li>
<li class="">parameters such as temperature, pressure, speed, or target cycle time</li>
</ul>
<p>A workflow or route connects segments in the required order. This is what should happen, independent of a specific order or Tuesday's production result.</p>
<p>Keeping process intent separate from physical topology makes the model much more useful. The same process step may run on one of four equivalent machines. The route stays the same while the equipment assignment changes.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="operations-and-production-execution">Operations and production execution<a href="https://nyejon.com/blog/isa-95-factory-model#operations-and-production-execution" class="hash-link" aria-label="Direct link to Operations and production execution" title="Direct link to Operations and production execution" translate="no">​</a></h3>
<p>The 2026 edition of <a href="https://webstore.iec.ch/en/publication/75127" target="_blank" rel="noopener noreferrer" class="">IEC 62264-2</a> uses generalized operations models rather than separate production-only schedule and performance models. This allows the same structure to describe production, maintenance, quality, and inventory work. I focus on production here, but the separation is the same:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Demand → Schedule → Dispatched work → Performance</span><br></div></code></pre></div></div>
<p>For production, a request might say: make 5,000 units of product X by Friday. A schedule assigns time and resources. Dispatch turns scheduled work into executable job orders. Performance records actual start and end times, quantities produced, quality results, and the resources used.</p>
<p>This separation is necessary for plan-versus-actual reporting. If a schedule row is continuously edited until it resembles reality, the original plan is lost. Keep versions of the plan and record actual performance separately.</p>
<p>It also provides the data required for <a class="" href="https://nyejon.com/blog/oee-introduction">OEE</a>: planned production time, runtime, ideal cycle time or rate, total count, and good count.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="materials-and-genealogy">Materials and genealogy<a href="https://nyejon.com/blog/isa-95-factory-model#materials-and-genealogy" class="hash-link" aria-label="Direct link to Materials and genealogy" title="Direct link to Materials and genealogy" translate="no">​</a></h3>
<p>A material definition and a material lot are not the same thing.</p>
<p>“Steel grade X” is master data. “Lot S-2026-0814” is a particular quantity of that steel received or produced at a particular time. Recipes and process segments normally refer to material definitions. Traceability refers to lots.</p>
<p>Once execution results are linked to consumed and produced lots, genealogy becomes another directed graph:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">Input lot A ─┐</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">             ├── Production run ── Output lot C</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Input lot B ─┘</span><br></div></code></pre></div></div>
<p>This supports recalls, quality investigations, and product-level cost or emission attribution. It is useful, but not every first version of a factory model needs it. Add lot genealogy when there is a real traceability question to answer.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="measurements">Measurements<a href="https://nyejon.com/blog/isa-95-factory-model#measurements" class="hash-link" aria-label="Direct link to Measurements" title="Direct link to Measurements" translate="no">​</a></h3>
<p>A measurement point defines the meaning of a signal. A reading carries the observed value and timestamp, normally with a quality or status indicator.</p>
<p>The point should identify:</p>
<ul>
<li class="">what is measured</li>
<li class="">the unit of measure</li>
<li class="">whether it belongs to equipment or a flow connection</li>
<li class="">the material or utility, where relevant</li>
<li class="">whether it is physical or calculated</li>
<li class="">which sensor or calculation provided it during a given time range</li>
</ul>
<p>This distinction keeps the logical point stable when a meter is replaced. Historical readings remain attached to “Steam flow into Line 2” even though the physical device has changed.</p>
<p>I would normally keep this metadata in the relational model and store high-volume readings in a time-series database. At 1 Hz, 10,000 tags generate 864 million readings per day. The factory model should provide context for those readings without forcing every reading through the same transactional database used for equipment, recipes, and schedules.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="units-and-time-are-part-of-the-model">Units and time are part of the model<a href="https://nyejon.com/blog/isa-95-factory-model#units-and-time-are-part-of-the-model" class="hash-link" aria-label="Direct link to Units and time are part of the model" title="Direct link to Units and time are part of the model" translate="no">​</a></h2>
<p>Units should not be stored as inconsistent free text across sensor and material tables. For gas volumes, <code>m³</code> identifies the unit of volume but does not state the temperature and pressure conditions. A value expressed in <code>Nm³</code> has been normalized to defined reference conditions. Those conditions must also be recorded.</p>
<p>A unit dictionary should include a stable code, symbol, quantity kind, quantity dimension, and, where valid, a deterministic conversion to a canonical unit. Every measured or calculated quantity should reference a defined unit. Cost and emission factors must also state their unit explicitly.</p>
<p>Time validity matters for the same reason. Electricity tariffs change. Emission factors change. Assets are replaced. A sensor is remapped. A machine moves to another line.</p>
<p>If the model overwrites these relationships, historical calculations can silently change. Store <code>valid_from</code> and <code>valid_to</code> for any fact whose value or assignment can change over time.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="build-it-in-layers">Build it in layers<a href="https://nyejon.com/blog/isa-95-factory-model#build-it-in-layers" class="hash-link" aria-label="Direct link to Build it in layers" title="Direct link to Build it in layers" translate="no">​</a></h2>
<p>The first useful version does not need the whole standard. I would build it in three layers.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="layer-1-structure-and-measurements">Layer 1: structure and measurements<a href="https://nyejon.com/blog/isa-95-factory-model#layer-1-structure-and-measurements" class="hash-link" aria-label="Direct link to Layer 1: structure and measurements" title="Direct link to Layer 1: structure and measurements" translate="no">​</a></h3>
<p>Start with:</p>
<ul>
<li class="">equipment and its hierarchy</li>
<li class="">material and utility definitions</li>
<li class="">physical flow connections</li>
<li class="">measurement points and units</li>
</ul>
<p>This is enough to browse the factory, map sensor data, and answer basic consumption questions by equipment, line, or site.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="layer-2-process-and-execution">Layer 2: process and execution<a href="https://nyejon.com/blog/isa-95-factory-model#layer-2-process-and-execution" class="hash-link" aria-label="Direct link to Layer 2: process and execution" title="Direct link to Layer 2: process and execution" translate="no">​</a></h3>
<p>Add:</p>
<ul>
<li class="">segment definitions and workflows</li>
<li class="">equipment, material, and personnel requirements</li>
<li class="">operations requests and schedules</li>
<li class="">dispatched work or job orders</li>
<li class="">performance results</li>
</ul>
<p>Now the model can connect what should happen to what did happen. Scheduling, OEE, throughput, and resource attribution become possible.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="layer-3-traceability-and-optimization">Layer 3: traceability and optimization<a href="https://nyejon.com/blog/isa-95-factory-model#layer-3-traceability-and-optimization" class="hash-link" aria-label="Direct link to Layer 3: traceability and optimization" title="Direct link to Layer 3: traceability and optimization" translate="no">​</a></h3>
<p>Add these only where required:</p>
<ul>
<li class="">material lots and genealogy</li>
<li class="">personnel capabilities</li>
<li class="">asset assignment history</li>
<li class="">time-valid cost and emission factors</li>
<li class="">storage capacity and compatibility</li>
<li class="">changeover costs and scheduling constraints</li>
</ul>
<p>This is where a factory model becomes valuable for optimization, product costing, emissions accounting, and traceability. It is also where complexity increases quickly. Each extension should still be justified by a question or workflow.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-mistakes">Common mistakes<a href="https://nyejon.com/blog/isa-95-factory-model#common-mistakes" class="hash-link" aria-label="Direct link to Common mistakes" title="Direct link to Common mistakes" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="putting-everything-in-one-node-and-edge-table">Putting everything in one node and edge table<a href="https://nyejon.com/blog/isa-95-factory-model#putting-everything-in-one-node-and-edge-table" class="hash-link" aria-label="Direct link to Putting everything in one node and edge table" title="Direct link to Putting everything in one node and edge table" translate="no">​</a></h3>
<p>A generic graph looks flexible at first. Eventually every query depends on a growing list of node types, edge types, and JSON properties. Database constraints become difficult and invalid relationships become easy.</p>
<p>Use explicit tables for concepts with different rules. An equipment hierarchy, process dependency, material genealogy edge, and steam connection can all be traversed as graphs without pretending they are the same relationship.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="copying-isa-95-literally">Copying ISA-95 literally<a href="https://nyejon.com/blog/isa-95-factory-model#copying-isa-95-literally" class="hash-link" aria-label="Direct link to Copying ISA-95 literally" title="Direct link to Copying ISA-95 literally" translate="no">​</a></h3>
<p>ISA-95 is a conceptual standard designed to work across industries and systems. Your implementation serves a particular product and set of factories.</p>
<p>Keep the standard's semantics, but use names your team understands. Document the mapping. Do not add tables merely because an object exists somewhere in the standard.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="mixing-definitions-plans-and-actuals">Mixing definitions, plans, and actuals<a href="https://nyejon.com/blog/isa-95-factory-model#mixing-definitions-plans-and-actuals" class="hash-link" aria-label="Direct link to Mixing definitions, plans, and actuals" title="Direct link to Mixing definitions, plans, and actuals" translate="no">​</a></h3>
<p>A recipe is not a production order. A production order is not a schedule. A schedule is not a production result.</p>
<p>Combining them makes the first demo faster and every later analysis harder. Keep intent, plan, dispatch, and actual performance separate.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ignoring-identity">Ignoring identity<a href="https://nyejon.com/blog/isa-95-factory-model#ignoring-identity" class="hash-link" aria-label="Direct link to Ignoring identity" title="Direct link to Ignoring identity" translate="no">​</a></h3>
<p>The same machine will have different IDs in ERP, MES, SCADA, maintenance, and the historian. Pick a stable internal identity and keep aliases per source system. Avoid making a display name or one vendor's identifier the primary key for the whole factory.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="modeling-before-asking">Modeling before asking<a href="https://nyejon.com/blog/isa-95-factory-model#modeling-before-asking" class="hash-link" aria-label="Direct link to Modeling before asking" title="Direct link to Modeling before asking" translate="no">​</a></h3>
<p>The most dangerous version of a factory model is one that is technically elegant but operationally irrelevant.</p>
<p>Start with five to ten questions from engineers, planners, operators, and managers. Build the smallest model that answers them. Add the next concept when the next question requires it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-model-is-the-integration-layer">The model is the integration layer<a href="https://nyejon.com/blog/isa-95-factory-model#the-model-is-the-integration-layer" class="hash-link" aria-label="Direct link to The model is the integration layer" title="Direct link to The model is the integration layer" translate="no">​</a></h2>
<p>ISA-95 was created to make integration between manufacturing and business systems less ambiguous. That remains the useful idea.</p>
<p>A factory model should allow a production request from ERP, a machine state from a PLC, a meter reading from a historian, and a finished quantity from MES to refer to the same operational context.</p>
<p>The final schema will differ between a steel mill, a battery plant, and a food factory. The underlying questions are similar: where did this happen, what was supposed to happen, what actually happened, what went in, what came out, and what did it cost?</p>
<p>ISA-95 gives us a solid language for answering those questions. The work is choosing how much of that language the factory actually needs.</p>
<p>If building software for factories sounds interesting, <a href="https://juna-ai.jobs.personio.de/?language=en" target="_blank" rel="noopener noreferrer" class="">take a look at the open roles at Juna AI</a>.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Manufacturing" term="Manufacturing"/>
        <category label="Software Development" term="Software Development"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Giving an old Ricoh SP 112 printer a second life]]></title>
        <id>https://nyejon.com/blog/ricoh-sp112-cups-driver</id>
        <link href="https://nyejon.com/blog/ricoh-sp112-cups-driver"/>
        <updated>2026-08-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Turning a USB-only Ricoh SP 112 into a printer that works with Apple Silicon Macs and can be shared across a network with Unraid.]]></summary>
        <content type="html"><![CDATA[<p>I have a perfectly good Ricoh SP 112 laser printer. The hardware still works,
but it is USB-only and getting it to print from a modern Apple Silicon Mac was
far more difficult than it should have been.</p>
<p>A community driver existed, but installing it involved old dependencies and
manual configuration. I wanted something simpler: open a normal macOS package,
add the printer in System Settings and print.</p>
<p>I also wanted to connect the printer to my Unraid server so that every computer
on the network could use it without moving a USB cable around.</p>
<p>I used Codex with GPT-5.6 Sol on high to do most of the work. I gave it the old
driver and asked it to turn it into something I could install normally on my
Mac, then added the Unraid setup. After a few rounds of testing and cleanup, I
had a much smaller driver, a macOS installer and a Docker container.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-smaller-macos-driver">A smaller macOS driver<a href="https://nyejon.com/blog/ricoh-sp112-cups-driver#a-smaller-macos-driver" class="hash-link" aria-label="Direct link to A smaller macOS driver" title="Direct link to A smaller macOS driver" translate="no">​</a></h2>
<p>The printer expects pages in Ricoh's own format. The new driver lets macOS do
the normal document conversion, then performs the final two jobs the printer
needs: compressing the page with JBIG and wrapping it in the Ricoh printer
commands.</p>
<p>This reduced the driver to one small CUPS filter and a printer description. It
can now be installed with a standard <code>.pkg</code> file and appears as <strong>Ricoh SP 112
Gurich</strong> when adding a printer on macOS.</p>
<p>It supports both 600×600 and 1200×600 dpi. The closely related Ricoh SP 110
uses the same protocol and should work too.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="turning-it-into-a-network-printer">Turning it into a network printer<a href="https://nyejon.com/blog/ricoh-sp112-cups-driver#turning-it-into-a-network-printer" class="hash-link" aria-label="Direct link to Turning it into a network printer" title="Direct link to Turning it into a network printer" translate="no">​</a></h2>
<p>The same filter can run in a small CUPS container on Unraid. The printer stays
connected to the server by USB, while CUPS shares it over the network using
IPP. Macs normally discover it automatically through Bonjour, and other
computers can connect directly to its IPP address.</p>
<p>Once the repository is on Unraid, starting it is one command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">docker compose -f docker/compose.unraid.yaml up -d --build</span><br></div></code></pre></div></div>
<p>The container detects the USB printer, creates the queue and shares it. Client
computers do not need the Ricoh driver because the server handles the final
conversion.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-it">Using it<a href="https://nyejon.com/blog/ricoh-sp112-cups-driver#using-it" class="hash-link" aria-label="Direct link to Using it" title="Direct link to Using it" translate="no">​</a></h2>
<p>The source code, macOS installer and Unraid instructions are available in the
<a href="https://github.com/nyejon/ricoh-sp112-cups" target="_blank" rel="noopener noreferrer" class="">ricoh-sp112-cups repository</a>.</p>
<p>For a Mac connected directly over USB, download the package from the
<a href="https://github.com/nyejon/ricoh-sp112-cups/releases/latest" target="_blank" rel="noopener noreferrer" class="">latest release</a>,
install it and add the printer through <strong>System Settings → Printers &amp;
Scanners</strong>. The package is not notarized, so macOS may ask you to approve it
under <strong>System Settings → Privacy &amp; Security → Open Anyway</strong>.</p>
<p>For Unraid, clone the repository into an appdata directory, connect the printer
by USB and start the included Docker Compose configuration. The shared queue is
then available at:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">ipp://UNRAID-IP:631/printers/RICOH_SP_112</span><br></div></code></pre></div></div>
<p>It is a satisfying way to keep a simple, reliable printer useful instead of
replacing working hardware just because the original software stopped keeping
up.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Software Development" term="Software Development"/>
        <category label="Self-Hosting" term="Self-Hosting"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Production vibe coding]]></title>
        <id>https://nyejon.com/blog/production-vibe-coding</id>
        <link href="https://nyejon.com/blog/production-vibe-coding"/>
        <updated>2026-06-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[What it's like writing code in June 2026. This post will likely be outdated before I hit publish.]]></summary>
        <content type="html"><![CDATA[<p>It is June 2026. AI coding is not going away, and given the current trajectory will only get more pervasive. Software engineering is not what it used to be just a few months ago. This post will likely be outdated before I hit publish. Let's go.</p>
<!-- -->
<p>AI models can pretty much solve any trivial/medium and even "hard" task you throw at them. It's basically magic.
Tests will pass, the functions will work, and the task will be "solved".</p>
<p>You see others shipping features at the speed of prompt and you want the same. You use the tools to your advantage, as you should.</p>
<p>Overtime, you're left with a strange feeling. You reflect and think, what did I learn these last months and nothing comes to mind. At least you shipped 100 new features, and rewrote your entire codebase. Improve, enhance, repeat.</p>
<p>How do you deal with this. Let's view a few scenarios, depending on how much you care.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-stages-of-caring">The stages of caring<a href="https://nyejon.com/blog/production-vibe-coding#the-stages-of-caring" class="hash-link" aria-label="Direct link to The stages of caring" title="Direct link to The stages of caring" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="you-dont-care">You don't care<a href="https://nyejon.com/blog/production-vibe-coding#you-dont-care" class="hash-link" aria-label="Direct link to You don't care" title="Direct link to You don't care" translate="no">​</a></h3>
<p>You might look through the code on the surface and then say "looks good to me". Commit to main.</p>
<p>Job done. Let's go home.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="care-a-little-bit">Care a little bit<a href="https://nyejon.com/blog/production-vibe-coding#care-a-little-bit" class="hash-link" aria-label="Direct link to Care a little bit" title="Direct link to Care a little bit" translate="no">​</a></h3>
<p>You care a little bit, you read through the code. This is code you know well. There are some minor changes here and there that don't look too dangerous on the surface. You ask yourself, is this an improvement? Maybe. Upon closer inspection, some tradeoffs you spent many hours thinking about are ignored. You might catch the ignored tradeoff, you might not. Ultimately, the feature is shiny. You say, "how bad can it be?" and commit.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="you-care-a-lot">You care a lot<a href="https://nyejon.com/blog/production-vibe-coding#you-care-a-lot" class="hash-link" aria-label="Direct link to You care a lot" title="Direct link to You care a lot" translate="no">​</a></h3>
<p>You're different.</p>
<p>You care a lot. You take it slow. You look at your code in great detail. Inspect every change, hand-craft the architecture where needed.</p>
<p>Perfection achieved much faster than you could have done without these tools, but not quite at the speed of a prompt.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="teamwork">Teamwork<a href="https://nyejon.com/blog/production-vibe-coding#teamwork" class="hash-link" aria-label="Direct link to Teamwork" title="Direct link to Teamwork" translate="no">​</a></h2>
<p>Let's assume we're all in the "you care a lot" camp.</p>
<p>You take a day off. Someone wants to implement a new feature and vibe codes all your carefully crafted perfection away. They "fix" a bug on code they don't understand.</p>
<p>All those hours you spent thinking about the pros and cons of various decisions along the way get lost to history for the sake of speed. At least the tests pass.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-price-of-good-work">The price of good work<a href="https://nyejon.com/blog/production-vibe-coding#the-price-of-good-work" class="hash-link" aria-label="Direct link to The price of good work" title="Direct link to The price of good work" translate="no">​</a></h2>
<p>One used to have to work to produce something. Even something of poor quality. Now it is effectively free.
Anyone can produce something and at first glance it looks acceptable.
The barrier to entry is effectively zero. The barrier to reach the top is harder than before. The bar is higher and lower at the same time.</p>
<p>The people who can tell the difference between good and bad code are more powerful than before, just as a person who knows how to sew can identify what good stitching looks like on premium clothing.</p>
<p>The price of good work only increases as the need to filter out unlimited low quality output from someone takes more effort than they put into creating it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="its-not-just-coding">It's not just coding<a href="https://nyejon.com/blog/production-vibe-coding#its-not-just-coding" class="hash-link" aria-label="Direct link to It's not just coding" title="Direct link to It's not just coding" translate="no">​</a></h2>
<p>There are analogies to other industries.</p>
<p>Building has become more efficient than ever, but housing remains as expensive.
Clothing has become cheap to make, but quality has deteriorated and it gets thrown away.</p>
<p>Vice coding fits perfectly into society today of fast fashion. Your code will only last the season before falling apart. Sometimes it just goes straight to the bin.</p>
<p>It makes things more accessible, but increases the amount of energy wasted along the way.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-vybe-chicken-is-born">The vybe chicken is born<a href="https://nyejon.com/blog/production-vibe-coding#the-vybe-chicken-is-born" class="hash-link" aria-label="Direct link to The vybe chicken is born" title="Direct link to The vybe chicken is born" translate="no">​</a></h2>
<p><img decoding="async" loading="lazy" alt="vybe-chicken.jpeg" src="https://nyejon.com/assets/images/vybe-chicken-f1ca0c8998f94178b06783fb907ee306.jpeg" width="1024" height="1024" class="img_ev3q"></p>
<p>The flood of code has created the <em>vybe chicken</em>. Vybe chicken don't care. Vybe chicken ships 10 features a day.</p>
<p>Vybe chicken doesn't care about what thought others put into a bit of code. After all, the others probably didn't think, so why should it. Vybe chicken does what it's told, but no more.</p>
<p>After a while, vybe chicken spends its day only fixing bugs. Feature development slows down. Vybe chicken doesn't understand why.</p>
<p>This is the chicken's life. Vibe coding bugfixes for features which have been vibe coded. All to just ship it bro.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to">Where to<a href="https://nyejon.com/blog/production-vibe-coding#where-to" class="hash-link" aria-label="Direct link to Where to" title="Direct link to Where to" translate="no">​</a></h2>
<p>This is not a new problem. Everything and timelines have just been amplified, and without discipline will only get worse.</p>
<p>Humans have developed tools to help them since the dawn of time. Our tools get more advanced, and each comes with additional skills and education required to master them.
At university, we learned fundamentals before we learned the higher level stuff. Not because it was useful, but we understood it was necessary.</p>
<p>I've very rarely needed to use the direct fundamentals in real life, but they still help one use the more advanced tools.</p>
<p>Currently, these models are no different. Sure for simple stuff it doesn't matter, and it's addictive to feel productive.
Eventually everyone will catch up with what it really means to be productive given the current tools, and a balance will be found.</p>
<p>Or it doesn't matter as the models get so good and all these issues become irrelevant. Nobody knows.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Vybe Chicken" term="Vybe Chicken"/>
        <category label="AI" term="AI"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Hacking together JournalAIst]]></title>
        <id>https://nyejon.com/blog/journalaist-personal-ghostwriter</id>
        <link href="https://nyejon.com/blog/journalaist-personal-ghostwriter"/>
        <updated>2024-11-14T14:12:00.000Z</updated>
        <summary type="html"><![CDATA[This tells the story of the creation of JournalAIst, your own personal ghostwriter which was hacked together on a weekend.]]></summary>
        <content type="html"><![CDATA[<p>I participated in an AI hackathon with my friends <a href="https://fnands.com/" target="_blank" rel="noopener noreferrer" class="">Ferdinand Schenck</a> and Axel Nordfeldt. During the roughly 36 hours, we came up with an idea and hacked together a personal ghostwriter, which we called <a href="https://journalaist.streamlit.app/" target="_blank" rel="noopener noreferrer" class="">JournalAIst</a> and you can try out for yourself.</p>
<!-- -->
<p>This was my first hackathon in many years and it was incredibly well organized by&nbsp;<a href="https://factory.network/" target="_blank" rel="noopener noreferrer" class="">Factory Network</a>&nbsp;and&nbsp;<a href="https://www.techberlin.io/" target="_blank" rel="noopener noreferrer" class="">{Tech: Berlin}</a>. The hackathon was sponsored by&nbsp;<a href="https://mistral.ai/" target="_blank" rel="noopener noreferrer" class="">Mistral</a>,&nbsp;<a href="https://weaviate.io/" target="_blank" rel="noopener noreferrer" class="">Weaviate</a>&nbsp;and&nbsp;<a href="https://lumalabs.ai/" target="_blank" rel="noopener noreferrer" class="">LumaAI</a> who provided free credits for their platforms.</p>
<p>I have experience with natural language processing in my previous role as a data science lead, but hadn't spent much time playing around with current LLMs. These days, I mostly use them as a coding assistant. It was fun to get to test out the latest LLM, image understanding and video generation models to discover what works well (and what doesn't).</p>
<p>We had written down a few ideas before the event but after a bit of brainstorming we settled on building a ghostwriter. The idea was inspired by Axel who had someone write a beautiful story about an event in his life, which he can fondly look back at forever. Most of us don't have the will or the time to write down our experiences. When we do write them down and read them months or years later they are a pleasure to have and bring one back into the memory. I have personally started writing down summaries of any trips I go on but unfortunately often forget to or am just lazy to do a proper job.</p>
<p>I usually make time to write about my day to friends or family, typically sending along a few pictures that highlight my experiences throughout the day. Messaging in short snippets is easier than writing a perfectly written story. While messaging, we don't let perfect get in the way of good enough so we are more likely to do it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="building">Building<a href="https://nyejon.com/blog/journalaist-personal-ghostwriter#building" class="hash-link" aria-label="Direct link to Building" title="Direct link to Building" translate="no">​</a></h2>
<p>The aim, divide and conquer. Ferdi, Axel and myself broke our tasks down into separate chunks which we could stitch together. We broke the problem down into a picture summarizer, an interviewer, and a writer. As a bonus (and because we could use the API for free) we added a step to generate a 50-word description of a video to send to the LumaAI's Dream Machine model to generate a 5 second video.</p>
<p>Each stage builds upon the previous one, and the aim of each step is to capture information to help with the next task.</p>
<p>Here is a general overview of the flow:</p>
<!-- -->
<p>We had some trouble getting the model to say when the interview should end, so to save time we just added an 'End conversation' button that the user could press when they got tired.</p>
<p>&nbsp;<a href="https://github.com/nyejon/journalaist" target="_blank" rel="noopener noreferrer" class="">The code</a>&nbsp;is available in my GitHub if you wish to play around with it. To run it locally, you will need a Mistral API key, which you can get for free from their website.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-final-product">The final product<a href="https://nyejon.com/blog/journalaist-personal-ghostwriter#the-final-product" class="hash-link" aria-label="Direct link to The final product" title="Direct link to The final product" translate="no">​</a></h2>
<p>We ultimately deployed the final product to <a href="https://journalaist.streamlit.app/" target="_blank" rel="noopener noreferrer" class="">Streamlit</a> . Feel free to give it a try and let me know if you have any feedback. Please note this is hackathon quality, and was made in 24 hours!</p>
<p>Here are some screenshots of the various steps:</p>
<p><img decoding="async" loading="lazy" alt="journalaist-starting-step.png" src="https://nyejon.com/assets/images/journalaist-starting-step-3722ca6b8f2aaf6b28702141f8a6fadf.png" width="1626" height="780" class="img_ev3q"></p>
<p>The interview:</p>
<p><img decoding="async" loading="lazy" alt="journalaist-story-step.png" src="https://nyejon.com/assets/images/journalaist-story-step-f6ecf3bffd0decd5accf0c7a83812ede.png" width="1572" height="1512" class="img_ev3q"></p>
<p>Pick your story adventure:</p>
<p><img decoding="async" loading="lazy" alt="journalaist-generation-step.png" src="https://nyejon.com/assets/images/journalaist-generation-step-5f8106a1c2b73e5f111f7f1522a775cc.png" width="1582" height="804" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-output">The output<a href="https://nyejon.com/blog/journalaist-personal-ghostwriter#the-output" class="hash-link" aria-label="Direct link to The output" title="Direct link to The output" translate="no">​</a></h2>
<p>Here is an <a class="" href="https://nyejon.com/blog/tesla-journalaist-story">example story</a> that I made up and is completely fictional, but based upon my made up answers. I used the Tesla marketing images for the Fremont factory. The pictures are automatically placed alongside the relevant part of the story.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="video">Video<a href="https://nyejon.com/blog/journalaist-personal-ghostwriter#video" class="hash-link" aria-label="Direct link to Video" title="Direct link to Video" translate="no">​</a></h3>
<p>Here are some sample videos generated by the Dream Machine. They were really a bit of a hit or a miss. The less realistic the video, the better it appeared to be.</p>
<video controls="" width="100%"><source src="/assets/journalaist-luma-ai-tesla-story.mp4" type="video/mp4"></video>
<video controls="" width="100%"><source src="/assets/journalaist-luma-ai-kruger-story.mp4" type="video/mp4"></video>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://nyejon.com/blog/journalaist-personal-ghostwriter#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>We made it to the final (Top 6 of 25 teams), and really impressed the judges in our first demonstration. Our project was one of the few that actually worked, and was developed from scratch during the hackathon.</p>
<p>The final pitch went well, but the judges had some reservations about the amount of hallucinations that the models could generate. This could be reduced with better prompting and having more information added in the interview. Overall we were happy to make it to the finals, but it was bitter-sweet to leave with nothing. Maybe we could have done with a product or marketing team mate who could have sold the idea better.</p>
<p>Overall, there is something that could be useful here, and probably needs more than 24 hours to solve. It needs to be made more convenient to use and to gather more information to limit any hallucinations.</p>
<p>Convenience leads down a big privacy path due to the nature of having 'someone' follow you around and ask questions about your experiences in your life. It would need to be built in a way that doesn't stream your entire life to an unknown server. Ignoring that, ideally it should be something that could read the information you are already capturing, built into your existing flow of communication. It could summarize messages, photos and possibly even your chats about a topic with various contacts, but only extract the relevant bits for the story you would like to tell.</p>
<p>I hope you enjoyed the read, and please let me know if you have any comments!</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Software Development" term="Software Development"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Plotly Dash is all you need]]></title>
        <id>https://nyejon.com/blog/plotly-dash-is-all-you-need</id>
        <link href="https://nyejon.com/blog/plotly-dash-is-all-you-need"/>
        <updated>2024-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Plotly Dash is a great solution for complex analytics and reporting needs. It offers a near perfect balance of capability, development speed and complexity to meet the requirements of your business.]]></summary>
        <content type="html"><![CDATA[<p>… for enterprise analytics and reporting.<sup><a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#user-content-fn-1-021f46" id="user-content-fnref-1-021f46" data-footnote-ref="true" aria-describedby="footnote-label" class="anchorTargetStickyNavbar_Vzrq">1</a></sup></p>
<p><em>This post was inspired by <a href="https://world.hey.com/dhh/merchants-of-complexity-4851301b" target="_blank" rel="noopener noreferrer" class="">DHH's “Merchants of Complexity”</a>.</em></p>
<p>Over the years, I've seen many teams over-engineer their dashboards. Don't do this. What you want is something that meets your requirements, is as simple as possible and as complex as necessary.</p>
<p>In this post, I'll explain my approach to building performant dashboards that are easy to develop and maintain.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>There are many tools available for creating dashboards. They range from easy to use code-free tools, to fully custom made "solutions" built with significant investment.</p>
<p>The easy-to-use tools are great for simple reports with limited interactivity. They also don't require a development team. For many teams these will be enough.</p>
<p>On the latter end of the scale, a typical approach looks like a custom backend that interfaces with various data sources and then uses a custom React frontend. This is great if you have infinite time and resources with relaxed deadlines. But let's be real. These solutions often don't live up to their initial goals, and any changes that need to be made require input from the entire development team.</p>
<p>I've personally settled on something in the middle for my own projects. <a href="https://dash.plotly.com/" target="_blank" rel="noopener noreferrer" class="">Plotly Dash</a>. It's a versatile and simple solution for creating highly interactive dashboards.</p>
<p><img decoding="async" loading="lazy" alt="plotly-dash.png" src="https://nyejon.com/assets/images/plotly-dash-e443d29c0cdd9766a167e5d2d4e7e0e8.png" width="1650" height="1074" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="problem">Problem<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#problem" class="hash-link" aria-label="Direct link to Problem" title="Direct link to Problem" translate="no">​</a></h3>
<p>In the real world, businesses typically need to see a report on something promptly. Time is money, after all, and not having visibility into a critical process costs you money each day. Businesses might also not know exactly which metrics they need to see. They just know that they need to see something, and something is better than nothing. The development process will have a lot of back and forth, with a lot of iteration until finally settling on a solution. The key point is providing value along the way and not waiting for once everything is complete.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="solution">Solution<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#solution" class="hash-link" aria-label="Direct link to Solution" title="Direct link to Solution" translate="no">​</a></h3>
<p>Plotly Dash allows one to develop reports quickly and present them to your users within a few days, if not hours. One can iterate to provide something useful within a very short time frame. Version control and multiple environments can be set up so that any changes can easily be rolled back. To sum it up, you can move quickly and break things.</p>
<p>In addition:</p>
<ul>
<li class="">Dash looks good enough with sensible defaults.</li>
<li class="">Custom components enable your app to follow your companies design guidelines.</li>
<li class="">Fast, especially with caching.</li>
</ul>
<p>Dash allows you to build interactive dashboards quickly, at scale and provide benefits incrementally as you build.</p>
<p>Dash does require someone that can program Python and have some basic understanding of web development. However, it is easy to learn and get started with.
It can be as complex as needed and doesn't require a huge amount of boilerplate to get started. If you are more experienced, you can still use all your web development skills if you happen to have them. In my opinion, it is a huge benefit when one can have something that satisfies both the beginner and the expert, with both feeling challenged and productive.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="typical-project-layout">Typical project layout<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#typical-project-layout" class="hash-link" aria-label="Direct link to Typical project layout" title="Direct link to Typical project layout" translate="no">​</a></h2>
<p>Let's get into how to structure your Dash project and go through a few common issues that you might encounter.</p>
<p>While a Plotly Dash project is simple to set up, it still requires some overhead. A typical (maybe slightly more advanced) layout might look something like this:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">assets</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">components</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">db</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">config</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">pages</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">redis</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  - Dockerfile</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  - redis.conf</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">prometheus</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">schemas</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">tests</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">utils</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">.dockerignore</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">.gitignore</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">.pre-commit-config.yaml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">.python-version</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">config.env</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">docker-compose.yml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Dockerfile</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">gunicorn.conf.py</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">main.py</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">odbcinst.ini</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">poetry.toml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">poetry.lock</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">pyproject.toml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">README.md</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">secrets.env (Don't add to git)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="configuration">Configuration<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#configuration" class="hash-link" aria-label="Direct link to Configuration" title="Direct link to Configuration" translate="no">​</a></h2>
<p>For all my projects, I follow the <a href="https://12factor.net/" target="_blank" rel="noopener noreferrer" class="">Twelve Factor App</a> principles. Keep your config out of your code.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-config-and-secrets">Application config and secrets<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#application-config-and-secrets" class="hash-link" aria-label="Direct link to Application config and secrets" title="Direct link to Application config and secrets" translate="no">​</a></h3>
<p>For any Python application, the <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" target="_blank" rel="noopener noreferrer" class="">Pydantic Settings Management</a> works wonderfully to load your config from environment variables and validate that your config is correct.
This helps debug deployment issues and also helps document what should go into each environment variable.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="managing-data-sources-and-database-connections">Managing data sources and database connections<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#managing-data-sources-and-database-connections" class="hash-link" aria-label="Direct link to Managing data sources and database connections" title="Direct link to Managing data sources and database connections" translate="no">​</a></h3>
<p>Dash allows you to use data from any source. Databases, APIs, CSV files - it doesn't matter.</p>
<p>In some applications I've developed, it's been necessary to connect to many different databases.
This can get quite overwhelming, but a simple pattern can help manage all the connections.</p>
<p>Firstly, the database connection details are defined in your Pydantic Config. After the config has been initialised you can set up the various connections using connection strings. In this case I'm using <a href="https://www.sqlalchemy.org/" target="_blank" rel="noopener noreferrer" class="">SQLAlchemy</a> which allows connection to many databases with a common interface.</p>
<p>To standardize the connection, create a simple Pydantic model.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> pydantic </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> BaseModel</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">SQLAlchemyBind</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">BaseModel</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""SQLAlchemy bind config.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    This object is a generic representation of SQLAlchemy bind configs.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    isolation_level</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><br></div></code></pre></div></div>
<p>In the config file, define all your database connection strings.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">config </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> DashboardConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">_env_file</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"config.env"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"secrets.env"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> _env_file_encoding</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"utf-8"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># type: ignore</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">config</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sqlalchemy_binds </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"mysql_db"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> SQLAlchemyBind</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		url</span><span class="token operator" style="color:#393A34">=</span><span class="token string-interpolation string" style="color:#e3116c">f"mysql+pymysql://</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">mysql_user</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">mysql_pass</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">get_secret_value</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">@</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">mysql_host</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">mysql_port</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">/</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">mysql_name</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		isolation_level</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"READ UNCOMMITTED"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"clickhouse_db"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> SQLAlchemyBind</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		url</span><span class="token operator" style="color:#393A34">=</span><span class="token string-interpolation string" style="color:#e3116c">f"clickhouse://</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">clickhouse_username</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">clickhouse_secret</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">get_secret_value</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">@</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">clickhouse_host</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">:</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">clickhouse_port</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">/</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">config</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">clickhouse_name</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		isolation_level</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><br></div></code></pre></div></div>
<p>To create and collect all the database sessions, create an <code>init_sessions</code> function which will store all the database sessions in a dictionary as a singleton.</p>
<p>You can then access a particular database session using <code>database_sessions[bind]</code>.</p>
<p>In <code>db/__init__.py</code>:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">database_sessions</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">dict</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> scoped_session</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@contextmanager</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">query_db</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    query_path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> bind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> params</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">dict</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> Generator</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">dict</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Any</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""Executes the given query and returns the results.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    Parameters</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    ----------</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    query_path: str</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">        Path to the query file</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    bind: str</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">        sqlalchemy bind id</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    params: dict</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">        Parameters to render in query</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    Yields</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    ------</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    list[Dict[str, Any]]: query results</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">try</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">with</span><span class="token plain"> </span><span class="token builtin">open</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">query_path</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"r"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> f</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            query </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> f</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">read</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">except</span><span class="token plain"> FileNotFoundError </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Error opening query file </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">query_path</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">raise</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">except</span><span class="token plain"> Exception </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"An unexpected error occurred while opening query file </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">query_path</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">raise</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    db_session </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> database_sessions</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">bind</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    session </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> db_session</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">try</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">debug</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Query </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">bind</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">query_path</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c"> executed with params </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">params</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        results </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">execute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">query</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> params</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">params</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">mappings</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token builtin">all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Convert SQLAlchemy Row to dict for compatibility</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">yield</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">dict</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">row</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> row </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> results</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">except</span><span class="token plain"> Exception </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"An error occurred while executing query </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">query_path</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">raise</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">finally</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">try</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            db_session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">close</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">except</span><span class="token plain"> Exception </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> e</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"An error occurred while closing the database session: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">e</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">init_sessions</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> bind </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> config</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sqlalchemy_binds</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">keys</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        engine </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> create_engine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            url</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">config</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sqlalchemy_binds</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">bind</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">url</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            isolation_level</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">config</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sqlalchemy_binds</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">bind</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">isolation_level</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            pool_recycle</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3600</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            pool_pre_ping</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        session_factory </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> sessionmaker</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">bind</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">engine</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        db_session </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> scoped_session</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">session_factory</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        database_sessions</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">bind</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> db_session</span><br></div></code></pre></div></div>
<p>I personally put all queries into <code>.sql</code> files structured according to the database name. The queries can be linted and formatted with <a href="https://sqlfluff.com/" target="_blank" rel="noopener noreferrer" class="">SQLFluff</a>.</p>
<p>Then you can use the query using the template:</p>
<p><code>db/clickhouse.py</code></p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@cache</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">memoize</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">config</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">cache_timeout_seconds</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get_ultimate_question</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    parameter_one</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> pl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DataFrame</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">with</span><span class="token plain"> get_result</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        query_path</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"db/queries/clickhouse/some_amazing_query.sql"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        bind</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"clickhouse"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        params</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string" style="color:#e3116c">"parameter_one"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> parameter_one</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> results</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        ultimate_question </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> pl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DataFrame</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            results</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            schema</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"name"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> pl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Utf8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"date"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> pl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Date</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"hour"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> pl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Int8</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token string" style="color:#e3116c">"answer"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> pl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Int16</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            orient</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"row"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic"># Any other logic you need in Python...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ultimate_question</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="caching-and-background-callbacks">Caching and background callbacks<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#caching-and-background-callbacks" class="hash-link" aria-label="Direct link to Caching and background callbacks" title="Direct link to Caching and background callbacks" translate="no">​</a></h2>
<p>Caching is important for any Plotly Dash app to ensure good performance. It limits recomputing things unnecessarily.</p>
<p>Because Plotly Dash is based on Flask, one can just use the excellent <a href="https://flask-caching.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class="">Flask Caching</a>  library.</p>
<p>After setting it up, function calls are cached with the <code>@cache.memoize</code> decorator. In practice, this usually means adding the decorator to any database query functions to cache the database queries but any function can be cached using this pattern.</p>
<p>The cached data can then be used in multiple callbacks, without having to make repeat database queries.</p>
<p>Caching goes hand in hand with using <a href="https://dash.plotly.com/background-callbacks" target="_blank" rel="noopener noreferrer" class="">background callbacks</a> to execute queries that take longer than a few seconds.
Functions that query the database are called first in the background callback. Once the background callback is complete a subsequent callback can call that same function and get the result almost immediately.</p>
<p>This leads onto the next topic...</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="background-callback-signalling">Background callback signalling<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#background-callback-signalling" class="hash-link" aria-label="Direct link to Background callback signalling" title="Direct link to Background callback signalling" translate="no">​</a></h3>
<p>Signalling is the process of letting one callback know that the long running background callback is complete.</p>
<p>The general pattern goes like this:</p>
<!-- -->
<p>The general steps of the code below are:</p>
<ol>
<li class="">Add a <code>dcc.Store</code> component to our layout.</li>
<li class="">Create a background callback that calls the expensive function and outputs a "signalling" value to the dcc.Store when it's complete.</li>
<li class="">Create another callback that uses the dcc.Store as an input so that it is only triggered once the expensive function is complete.</li>
</ol>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Add to layout</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">data_signal_store </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> dcc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Store</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">id</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"data-signal-store"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@callback</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Output</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"data-signal-store"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"data"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Input</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"date-picker"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"date"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    background</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fetch_data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">datestr</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""Fetches the data in the background</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    _date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> datetime</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">strptime</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">datestr</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> DATE_FORMAT_STRING</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic"># Takes a long time to execute</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    data_df </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> get_clickhouse_data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">date</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">_date</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"signal-</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">start_datetime</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">strftime</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">DATE_FORMAT_STRING</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@dash</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">callback</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Output</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"output-one"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"children"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Output</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"output-two"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"children"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Input</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"data-signal-store"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"data"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    State</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"date-picker"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"date"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">update_widget</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    board_state_signal</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    datestr</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">tuple</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""Updates the widgets with the data</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    _date </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> datetime</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">strptime</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">datestr</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> DATE_FORMAT_STRING</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic"># Gets fetched from cache</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	data_df </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> get_clickhouse_data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">date</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">_date</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic"># Other logic</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> widget_one</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> widget_two</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div></code></pre></div></div>
<p>In this way, we can ensure the long-running tasks always execute before the main callbacks as Dash will only execute the <code>update_widget</code> callback once the background callback is complete.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="authentication">Authentication<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#authentication" class="hash-link" aria-label="Direct link to Authentication" title="Direct link to Authentication" translate="no">​</a></h2>
<p>As Dash is based upon Flask, you can just use <a href="https://flask-login.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class="">Flask Login</a> to manage your Auth.</p>
<p>Create routes for your particular use case such as <em>/login</em>, <em>/unauthorized</em>, <em>/auth</em> on the Flask server directly …</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@server</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">route</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> methods</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"GET"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">login</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    next_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> flask</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"next"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Validate that next is a valid url and has the same host as the server</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    valid_next_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> validate_next_parameter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">flask</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">request</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next_url</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">not</span><span class="token plain"> valid_next_url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Invalid URL for redirect"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    flash</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"You have to be logged in to access this page."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">info</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Logging user in..."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Custom login logic</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> redirect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">url</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">/?next=</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">next_url</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><br></div></code></pre></div></div>
<p>... then add authentication to routes by checking whether the user is logged in before every request. Here is an example:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@server</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">before_request</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">before_request_func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Allow the auth routes</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    allowed_paths </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/alive"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/ready"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/auth"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/unauthorized"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"/login"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">not</span><span class="token plain"> current_user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">is_authenticated </span><span class="token keyword" style="color:#00009f">and</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">not</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">startswith</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> path </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> allowed_paths</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        next_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> request</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">url</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        valid_next_url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> validate_next_parameter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">flask</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">request</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next_url</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">not</span><span class="token plain"> valid_next_url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Invalid URL for redirect"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">400</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> redirect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token string-interpolation string" style="color:#e3116c">f"/login?next=</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">next_url</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="embedding-your-application-in-an-iframe">Embedding your application in an iFrame<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#embedding-your-application-in-an-iframe" class="hash-link" aria-label="Direct link to Embedding your application in an iFrame" title="Direct link to Embedding your application in an iFrame" translate="no">​</a></h3>
<p>I sometimes have the case where users would like to embed certain graphs in Confluence or some other tool. To achieve this, one needs to add the website to <em>X-Frame-Options</em> and <em>Content-Security-Policy</em> in the request headers. To read more about these policies see <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" target="_blank" rel="noopener noreferrer" class="">Content Security Policy</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy" target="_blank" rel="noopener noreferrer" class="">Same-origin policy</a>.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token decorator annotation punctuation" style="color:#393A34">@server</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">after_request</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add_headers</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">headers</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"X-Frame-Options"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ALLOW-FROM https://confluence.com/"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">headers</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">"Content-Security-Policy"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"frame-ancestors 'self' https://confluence.com/;"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> response</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="logging-and-metrics">Logging and metrics<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#logging-and-metrics" class="hash-link" aria-label="Direct link to Logging and metrics" title="Direct link to Logging and metrics" translate="no">​</a></h2>
<p>I like to use <a href="https://github.com/Delgan/loguru" target="_blank" rel="noopener noreferrer" class="">Loguru</a> for logging and <a href="https://pypi.org/project/prometheus-flask-exporter/" target="_blank" rel="noopener noreferrer" class="">Prometheus</a> for metrics. You can then use your companies usual monitoring tools such as <a href="https://grafana.com/" target="_blank" rel="noopener noreferrer" class="">Grafana</a> or <a href="https://www.elastic.co/elastic-stack" target="_blank" rel="noopener noreferrer" class="">ELK</a> to monitor the usage of your application.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="customizing-components">Customizing components<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#customizing-components" class="hash-link" aria-label="Direct link to Customizing components" title="Direct link to Customizing components" translate="no">​</a></h2>
<p>Many companies have their own design system and typically want any developed applications to match their design. With Plotly Dash, you can relatively easily convert your companies components (especially if they are React components) to Dash components. They even provide a <a href="https://github.com/plotly/dash-component-boilerplate" target="_blank" rel="noopener noreferrer" class="">template</a> to start with.</p>
<p>Alternatively, if you just want something that looks good without too much customization <a href="https://dash-bootstrap-components.opensource.faculty.ai/" target="_blank" rel="noopener noreferrer" class="">Dash Bootstrap Components</a> or <a href="https://www.dash-mantine-components.com/" target="_blank" rel="noopener noreferrer" class="">Dash Mantine Components</a> are good alternatives to the dash core components.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploying">Deploying<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#deploying" class="hash-link" aria-label="Direct link to Deploying" title="Direct link to Deploying" translate="no">​</a></h2>
<p>Deploying a Dash app is pretty easy. To include caching and background jobs, it requires just three containers.
One for the Dash app itself, one for the background jobs and one for Redis.</p>
<p>Where to deploy is a matter of personal preference. I've always deployed to Kubernetes using a CI pipeline for seamless updates but docker compose would work just as well.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="local-testing-with-docker">Local testing with Docker<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#local-testing-with-docker" class="hash-link" aria-label="Direct link to Local testing with Docker" title="Direct link to Local testing with Docker" translate="no">​</a></h3>
<p>This can all be tested locally with docker.</p>
<p><code>docker-compose.yaml</code></p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">services</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">myapp</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">platform</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> linux/arm64</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">build</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> .</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">dockerfile</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Dockerfile</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">ports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> 8080</span><span class="token punctuation" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">8080</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> 8050</span><span class="token punctuation" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">8050</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">volumes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> ./config.env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/app/config.env</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> ./secrets.env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/app/secrets.env</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> .</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">delegated</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /app/.venv</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> prometheus_data</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/prometheus</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">environment</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> GIT_COMMIT=latest</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> GIT_BRANCH=latest</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> BUILD_TIMESTAMP=now</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> PYTHONUNBUFFERED=1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> USE_REDIS=True</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> REDIS_DSN=redis</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"gunicorn"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"main:server"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"--reload"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"--workers=1"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">dash-celery</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">platform</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> linux/arm64</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">build</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> .</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">dockerfile</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Dockerfile</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">ports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> 5555</span><span class="token punctuation" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">5555</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">volumes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> ./config.env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/app/config.env</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> ./secrets.env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/app/secrets.env</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> .</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">delegated</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /app/.venv</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> prometheus_data</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">/prometheus</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">tmpfs</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /tmp</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">exec</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">size=100M</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">entrypoint</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"celery"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">command</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'-A'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'main:celery_app'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'worker'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'--loglevel=debug'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'--concurrency=2'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'--without-mingle'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'-n'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'worker1'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"--prefetch-multiplier=1"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">environment</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> GIT_COMMIT=latest</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> GIT_BRANCH=latest</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> BUILD_TIMESTAMP=now</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> USE_REDIS=True</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> REDIS_DSN=redis</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> PROMETHEUS_MULTIPROC_DIR=./prometheus</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">redis</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">build</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">context</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ./redis/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">dockerfile</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Dockerfile</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">ports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> 6379</span><span class="token punctuation" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">6379</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">volumes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  prometheus_data</span><span class="token punctuation" style="color:#393A34">:</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="adding-pages-and-creating-direct-links-to-reports">Adding pages and creating direct links to reports<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#adding-pages-and-creating-direct-links-to-reports" class="hash-link" aria-label="Direct link to Adding pages and creating direct links to reports" title="Direct link to Adding pages and creating direct links to reports" translate="no">​</a></h2>
<p>Dash supports <a href="https://dash.plotly.com/urls" target="_blank" rel="noopener noreferrer" class="">multiple pages</a>, so the different pages go into the <code>pages</code> folder.</p>
<p>Once the initial overhead of setting up the database connections, deployments and creating a few sample pages even inexperienced developers and analysts can create new pages using the existing ones as a template.</p>
<p>It's as easy as copying an existing page from your <code>pages</code> folder and editing as needed.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="sharing-views">Sharing views<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#sharing-views" class="hash-link" aria-label="Direct link to Sharing views" title="Direct link to Sharing views" translate="no">​</a></h3>
<p>Sharing reports with others can be done using query parameters as long as you ensure all callback inputs are parametrized in the URL.
This means you can share the exact view by copying the URL.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Add to the header in your main layout</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">dcc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Location</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">id</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"url"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> refresh</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">False</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># In each page create the following callback</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator annotation punctuation" style="color:#393A34">@dash</span><span class="token decorator annotation punctuation" style="color:#393A34">.</span><span class="token decorator annotation punctuation" style="color:#393A34">callback</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Output</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"url"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"search"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> allow_duplicate</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Input</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"input-one"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"value"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    Input</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"input-two"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"value"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    prevent_initial_call</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"initial_duplicate"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">update_url_state</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    input_one</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    input_two</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    Updates the URL query parameters based upon the input values</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    params </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> input_one</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	    </span><span class="token comment" style="color:#999988;font-style:italic">#Serialize any objects to json</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        params </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"input_one=</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">json</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">.</span><span class="token string-interpolation interpolation">dumps</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation">input_one</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">,</span><span class="token string-interpolation interpolation"> separators</span><span class="token string-interpolation interpolation operator" style="color:#393A34">=</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">(</span><span class="token string-interpolation interpolation string" style="color:#e3116c">','</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">,</span><span class="token string-interpolation interpolation"> </span><span class="token string-interpolation interpolation string" style="color:#e3116c">':'</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">)</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> input_two</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        params </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"&amp;input_two=</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">input_two</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> params </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"?</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">params</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Define the layout for the page with the parameters and inputs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">layout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    input_one</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    input_two</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">int</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> dash</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">development</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">base_component</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Component</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic"># Deserialize the object from json in the query parameter</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	_input_one </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> input_one</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		_input_one </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> json</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">loads</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">input_one</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"> other layout</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Dash is a great tool to create easy to update and maintainable reports. Once the initial overhead of configuration and deployment is done, adding and updating reports becomes trivial. If someone in your company is proposing to create over-engineered reporting infrastructure, pause for a moment and ask yourself whether it is really needed.</p>
<p>In many cases, something simpler might be all that's required.</p>
<p>You might find that all you need is Dash.</p>
<hr>
<p>Please let me know if I have missed something or made any mistakes.</p>
<!-- -->
<section data-footnotes="true" class="footnotes"><h2 class="anchor anchorTargetStickyNavbar_Vzrq sr-only" id="footnote-label">Footnotes<a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#footnote-label" class="hash-link" aria-label="Direct link to Footnotes" title="Direct link to Footnotes" translate="no">​</a></h2>
<ol>
<li class="anchorTargetStickyNavbar_Vzrq" id="user-content-fn-1-021f46">
<p>This is assuming you already some some databases or data sources that you can utilise for your dashboards. <a href="https://nyejon.com/blog/plotly-dash-is-all-you-need#user-content-fnref-1-021f46" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref">↩</a></p>
</li>
</ol>
</section>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Software Development" term="Software Development"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introduction to OEE]]></title>
        <id>https://nyejon.com/blog/oee-introduction</id>
        <link href="https://nyejon.com/blog/oee-introduction"/>
        <updated>2024-01-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[OEE is the most important KPI in manufacturing. Being able to understand and interpret this number is critical to improve your manufacturing process.]]></summary>
        <content type="html"><![CDATA[<p>Overall Equipment Effectiveness, usually referred to as OEE, is one of the main manufacturing metrics to measure productivity.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://nyejon.com/blog/oee-introduction#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>Across different industries there are many ways to measure productivity. In manufacturing, OEE is the metric most commonly used to know how productive your factory is.</p>
<p>OEE is a subset of the Total Effective Equipment Performance (TEEP) which is defined as the total amount of units a line could produce if it ran perfectly all the time.</p>
<p>There is a great resource online at <a href="https://www.oee.com/" target="_blank" rel="noopener noreferrer" class="">oee.com</a> to learn about OEE. I suggest you read it thoroughly.
This post will act as a summary with practical examples to understand OEE.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-do-we-measure-oee">Why do we measure OEE?<a href="https://nyejon.com/blog/oee-introduction#why-do-we-measure-oee" class="hash-link" aria-label="Direct link to Why do we measure OEE?" title="Direct link to Why do we measure OEE?" translate="no">​</a></h2>
<p>Measuring OEE allows us to answer a few important questions when running a production line.</p>
<ol>
<li class="">How well are we performing compared to the ideal case?</li>
<li class="">Why didn't we hit our production targets?</li>
<li class="">What can we do to increase the productivity of our line?</li>
</ol>
<p>These three questions can be broken down further, depending on whether it is an engineer or manager asking the question.</p>
<p>The key outcome, is helping one figure out where to allocate resources to get the biggest increase in productivity. We want more product out for less money in.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="oee-definition">OEE Definition<a href="https://nyejon.com/blog/oee-introduction#oee-definition" class="hash-link" aria-label="Direct link to OEE Definition" title="Direct link to OEE Definition" translate="no">​</a></h2>
<p>OEE has the following mathematical definition:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right" columnspacing=""><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>O</mi><mi>E</mi><mi>E</mi><mo>=</mo><mfrac><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>u</mi><mi>n</mi><mi>i</mi><mi>t</mi><mi>s</mi><mo>×</mo><mi>T</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>e</mi><mi>t</mi><mtext>  </mtext><mi>C</mi><mi>y</mi><mi>c</mi><mi>l</mi><mi>e</mi><mtext>  </mtext><mi>T</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow><mrow><mi>P</mi><mi>l</mi><mi>a</mi><mi>n</mi><mi>n</mi><mi>e</mi><mi>d</mi><mtext>  </mtext><mi>P</mi><mi>r</mi><mi>o</mi><mi>d</mi><mi>u</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><mtext>  </mtext><mi>T</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
OEE = \frac{Good\;units \times Target\;Cycle\;Time}{Planned\;Production\;Time}
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.0574em;vertical-align:-0.7787em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2787em"><span style="top:-3.2787em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">O</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">ann</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">u</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">u</span><span class="mord mathnormal">ni</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0715em">C</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7787em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2787em"><span style="top:-3.2787em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7787em"><span></span></span></span></span></span></span></span></span>
<p>OEE can be defined as the ratio of good units produced to the theoretical number of units that could have been produced in a given amount of working time.
This means that OEE can never exceed 100% and is bound within the range of 0 to 100. In comparison to TEEP, it excludes any losses due to your scheduling and only considers planned production time.</p>
<p>Any reduction, from the ideal 100%, in OEE is caused for a particular reason. These are known as losses, or reasons why we couldn't produce at 100% of our capacity. The common losses are typically:</p>
<ul>
<li class="">Availability loss - Production lost due to the equipment not being able to produce.</li>
<li class="">Performance loss - Production lost due to slow cycles.</li>
<li class="">Quality loss - Production lost due to poor quality/scrap.</li>
</ul>
<p>Graphically, we can visualize everything we have defined with the figure below:</p>
<p><img decoding="async" loading="lazy" alt="OEE.svg" src="https://nyejon.com/assets/images/OEE-2a39c5f7998adacfed77b90c5a203bbc.svg" width="821" height="554" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="allocating-losses">Allocating losses<a href="https://nyejon.com/blog/oee-introduction#allocating-losses" class="hash-link" aria-label="Direct link to Allocating losses" title="Direct link to Allocating losses" translate="no">​</a></h2>
<p>OEE is often represented as the product of availability, performance, and quality.</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>O</mi><mi>E</mi><mi>E</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>U</mi><mi>n</mi><mi>i</mi><mi>t</mi><mi>s</mi><mo>×</mo><mi>T</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>e</mi><mi>t</mi><mtext>  </mtext><mi>C</mi><mi>y</mi><mi>c</mi><mi>l</mi><mi>e</mi><mtext>  </mtext><mi>T</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow><mrow><mi>P</mi><mi>l</mi><mi>a</mi><mi>n</mi><mi>n</mi><mi>e</mi><mi>d</mi><mtext>  </mtext><mi>P</mi><mi>r</mi><mi>o</mi><mi>d</mi><mi>u</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><mtext>  </mtext><mi>T</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>A</mi><mi>v</mi><mi>a</mi><mi>i</mi><mi>l</mi><mi>a</mi><mi>b</mi><mi>i</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi><mo>×</mo><mi>P</mi><mi>e</mi><mi>r</mi><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi><mi>a</mi><mi>n</mi><mi>c</mi><mi>e</mi><mo>×</mo><mi>Q</mi><mi>u</mi><mi>a</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
OEE &amp; = \frac{Good\;Units \times Target\;Cycle\;Time}{Planned\;Production\;Time} \\
    &amp; = Availability \times Performance \times Quality
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.5574em;vertical-align:-1.5287em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0287em"><span style="top:-4.0287em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">O</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span></span></span><span style="top:-2.2027em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5287em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0287em"><span style="top:-4.0287em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">ann</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">u</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.109em">U</span><span class="mord mathnormal">ni</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0715em">C</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.2027em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">ai</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">abi</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">man</span><span class="mord mathnormal">ce</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal">Q</span><span class="mord mathnormal">u</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5287em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0287em"><span style="top:-4.0287em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-2.2027em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5287em"><span></span></span></span></span></span></span></span></span>
<p>Frequently, people confuse the two methods of calculating OEE as two separate definitions. The value of OEE is always the same with both methods of calculation.
Specifically, the breakdown into A, P and Q is only used to allocate the reasons for an OEE reduction to a specific category so that you know what needs to be changed to improve OEE the most. If you get different values for OEE with the two calculation methods, you have made a mistake and are ignoring some unknown losses.</p>
<p>Availability, performance, and quality are defined as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right" columnspacing=""><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>A</mi><mi>v</mi><mi>a</mi><mi>i</mi><mi>l</mi><mi>a</mi><mi>b</mi><mi>i</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi><mo>=</mo><mfrac><mrow><mi>R</mi><mi>u</mi><mi>n</mi><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow><mrow><mi>P</mi><mi>l</mi><mi>a</mi><mi>n</mi><mi>n</mi><mi>e</mi><mi>d</mi><mtext>  </mtext><mi>P</mi><mi>r</mi><mi>o</mi><mi>d</mi><mi>u</mi><mi>c</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><mtext>  </mtext><mi>T</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Availability = \frac{Runtime}{Planned\;Production\;Time}
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.0463em;vertical-align:-0.7732em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2732em"><span style="top:-3.2732em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">ai</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">abi</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3603em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">ann</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal">u</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0077em">R</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7732em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2732em"><span style="top:-3.2732em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7732em"><span></span></span></span></span></span></span></span></span>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right" columnspacing=""><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>P</mi><mi>e</mi><mi>r</mi><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi><mi>a</mi><mi>n</mi><mi>c</mi><mi>e</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>e</mi><mi>t</mi><mtext>  </mtext><mi>C</mi><mi>y</mi><mi>c</mi><mi>l</mi><mi>e</mi><mtext>  </mtext><mi>T</mi><mi>i</mi><mi>m</mi><mi>e</mi><mo>×</mo><mo stretchy="false">(</mo><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>U</mi><mi>n</mi><mi>i</mi><mi>t</mi><mi>s</mi><mo>+</mo><mi>S</mi><mi>c</mi><mi>r</mi><mi>a</mi><mi>p</mi><mo stretchy="false">)</mo></mrow><mrow><mi>R</mi><mi>u</mi><mi>n</mi><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Performance=\frac{Target\;Cycle\;Time \times (Good\;Units + Scrap)}{Runtime}
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.113em;vertical-align:-0.8065em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3065em"><span style="top:-3.3065em"><span class="pstrut" style="height:3.427em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">man</span><span class="mord mathnormal">ce</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0077em">R</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0715em">C</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mopen">(</span><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.109em">U</span><span class="mord mathnormal">ni</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.0576em">S</span><span class="mord mathnormal" style="margin-right:0.0278em">cr</span><span class="mord mathnormal">a</span><span class="mord mathnormal">p</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8065em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3065em"><span style="top:-3.3065em"><span class="pstrut" style="height:3.427em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8065em"><span></span></span></span></span></span></span></span></span>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right" columnspacing=""><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>Q</mi><mi>u</mi><mi>a</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi><mo>=</mo><mfrac><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>U</mi><mi>n</mi><mi>i</mi><mi>t</mi><mi>s</mi></mrow><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>U</mi><mi>n</mi><mi>i</mi><mi>t</mi><mi>s</mi><mo>+</mo><mi>S</mi><mi>c</mi><mi>r</mi><mi>a</mi><mi>p</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Quality=\frac{Good\;Units}{Good\;Units + Scrap}
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.2519em;vertical-align:-0.8759em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3759em"><span style="top:-3.3759em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="mord mathnormal">u</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.109em">U</span><span class="mord mathnormal">ni</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.0576em">S</span><span class="mord mathnormal" style="margin-right:0.0278em">cr</span><span class="mord mathnormal">a</span><span class="mord mathnormal">p</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.109em">U</span><span class="mord mathnormal">ni</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8759em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3759em"><span style="top:-3.3759em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8759em"><span></span></span></span></span></span></span></span></span>
<p>Multiplying all of these together, results in the initial OEE formula defined above.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="line-vs-equipment-oee-and-loss-breakdown">Line vs equipment OEE and loss breakdown<a href="https://nyejon.com/blog/oee-introduction#line-vs-equipment-oee-and-loss-breakdown" class="hash-link" aria-label="Direct link to Line vs equipment OEE and loss breakdown" title="Direct link to Line vs equipment OEE and loss breakdown" translate="no">​</a></h2>
<p>The OEE losses will be measured differently depending on whether you are measuring it at the equipment or line level.</p>
<p>For the equipment level measurement, the OEE losses allows you to determine how the specific equipment is performing and understand the reasons why.
As an example, the machine might be operating perfectly, but it does not get enough parts coming in due to an upstream process issue.
Equipment OEE enables you to understand the root causes for lost output on a specific piece of equipment.</p>
<p>For line level measurement, the OEE allows you to compare how the entire line, department, or factory is doing.
Line OEE enables you to determine where the bottlenecks are that prevent you from increasing your output of the complete end product.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="oee-example">OEE example<a href="https://nyejon.com/blog/oee-introduction#oee-example" class="hash-link" aria-label="Direct link to OEE example" title="Direct link to OEE example" translate="no">​</a></h2>
<p>Let's work through an example. We are going to calculate OEE for something we are all familiar with… A road trip.</p>
<p>We are going on a road trip to our holiday destination 1000 km away.</p>
<p>To start, we define our TEEP for our car. We can define the limit of TEEP of our car as if we drove it 100% of the time at the speed limit with every kilometer driven taking us closer to our destination, with no problems, maintenance or need to stop for a charge. Obviously this is impossible, but theoretically a car is being wasted every time it is not used or drives a kilometre that doesn't need to be driven. All roads should point directly to our destination.</p>
<p>For our road trip, we plan to drive 1000&nbsp;km in a single day and assume a 100 kmh average speed limit (To keep things simple) so we could drive 2400km a day if we drove 100% of the time.</p>
<p>Therefore, we can define our utilization or TEEP with ideal OEE as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>U</mi><mi>t</mi><mi>l</mi><mi>i</mi><mi>z</mi><mi>a</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>P</mi><mi>l</mi><mi>a</mi><mi>n</mi><mi>n</mi><mi>e</mi><mi>d</mi><mtext>  </mtext><mi>u</mi><mi>s</mi><mi>a</mi><mi>g</mi><mi>e</mi></mrow><mrow><mi>A</mi><mi>l</mi><mi>l</mi><mtext>  </mtext><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mn>1000</mn><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow><mrow><mn>2400</mn><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.42</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Utlization &amp;= \frac{Planned\;usage}{All\;time} \\
 &amp;= \frac{1000\;km}{2400\;km}\\
 &amp; \approx 0.42
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:5.9149em;vertical-align:-2.7074em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2074em"><span style="top:-5.2074em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.109em">U</span><span class="mord mathnormal" style="margin-right:0.0197em">tl</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.044em">z</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span></span></span><span style="top:-2.85em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span><span style="top:-1.024em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7074em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2074em"><span style="top:-5.2074em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">ann</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">u</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.85em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">2400</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">1000</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-1.024em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.42</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7074em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2074em"><span style="top:-5.2074em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-2.85em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-1.024em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7074em"><span></span></span></span></span></span></span></span></span>
<p>This means, that assuming our car works perfectly all the time on this trip, we will get a utilization of 0.42 for the day.</p>
<p>As a side-note:</p>
<p>Typically, a car will be used for less than 2 hours a day, and often driven slower than the ideal speed. Car sharing companies effectively hope to make money by increasing this utilization rate of a car. They make more use of each car in a given time (And pass on any losses while the car is being used to the customer).</p>
<p>If we want to calculate the OEE of our trip, we can define this as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>O</mi><mi>E</mi><mi>E</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>k</mi><mi>m</mi><mo>×</mo><mi>T</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>e</mi><mi>t</mi><mtext>  </mtext><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi><mtext>  </mtext><mi>p</mi><mi>e</mi><mi>r</mi><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow><mrow><mi>T</mi><mi>r</mi><mi>i</mi><mi>p</mi><mtext>  </mtext><mi>l</mi><mi>e</mi><mi>n</mi><mi>g</mi><mi>t</mi><mi>h</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mn>1000</mn><mo>×</mo><mn>0.6</mn></mrow><mn>780</mn></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.77</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
OEE &amp;= \frac{Good\;km \times Target\;time\;per\;km}{Trip\;length} \\
   &amp;= \frac{1000 \times 0.6}{780}\\
   &amp;\approx 0.77
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6.0593em;vertical-align:-2.7797em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">O</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">780</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">1000</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">0.6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.77</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span></span></span></span>
<p>Now we want to figure out how we could have reached our destination sooner. We ended up taking an additional 3 hours to reach our destination, as if we could have driven at the speed limit without stopping the entire way.</p>
<p>To do this, we want to determine our losses. Why did we take longer to reach our destination than planned?</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="quality-loss-of-our-road-trip">Quality loss of our road trip<a href="https://nyejon.com/blog/oee-introduction#quality-loss-of-our-road-trip" class="hash-link" aria-label="Direct link to Quality loss of our road trip" title="Direct link to Quality loss of our road trip" translate="no">​</a></h3>
<p>In our case, we can specify a good kilometre as a kilometre travelled that brings us closer to our destination.
Extra kilometres needed to get to a charging point, stop off for snacks or do some sightseeing add kilometres to our trip and don't bring us closer to the destination.</p>
<p>Let's say we had to do an extra 50 km. There were a few reasons for this:</p>
<ul>
<li class="">There was a nice tourist attraction on the way that the family desperately wanted to see</li>
<li class="">We took a wrong turn, driving in the wrong direction because the kids were playing with the navigation</li>
<li class="">We took a slight detour to a get to a closer charging point because we misjudged how far we could travel on a charge</li>
<li class="">The roads are not a straight line from our house to our destination</li>
</ul>
<p>We can therefore define the quality of our trip as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>Q</mi><mi>u</mi><mi>a</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>k</mi><mi>m</mi><mo>+</mo><mi>E</mi><mi>x</mi><mi>t</mi><mi>r</mi><mi>a</mi><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mn>1000</mn><mrow><mn>1000</mn><mo>+</mo><mn>50</mn></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.95</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Quality &amp;= \frac{Good\;km}{Good\;km+Extra\;km} \\
        &amp;= \frac{1000}{1000+50} \\
        &amp;\approx 0.95
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6.0315em;vertical-align:-2.7658em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2658em"><span style="top:-5.2658em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="mord mathnormal">u</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span></span></span><span style="top:-2.875em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span><span style="top:-0.9657em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7658em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2658em"><span style="top:-5.2658em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal">x</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.875em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">1000</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">50</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">1000</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9657em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.95</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7658em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2658em"><span style="top:-5.2658em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-2.875em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-0.9657em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7658em"><span></span></span></span></span></span></span></span></span>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="availability-loss-of-our-road-trip">Availability loss of our road trip<a href="https://nyejon.com/blog/oee-introduction#availability-loss-of-our-road-trip" class="hash-link" aria-label="Direct link to Availability loss of our road trip" title="Direct link to Availability loss of our road trip" translate="no">​</a></h3>
<p>While driving, we needed to stop to supercharge a few times, change a tyre, eat, balance our fluid levels and spend time enjoying the view.</p>
<p>We needed 1.5 hours to charge and managed to fit our eating and fluid level balancing into this time. Unfortunately, we spent 30 minutes changing a burst tyre, because we forgot to check the tyre pressure before the trip.</p>
<p>As this is a road trip, we spent some time enjoying the view. Do you think we should allocate this loss to availability or performance? In this case we are calculating the OEE for the car and the car was available to drive. It is you, the operator, that spent some time to enjoy the view. We therefore will allocate it as a performance loss in the next section. The car was starved of its driver.</p>
<p>Taking all of this into account, we can define the availability of the trip as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>A</mi><mi>v</mi><mi>a</mi><mi>i</mi><mi>l</mi><mi>a</mi><mi>b</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>D</mi><mi>r</mi><mi>i</mi><mi>v</mi><mi>i</mi><mi>n</mi><mi>g</mi><mtext>  </mtext><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow><mrow><mi>T</mi><mi>r</mi><mi>i</mi><mi>p</mi><mtext>  </mtext><mi>l</mi><mi>e</mi><mi>n</mi><mi>g</mi><mi>t</mi><mi>h</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mn>660</mn><mn>780</mn></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.85</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Availablity &amp;= \frac{Driving\;time}{Trip\;length}\\
		    &amp;=\frac{660}{780} \\
            &amp;\approx 0.85
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6.0482em;vertical-align:-2.7741em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2741em"><span style="top:-5.2741em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">ai</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">ab</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span></span></span><span style="top:-2.7722em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"></span></span><span style="top:-0.9462em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7741em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2741em"><span style="top:-5.2741em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3603em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">D</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.7722em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">780</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">660</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9462em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.85</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7741em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2741em"><span style="top:-5.2741em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span><span style="top:-2.7722em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span><span style="top:-0.9462em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7741em"><span></span></span></span></span></span></span></span></span>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="performance-loss-of-our-trip">Performance loss of our trip<a href="https://nyejon.com/blog/oee-introduction#performance-loss-of-our-trip" class="hash-link" aria-label="Direct link to Performance loss of our trip" title="Direct link to Performance loss of our trip" translate="no">​</a></h3>
<p>As mentioned before, we spent some time enjoying the view, but we also encountered some other issues on the way.</p>
<p>We ended up driving some kilometres where we couldn't drive at the speed limit due to road works. We also hit some stop start traffic. We were blocked.</p>
<p>We will allocate all of these other losses as a loss of performance:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>P</mi><mi>e</mi><mi>r</mi><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi><mi>a</mi><mi>n</mi><mi>c</mi><mi>e</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>T</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>e</mi><mi>t</mi><mtext>  </mtext><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi><mtext>  </mtext><mi>p</mi><mi>e</mi><mi>r</mi><mtext>  </mtext><mi>k</mi><mi>m</mi><mo>×</mo><mi>T</mi><mi>o</mi><mi>t</mi><mi>a</mi><mi>l</mi><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow><mrow><mi>D</mi><mi>r</mi><mi>i</mi><mi>v</mi><mi>i</mi><mi>n</mi><mi>g</mi><mtext>  </mtext><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mn>0.6</mn><mo>×</mo><mn>1050</mn></mrow><mn>660</mn></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.95</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Performance &amp;= \frac{Target\;time\;per\;km \times Total\;km}{Driving\;time}\\
			&amp;=\frac{0.6 \times 1050}{660}\\
			&amp;\approx0.95
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6.0593em;vertical-align:-2.7797em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">man</span><span class="mord mathnormal">ce</span></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">D</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">660</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">0.6</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">1050</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.95</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span></span></span></span>
<p>We can also calculate the performance using the known OEE, availability and quality of our trip.</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>P</mi><mi>e</mi><mi>r</mi><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi><mi>a</mi><mi>n</mi><mi>c</mi><mi>e</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>O</mi><mi>E</mi><mi>E</mi></mrow><mrow><mi>A</mi><mi>v</mi><mi>a</mi><mi>i</mi><mi>l</mi><mi>a</mi><mi>b</mi><mi>i</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi><mo>×</mo><mi>Q</mi><mi>u</mi><mi>a</mi><mi>l</mi><mi>i</mi><mi>t</mi><mi>y</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mn>0.77</mn><mrow><mn>0.85</mn><mo>×</mo><mn>0.95</mn></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.95</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
Performance &amp;=\frac{OEE}{Availability \times Quality}\\
			&amp;=\frac{0.77}{0.85\times0.95} \\
			&amp;\approx 0.95
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6.1315em;vertical-align:-2.8158em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.3158em"><span style="top:-5.3158em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">man</span><span class="mord mathnormal">ce</span></span></span><span style="top:-2.8139em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"></span></span><span style="top:-0.9046em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.8158em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.3158em"><span style="top:-5.3158em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3603em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">ai</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">abi</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal">Q</span><span class="mord mathnormal">u</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0359em">y</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">O</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.8139em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">0.85</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">0.95</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">0.77</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9046em"><span class="pstrut" style="height:3.3603em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.95</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.8158em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.3158em"><span style="top:-5.3158em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span><span style="top:-2.8139em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span><span style="top:-0.9046em"><span class="pstrut" style="height:3.3603em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.8158em"><span></span></span></span></span></span></span></span></span>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-could-we-improve-our-trip">How could we improve our trip?<a href="https://nyejon.com/blog/oee-introduction#how-could-we-improve-our-trip" class="hash-link" aria-label="Direct link to How could we improve our trip?" title="Direct link to How could we improve our trip?" translate="no">​</a></h3>
<p>Now that we know where our losses are, we can focus on how to improve our trip and reach our destination faster next time. There are some things that we wouldn't change (It is a road trip, after all).</p>
<p>What would you focus on improving first? As a reminder, our OEE is:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right" columnspacing=""><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>O</mi><mi>E</mi><mi>E</mi><mo>=</mo><mi>A</mi><mo>×</mo><mi>P</mi><mo>×</mo><mi>Q</mi><mo>≈</mo><mn>0.77</mn><mo>≈</mo><mn>0.85</mn><mo>×</mo><mn>0.95</mn><mo>×</mo><mn>0.95</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
OEE =A \times P \times Q  \approx 0.77 \approx 0.85 \times 0.95 \times 0.95
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2em;vertical-align:-0.35em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.85em"><span style="top:-3.01em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">O</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">P</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.77</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.85</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">0.95</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">0.95</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.35em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.85em"><span style="top:-2.85em"><span class="pstrut" style="height:2.84em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.35em"><span></span></span></span></span></span></span></span></span>
<p>It is quite clear that the availability is the main reason why our trip took longer. How could we improve this?</p>
<p>Well, it turns out we didn't start our trip with a full charge, so we spent more time charging than we needed. We also didn't do the required maintenance like checking tyre pressure before the trip, so when we hit a pothole, the tyre burst. If we did the required checks before going on our trip, we would have saved 30 minutes because of the tyre change and at least 20 minutes from one less charge. A saving of over 50 minutes.</p>
<p>This would bring our OEE up to:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.25em" columnalign="right left" columnspacing="0em"><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>O</mi><mi>E</mi><mi>E</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mi>G</mi><mi>o</mi><mi>o</mi><mi>d</mi><mtext>  </mtext><mi>k</mi><mi>m</mi><mo>×</mo><mi>T</mi><mi>a</mi><mi>r</mi><mi>g</mi><mi>e</mi><mi>t</mi><mtext>  </mtext><mi>t</mi><mi>i</mi><mi>m</mi><mi>e</mi><mtext>  </mtext><mi>p</mi><mi>e</mi><mi>r</mi><mtext>  </mtext><mi>k</mi><mi>m</mi></mrow><mrow><mi>T</mi><mi>r</mi><mi>i</mi><mi>p</mi><mtext>  </mtext><mi>l</mi><mi>e</mi><mi>n</mi><mi>g</mi><mi>t</mi><mi>h</mi></mrow></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mn>1000</mn><mo>×</mo><mn>0.6</mn></mrow><mn>730</mn></mfrac></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr><mtr><mtd class="mtr-glue"></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≈</mo><mn>0.82</mn></mrow></mstyle></mtd><mtd class="mtr-glue"></mtd><mtd class="mml-eqn-num"></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
OEE &amp;= \frac{Good\;km \times Target\;time\;per\;km}{Trip\;length} \\
	&amp;= \frac{1000 \times 0.6}{730}\\
	&amp;\approx 0.82
\end{align}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:6.0593em;vertical-align:-2.7797em"></span><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0278em">O</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3714em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">G</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord mathnormal" style="margin-right:0.1389em">T</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">im</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord mathnormal" style="margin-right:0.0315em">k</span><span class="mord mathnormal">m</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3214em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">730</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">1000</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em"></span><span class="mord">0.6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2778em"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2778em"></span><span class="mord">0.82</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span></span></span><span class="tag"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.2797em"><span style="top:-5.2797em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-2.7778em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span><span style="top:-0.9518em"><span class="pstrut" style="height:3.3714em"></span><span class="eqn-num"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.7797em"><span></span></span></span></span></span></span></span></span>
<p>A nice 5% improvement.</p>
<p>Because this is a road trip, we don't really want to spend less time enjoying the view but would rather try to increase our performance some other way.</p>
<p>How could we do this? Well, you might point out that we could improve our performance by driving faster - over the speed limit 😱. This might work for a short time, but the police are waiting for you and end up pulling you over. This creates an unscheduled stop in your trip and the police take 30 minutes to write you your ticket. Costing you both money and time.</p>
<p>Some things like traffic, and road works are unavoidable, but we might be able to leave at a different time or plan better which means we can drive for longer at the speed limit.</p>
<p>Lastly, we could improve our quality. Here we could have saved distance by planning better again. We could make sure we know our route beforehand, and perform checks more often before we drive too far in the wrong direction.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://nyejon.com/blog/oee-introduction#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>We have learnt how to use OEE using a practical example and now have an intuitive understanding of how we can use it to improve our production processes.</p>
<p>Go ahead and use these concepts to calculate OEE for your process, business, or even your cooking.
The concept of OEE can be applied to many industries, and could help numerous businesses improve their efficiencies.</p>
<ul>
<li class="">How well do we utilise our kitchen (Restaurant)</li>
<li class="">How many seat minutes are filled (Airlines, movie theaters)</li>
<li class="">Utilization of your server (Software companies)</li>
</ul>
<p>Feel free to leave any comments, and I look forward to discussions on how you applied OEE to make your business (or your cooking…) more efficient.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Manufacturing" term="Manufacturing"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Managers]]></title>
        <id>https://nyejon.com/blog/managers</id>
        <link href="https://nyejon.com/blog/managers"/>
        <updated>2023-11-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Some thoughts after observing management styles and peoples reactions to them.]]></summary>
        <content type="html"><![CDATA[<p>Good managers are hard to come by.
There are many things that make a great manager, and very few have all of these qualities.
See my post <a class="" href="https://nyejon.com/blog/types-of-leaders">types of leaders</a> for more on the qualities one can learn to become a good leader.</p>
<!-- -->
<p>I'm in a technical role with some direct reports and like having a manager that knows at least something about the process that their team is working on.
They do not need to know every detail, but they should know how to ask the right questions.
Knowing which questions to ask, usually results from having some experience in the role.
It is a painful experience watching someone try to manage a team without this quality.</p>
<p>Ideally, you want to be able to learn something from your manager.
Their experience should be yours for the taking. You should be able to learn new ways of thinking, dealing with people and approaching problems with incomplete information.</p>
<p>A manager should build a working environment encouraging people to move if needed for personal growth, but do things for their team to make sure they don't want to move.
This could involve supporting their employee's personal ambitions within the company, providing a budget for education and learning, or encouraging collaboration with other teams that the employee strives to be a part of.</p>
<p>Everyone typically wants the best for themselves.
Ambitious people want to perform exceptionally on what they are working on.
Managers should foster an environment that allows people to discuss things openly, without worrying if there could be negative consequences.
Feelings of fear and personal consequences results in people not speaking up when they should.
There should be a focus on the solution without fear of consequence for the person that raises it.</p>
<p>A manager should encourage people and show appreciation when they do a good job.
They should avoid constant negative feedback when someone's giving their all but still struggling on something difficult.
Bringing the person down might push them to solve the immediate problem, but it will result in resentment and hate.</p>
<p>Negative people should be removed from the team.
A manager should identify these people that are a bad influence on those around them, and remove them if they manage to slip into the team.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Leadership" term="Leadership"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Free custom domain email]]></title>
        <id>https://nyejon.com/blog/free-custom-domain-email</id>
        <link href="https://nyejon.com/blog/free-custom-domain-email"/>
        <updated>2022-09-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A simple guide for sending and receiving email on a custom domain without monthly costs.]]></summary>
        <content type="html"><![CDATA[<p>I've always wanted to have my own domain and be able to send and receive emails using it.
What I don't like are monthly subscriptions.</p>
<p>This guide explains how I managed to set up a custom domain with my existing Gmail inbox, all without a monthly cost.
The only cost is a domain if you don't already have one.</p>
<p>The goals:</p>
<ul>
<li class="">use your existing inbox with a custom domain,</li>
<li class="">send and receive emails with the custom domain,</li>
<li class="">be completely free (besides for the domain cost)</li>
</ul>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="things-you-need">Things you need<a href="https://nyejon.com/blog/free-custom-domain-email#things-you-need" class="hash-link" aria-label="Direct link to Things you need" title="Direct link to Things you need" translate="no">​</a></h2>
<ul>
<li class="">An existing email account, I use Gmail.</li>
<li class="">A <a href="https://www.cloudflare.com/" target="_blank" rel="noopener noreferrer" class="">Cloudflare account</a>.</li>
<li class="">A domain name using Cloudflare as your name server and DNS. Transfer your domain to them or buy one using the <a href="https://www.cloudflare.com/products/registrar/" target="_blank" rel="noopener noreferrer" class="">Cloudflare registrar</a>.</li>
<li class="">An email SMTP server such as <a href="https://www.brevo.com/" target="_blank" rel="noopener noreferrer" class="">Brevo</a>, <a href="https://sendgrid.com/" target="_blank" rel="noopener noreferrer" class="">SendGrid</a> or another of your choice. These allow you to send between 100 and 300 emails a day for free which should be fine for personal purposes.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="enable-email-forwarding">Enable email forwarding<a href="https://nyejon.com/blog/free-custom-domain-email#enable-email-forwarding" class="hash-link" aria-label="Direct link to Enable email forwarding" title="Direct link to Enable email forwarding" translate="no">​</a></h2>
<p>The first step once you have your domain registered is to enable email forwarding.
Do this within the Cloudflare admin page for your domain.
After setting email forwarding up, email sent to a <a href="mailto:youremail@yourdomain.com" target="_blank" rel="noopener noreferrer" class="">youremail@yourdomain.com</a> is forwarded to another email address of your choice.
You can also configure a 'catch all' address so that any emails sent to your domain will be forwarded to a specific inbox.</p>
<ul>
<li class="">Go to <em>Email</em> on the left menu bar.</li>
<li class="">Enable email forwarding for your domain.</li>
<li class="">Add the email DNS settings required by Cloudflare. This can be done automatically.</li>
<li class="">Add a destination address, and verify it.</li>
<li class="">You can either use a catch-all which forwards every email sent to your domain, or only forward specific email addresses.</li>
</ul>
<p>In the end, you should have something that looks similar to this:</p>
<p><img decoding="async" loading="lazy" alt="cloudflare-email-routing.png" src="https://nyejon.com/assets/images/cloudflare-email-routing-7d4e2e5a768569898c662e3e35a04944.png" width="2220" height="1944" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="enable-email-sending">Enable email sending<a href="https://nyejon.com/blog/free-custom-domain-email#enable-email-sending" class="hash-link" aria-label="Direct link to Enable email sending" title="Direct link to Enable email sending" translate="no">​</a></h2>
<p>Now that you can receive emails on your domain, it's time to enable sending email.</p>
<p>This part will be done within your SMTP provider and Gmail (or another email provider of your choice). What we want to achieve is being able to send emails, and maximise the probability of them being delivered to the expected recipient.</p>
<p>You need to have decided on a service that allows you to send emails. As previously mentioned, I use <a href="https://www.brevo.com/" target="_blank" rel="noopener noreferrer" class="">Brevo</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="smtp-service-setup">SMTP service setup<a href="https://nyejon.com/blog/free-custom-domain-email#smtp-service-setup" class="hash-link" aria-label="Direct link to SMTP service setup" title="Direct link to SMTP service setup" translate="no">​</a></h3>
<p>The first step is to set up the SMTP service to allow it to send emails on your behalf. On Brevo, the steps required look something like this:</p>
<ul>
<li class="">Authorize/validate your domain under <em>Senders and IPs</em> by adding all the records from the email sender to your Cloudflare DNS page.</li>
<li class="">Configure SPF, DMARC and DKIM</li>
</ul>
<p>Brevo will automatically setup DMARC and DKIM, but you may need to manually set up SPF and adjust the strictness of the email delivery.</p>
<p>Ultimately we want our DMARC management page in Cloudflare to look something like this:</p>
<p><img decoding="async" loading="lazy" alt="cloudflare-email-records.png" src="https://nyejon.com/assets/images/cloudflare-email-records-a4d0a28c3af78f09298646acf654862b.png" width="1307" height="205" class="img_ev3q"></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="spf">SPF<a href="https://nyejon.com/blog/free-custom-domain-email#spf" class="hash-link" aria-label="Direct link to SPF" title="Direct link to SPF" translate="no">​</a></h4>
<p>The Sender Policy Framework (or SPF) allows you to specify all IP addresses and hostnames that are permitted to send email on behalf of your domain. If you don't configure SPF on your domain your email may be blocked or marked as spam by email receivers.</p>
<p>For this to work, we need to add both Cloudflare and Brevo to the SPF record:</p>
<p>"v=spf1 include:_spf.mx.cloudflare.net include<!-- -->:spf<!-- -->.brevo.com mx -all"</p>
<p>This new SPF record now replaces the old record. It allows both Cloudflare and Brevo to send emails using your domain name, while all other senders are blocked using <code>-all</code>.</p>
<p>The options for controlling the strictness of the SPF record include:</p>
<ul>
<li class=""><code>+all</code> - will allow all emails to be received even if not sent by a trusted sender.</li>
<li class=""><code>~all</code> - will soft fail, so emails will be marked as spam if a trusted sender does not send them.</li>
<li class=""><code>-all</code> - will reject all emails not sent by a trusted sender.</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="dmarc">DMARC<a href="https://nyejon.com/blog/free-custom-domain-email#dmarc" class="hash-link" aria-label="Direct link to DMARC" title="Direct link to DMARC" translate="no">​</a></h4>
<p>Domain-based Message Authentication Reporting and Conformance (or DMARC) tells an email receiver how to treat incoming emails from your domain that fail email security checks. You can also specify a reporting email address to receive regular reports about outgoing emails on your domain.</p>
<p>We want to specify that we want to reject all email that fails the DMARC authentication checks.</p>
<p>Create a TXT record in the DNS of your domain with the following value replacing the <code>rua: mailto</code> with the settings for your domain:</p>
<p>Record type: TXT
Name: <code>_dmarc</code>
Value: <code>"v=DMARC1;  p=reject; rua=mailto:&lt;somehash&gt;@dmarc-reports.cloudflare.net,mailto:rua@dmarc.brevo.com"</code></p>
<p>The <code>p=reject</code> means that emails will be dropped if they do not include the DKIM and SPF as configured for your domain.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="dkim">DKIM<a href="https://nyejon.com/blog/free-custom-domain-email#dkim" class="hash-link" aria-label="Direct link to DKIM" title="Direct link to DKIM" translate="no">​</a></h4>
<p>DomainKeys Identified Mail (or <a href="http://dkim.org/" target="_blank" rel="noopener noreferrer" class="">DKIM</a>) adds a public key to your DNS for email receivers to verify your outgoing signed email.</p>
<p>Brevo and Cloudflare will automatically create this.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="gmail-setup">Gmail setup<a href="https://nyejon.com/blog/free-custom-domain-email#gmail-setup" class="hash-link" aria-label="Direct link to Gmail setup" title="Direct link to Gmail setup" translate="no">​</a></h3>
<p>Now, it's finally time to configure your Gmail inbox to be able to send and receive your emails from your domain account.</p>
<ul>
<li class="">Open Gmail settings and go to the <em>Accounts and Import</em> page.</li>
<li class="">Click <em>Add another email address</em>.</li>
<li class="">In the popup window, leave <em>treat as Alias</em> enabled and enter your custom email address that you wish to send from.</li>
<li class="">In the SMTP page, fill in the SMTP settings from the SMTP provider you set up earlier.</li>
<li class="">Validate the email address. This allows you to test that everything is working.</li>
<li class="">Optional: Set this as your default email address in Gmail.</li>
</ul>
<p>You can send and receive from as many email addresses as you like on your own domain.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prevent-your-custom-domain-email-from-being-detected-as-spam">Prevent your custom domain email from being detected as spam<a href="https://nyejon.com/blog/free-custom-domain-email#prevent-your-custom-domain-email-from-being-detected-as-spam" class="hash-link" aria-label="Direct link to Prevent your custom domain email from being detected as spam" title="Direct link to Prevent your custom domain email from being detected as spam" translate="no">​</a></h2>
<p>If you followed the instructions above, most of these steps should already be completed.
In case you are having trouble, double-check that all these records exist:</p>
<ul>
<li class="">Have an MX record for your domain, so you're able to accept responses.</li>
<li class="">Check the SPF, DMARC and DKIM record&nbsp;for your domain.</li>
<li class="">Check to see if your sending IP address is&nbsp;on any blacklists. Get it off if you can.</li>
</ul>
<p>Custom domains are often flagged by the spam filters on many email services so it might take a bit of time for your domain to become trusted if you recently registered it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://nyejon.com/blog/free-custom-domain-email#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Congrats, you should be able to send and receive your email on your custom domain. Completely for free!</p>
<p>Thanks for reading, and let me know if you encountered any issues.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Software Development" term="Software Development"/>
        <category label="Self-Hosting" term="Self-Hosting"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Remotely access self-hosted services]]></title>
        <id>https://nyejon.com/blog/remotely-access-self-hosted-services</id>
        <link href="https://nyejon.com/blog/remotely-access-self-hosted-services"/>
        <updated>2022-02-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Cloudflare Tunnel provides a reliable way to create a tunnel between your self-hosted service and Cloudflare. It is much easier to set up a self-hosted service with a domain, without worrying about port forwarding or dynamic DNS.]]></summary>
        <content type="html"><![CDATA[<p>I recently wanted to access a service on my local computer remotely.
The problem was that I generally use a VPN, which means there is no straightforward way to set up port forwarding (at least with my provider).</p>
<!-- -->
<p>I had successfully set up port forwarding, dynamic DNS and had a domain for the service without the VPN. I just couldn't figure out how to get it to work with the VPN. I had accepted that sometimes I wouldn't be able to access the service remotely.</p>
<p>I use Cloudflare as my DNS, and use their pages service to host this site. After browsing through their numerous services, they offer, I stumbled across <em>Cloudflare Tunnel.</em></p>
<blockquote>
<p>Cloudflare Tunnel</p>
<p>Cloudflare Tunnel exposes applications running on your local web server on any network with an internet connection without manually adding DNS records or configuring a firewall or router.</p>
</blockquote>
<p>Bingo! Exactly what was needed.</p>
<p>I followed <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/" target="_blank" rel="noopener noreferrer" class="">Cloudflare Tunnel · Cloudflare Zero Trust docs</a> and within 30 minutes the service was accessible, with and without the VPN.</p>
<p>Now I have my service accessible at a fixed URL, reliably and without having to mess around with my router and Dynamic DNS.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Self-Hosting" term="Self-Hosting"/>
        <category label="Software Development" term="Software Development"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Types of leaders]]></title>
        <id>https://nyejon.com/blog/types-of-leaders</id>
        <link href="https://nyejon.com/blog/types-of-leaders"/>
        <updated>2022-01-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Leaders come in different forms and have many developed traits. This post discusses some of the different leadership styles and a self reflection of which style represents me best.]]></summary>
        <content type="html"><![CDATA[<p>Leaders come in many forms and have different beliefs, values, and cultures.
This post breaks down some of the high-level differences among leaders and highlights what one should be aware of in a leadership role.</p>
<!-- -->
<p>It is based on the Coursera course: <a href="https://www.coursera.org/learn/leadership-collaboration" target="_blank" rel="noopener noreferrer" title="https://www.coursera.org/learn/leadership-collaboration" class="">https://www.coursera.org/learn/leadership-collaboration</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="leadership-development">Leadership development<a href="https://nyejon.com/blog/types-of-leaders#leadership-development" class="hash-link" aria-label="Direct link to Leadership development" title="Direct link to Leadership development" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="nature-versus-nurture">Nature versus nurture<a href="https://nyejon.com/blog/types-of-leaders#nature-versus-nurture" class="hash-link" aria-label="Direct link to Nature versus nurture" title="Direct link to Nature versus nurture" translate="no">​</a></h3>
<p>Are leaders made or born?</p>
<p>There are two dominant theories of leadership: entity theory, also known as trait theory and incremental theory.</p>
<p>Entity theory argues that leadership is a trait, that one is born with.
Incremental theory argues that one can learn to be a leader.
I personally subscribe to the incremental theory of leadership.
One can be born with certain traits that make one more naturally inclined to become a leader, but leadership skills can be grown and developed through hard work.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="mindset-and-growth">Mindset and growth<a href="https://nyejon.com/blog/types-of-leaders#mindset-and-growth" class="hash-link" aria-label="Direct link to Mindset and growth" title="Direct link to Mindset and growth" translate="no">​</a></h3>
<p>Do you have a growth or fixed mindset?
Do you believe that you can change who you are and improve your skills with work and practice or do you believe that you are who you are and anything you are good or bad at must stay that way?
That is the difference between a fixed and growth mindset.</p>
<p>Growth mindsets are much more successful long term and should be nurtured in yourself and others.
People with fixed mindsets don't like trying new things because the risk of failure implies that they aren't good enough.
In contrast, people who have a growth mindset, see themselves and others as having potential.
New things present an opportunity to learn and grow.</p>
<p>Have a growth mindset!</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="leadership-styles">Leadership styles<a href="https://nyejon.com/blog/types-of-leaders#leadership-styles" class="hash-link" aria-label="Direct link to Leadership styles" title="Direct link to Leadership styles" translate="no">​</a></h3>
<p>There are two main theories of leadership styles.
Theory X leadership and Theory Y leadership.</p>
<p>Theory X leadership is mostly transactional.
You do something and I'll give you a reward at the end, like a carrot dangling in front of a rabbit.</p>
<p>Theory Y leadership is based upon the idea that people want to contribute and do excellent work.</p>
<p>In my view, one needs to combine these leadership styles. People should be sufficiently rewarded monetarily, especially when they are contributing significantly to your own or the company's profits. However, the reward should not be the thing that motivates them to work for you. The reward should be a by-product of the intrinsic motivation to do something useful and meaningful.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="motivation-emotion-and-cognition">Motivation, emotion, and cognition<a href="https://nyejon.com/blog/types-of-leaders#motivation-emotion-and-cognition" class="hash-link" aria-label="Direct link to Motivation, emotion, and cognition" title="Direct link to Motivation, emotion, and cognition" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="intrinsic-and-extrinsic-motivation">Intrinsic and extrinsic motivation<a href="https://nyejon.com/blog/types-of-leaders#intrinsic-and-extrinsic-motivation" class="hash-link" aria-label="Direct link to Intrinsic and extrinsic motivation" title="Direct link to Intrinsic and extrinsic motivation" translate="no">​</a></h3>
<p>Are you intrinsically or extrinsically motivated? What about your colleagues?</p>
<p>Often people believe that they themselves are intrinsically motivated and believe that others are extrinsically motivated. This obviously makes no sense, as why would most people believe that others are motivated by money, while themselves having some other internal motivation for what they do.</p>
<p>It is important to nurture and develop the intrinsic motivation in your colleagues and subordinates. You will get far better work from them.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="happiness">Happiness<a href="https://nyejon.com/blog/types-of-leaders#happiness" class="hash-link" aria-label="Direct link to Happiness" title="Direct link to Happiness" translate="no">​</a></h3>
<p>You are either a happy person or not, right? Well, not exactly. According to some rough estimates about 50% of your happiness comes from your genetics, 40% from your intentional activities and 10% from material wealth.</p>
<p>You could take a few views from this:</p>
<ol>
<li class="">If you are born an unhappy person that you are cursed for life.</li>
<li class="">If you consciously work on some practices, you can make yourself happy.</li>
<li class="">Without the other things, money can't buy you happiness, but it can certainly help.</li>
</ol>
<p>Let's focus on the 40%. Few people are born with no intrinsic reason to be happy and if the 40% of intentional activity can be controlled, there is a good chance of being happy overall. Focus on behaviours and practices that we do voluntarily such as helping others, adopting a positive view, exercise and have goals you can work towards.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="decision-making">Decision making<a href="https://nyejon.com/blog/types-of-leaders#decision-making" class="hash-link" aria-label="Direct link to Decision making" title="Direct link to Decision making" translate="no">​</a></h3>
<p>Most people believe that they are good decision makers. They are overconfident in their decision-making prowess. This leads to bias in the decision-making process. Let's discuss a few of these biases and how to overcome them.</p>
<ol>
<li class=""><em>The framing effect</em> - The tendency for us to be risk-adverse regarding positive outcomes and risk taking regarding negative outcomes.</li>
<li class=""><em>Confirmation bias</em> - The tendency to actively seek out information that confirms your pre-existing viewpoint.</li>
<li class=""><em>Decision fatigue</em> - Making too many decisions, including insignificant decisions causes us to make poorer decisions when it really matters.</li>
<li class=""><em>Team scaling fallacy</em> - That by adding members to your team, you can solve the problem with linearly increasing efficiency.</li>
<li class=""><em>Common information effect</em> - The tendency for people in team to talk about the things that they all know, and not the things that they individually know which would add value.</li>
</ol>
<p>Wherever you are working, it is important to be aware of these biases and work together to not fall prey to their effects.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="people-skills">People skills<a href="https://nyejon.com/blog/types-of-leaders#people-skills" class="hash-link" aria-label="Direct link to People skills" title="Direct link to People skills" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="emotional-intelligence">Emotional intelligence<a href="https://nyejon.com/blog/types-of-leaders#emotional-intelligence" class="hash-link" aria-label="Direct link to Emotional intelligence" title="Direct link to Emotional intelligence" translate="no">​</a></h3>
<p>Think of your best boss. What characteristics stand out?</p>
<p>The things that stand out are likely not that they are intelligent, or that they had excellent grades at school. You probably thought about their people skills. Leaders are judged, not only on how clever they are, but also how they handle themselves and other people.</p>
<p>The skill related to understanding yourself, and others is known as emotional intelligence.</p>
<p>What are the implications for leadership? Emotional intelligence starts with self-awareness. People who are high in self-awareness are more empathic. You can improve your ability to self-regulate with rehearsal and practice and being more self-aware allows you to have more understanding for others.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="organisational-intelligence">Organisational intelligence<a href="https://nyejon.com/blog/types-of-leaders#organisational-intelligence" class="hash-link" aria-label="Direct link to Organisational intelligence" title="Direct link to Organisational intelligence" translate="no">​</a></h3>
<p>People who span organisational divides and integrate knowledge and best practices around the organisation are much more useful than people that work in silos.</p>
<p>They connect people and ideas.</p>
<p>You want to have a network that is large and spans many areas of knowledge within your company to maximise value. This is known as organisational intelligence. Good leaders encourage this interconnected behaviour and themselves have good relationships across the organisation.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="cultural-intelligence">Cultural intelligence<a href="https://nyejon.com/blog/types-of-leaders#cultural-intelligence" class="hash-link" aria-label="Direct link to Cultural intelligence" title="Direct link to Cultural intelligence" translate="no">​</a></h3>
<p>Cultural intelligence is a person's capability to adapt effectively to new cultural contexts.</p>
<p>The risk of talking about culture is that we may falsely stereotype people. A stereotype is a faulty belief that everyone from a given group or given culture is the same.</p>
<p>In general cultures across the globe can be defined into three main groups: <em>face, honour, and dignity</em>. It is important to be aware of other people's cultures and identify the overarching traits of theirs.</p>
<p><em>Face cultures</em> are primarily East Asia. People from face cultures derive their self-worth from earning the respect of others.</p>
<p><em>Dignity cultures</em> are primarily Europe North America, Australia, and New Zealand. People who embody the dignity culture believe strongly in speaking their mind and being self-reliant.</p>
<p><em>Honour cultures</em> are primarily in the Middle East, South Asia, North Africa, and Latin America. Self-worth in honour cultures is socially claimed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-multiple-intelligences-test">The multiple intelligences test<a href="https://nyejon.com/blog/types-of-leaders#the-multiple-intelligences-test" class="hash-link" aria-label="Direct link to The multiple intelligences test" title="Direct link to The multiple intelligences test" translate="no">​</a></h2>
<p>Howard Gardner's theory of multiple intelligences challenges the traditional view that intelligence is a unitary capacity. Gardner proposes that there are at least eight intelligences that can be identified, and they influence how we learn, think, and interact.</p>
<p>Your leadership style is influenced by your own multiple intelligences. Gaining self-awareness of your own multiple intelligences can help you motivate and influence others more effectively.</p>
<p>You can do the <a href="https://www.idrlabs.com/multiple-intelligences/test.php" target="_blank" rel="noopener noreferrer" title="Multiple Intelligences Test" class="">Multiple Intelligence Survey</a> yourself and read more about the <a href="https://www.multipleintelligencesoasis.org/the-components-of-mi" target="_blank" rel="noopener noreferrer" class="">The Components of Multiple Intelligences</a>.</p>
<p>Here are my results.</p>
<p><img decoding="async" loading="lazy" alt="multiple-intelligences.png" src="https://nyejon.com/assets/images/multiple-intelligences-f804c5dc42927e1d7ef4e4ccf7da3c20.png" width="635" height="470" class="img_ev3q"></p>
<p>The results show that my top three intelligences are logical-mathematical, bodily-kinaesthetic, and intra-personal. My weaknesses are linguistic and naturalistic.</p>
<p>It comes as no surprise that my top intelligence is logical-mathematical because of my role as a data scientist and engineer. In these roles it is critical to be able to formulate logical thoughts and understand complicated problems.</p>
<p>The next intelligence is the bodily-kinaesthetic. This is a strength for me as I have always participated in a variety of sports and been active. Learning new skills that require co-ordination and body-awareness come relatively easily.</p>
<p>The third intelligence is intra-personal. This involves self-reflection and an ability to learn from one's mistakes. I often review my actions and thoughts after events and figure out how different situations could be handled better in the future.</p>
<p>Getting to the weaknesses, by far my weakest area is linguistic intelligence. Writing, speaking, and learning languages doesn't come naturally to me. This requires work, and currently I am learning German. Based upon these results, I should invest more time writing, and working with language as effective communication is essential when working with others. One of the ways I intend to work on this intelligence is by writing for my blog. Over time, writing should become easier and more fun.</p>
<p>The next intelligence that I want to work on is my naturalistic intelligence. I enjoy being in nature, and spending time outdoors. I however don't learn much about various plants and animals and often just ignore any information that comes my way. To improve this, I should pay more attention to the details and try to learn and remember information to do with nature.</p>
<p>Working on these two intelligences will help my professional career, by improving communication and information sharing. They will help me become more aware of my surroundings and notice intricate details around me.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://nyejon.com/blog/types-of-leaders#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>If you made it this far, thanks for reading! I learnt a lot writing this post and found out where my strengths and weaknesses lie. Try out the exercise for yourself and come up with a plan to work on your own weaknesses and leverage your strengths in whatever environment you are currently working.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Leadership" term="Leadership"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Git template repositories]]></title>
        <id>https://nyejon.com/blog/git-template-projects</id>
        <link href="https://nyejon.com/blog/git-template-projects"/>
        <updated>2021-12-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Template repositories are one of my favourite ways to speed up and standardize your development workflow. They help both individual and team workflows.]]></summary>
        <content type="html"><![CDATA[<p>Repository templates are a quick way to bootstrap a repository for a new project and then keep it up to date with your best practices.</p>
<!-- -->
<p>A good template allows you to:</p>
<ul>
<li class="">update all subprojects easily</li>
<li class="">get to production quickly</li>
<li class="">have a consistent development environment</li>
</ul>
<p>Templates allow any improvements to be made in one place and then merged into all the projects that use the template as a base. They are vital when working in teams. Nobody likes repeating work many times over when you are working on multiple different projects at the same time.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="template-repositories">Template repositories<a href="https://nyejon.com/blog/git-template-projects#template-repositories" class="hash-link" aria-label="Direct link to Template repositories" title="Direct link to Template repositories" translate="no">​</a></h2>
<p>A template repository should include anything that fits into the standard project workflow that you use. You want to figure something out once, and document it's use by implementation in your template repository.</p>
<p>Things that you should include are:</p>
<ul>
<li class="">Readme</li>
<li class="">standard env files for your setup</li>
<li class="">development and production environment definitions</li>
<li class="">deployment files</li>
<li class="">CI/CD templates and scripts</li>
<li class="">standard secret name</li>
<li class="">formatting rules, pre-commit workflows</li>
</ul>
<p>This is not an exhaustive list. Include everything you would use repetitively.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-use-templates">How to use templates<a href="https://nyejon.com/blog/git-template-projects#how-to-use-templates" class="hash-link" aria-label="Direct link to How to use templates" title="Direct link to How to use templates" translate="no">​</a></h2>
<p>You have two choices when deciding to use templates.</p>
<p>The first, is creating a new repository from a template, without including the git history. This is effectively a snapshot at the point in time of your template repository. Any changes you make to the template repository will need to be manually merged into all the projects that use it.</p>
<p>The second, and the method which I prefer, is to add a template repository as a remote repository on an empty git-repo. The advantage is that you can pull any changes from your template repository into your projects that derive from it.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-one-create-a-repository">Step one: create a repository<a href="https://nyejon.com/blog/git-template-projects#step-one-create-a-repository" class="hash-link" aria-label="Direct link to Step one: create a repository" title="Direct link to Step one: create a repository" translate="no">​</a></h3>
<p>I like to standardise my project names when they are based upon a template.
For example, a project that is based on a template for a machine learning API could be named something like:</p>
<p><code>repository-name = project-name-ml-api</code></p>
<p>where <strong>project-name</strong> is the name of your project.</p>
<p>After deciding on a name, create the repository.
Clone this new repository to your local machine.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-two-add-the-template-repository-as-a-remote">Step two: add the template repository as a remote<a href="https://nyejon.com/blog/git-template-projects#step-two-add-the-template-repository-as-a-remote" class="hash-link" aria-label="Direct link to Step two: add the template repository as a remote" title="Direct link to Step two: add the template repository as a remote" translate="no">​</a></h3>
<p>Follow the following steps to setup the new repository with your template repository. It will be configured as a remote where it is only possible to pull from.</p>
<p>Initially only the new repository origin will be a remote.
You can check this by running the following command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">$ git remote -v</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">origin git@github.com:organisation/project-name-ml-api.git (fetch)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">origin git@github.com:organisation/project-name-ml-api.git (push)</span><br></div></code></pre></div></div>
<p>We will now add the template as a remote:</p>
<p><code>git remote add upstream git@github.com:organisation/template-ml-api.git</code></p>
<p>Then we want to ensure you cannot push to this remote:</p>
<p><code>git remote set-url --push upstream no_push</code></p>
<p>After executing the above commands, you should see the following output:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">$ git remote -v</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">origin git@github.com:organisation&gt;/project-name-ml-api.git (fetch)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">origin git@github.com:organisation&gt;/project-name-ml-api.git (push)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">upstream        git@github.com:organisation/template-ml-api.git (fetch)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">upstream        no_push (push)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-three-start-your-project-with-the-template">Step three: start your project with the template<a href="https://nyejon.com/blog/git-template-projects#step-three-start-your-project-with-the-template" class="hash-link" aria-label="Direct link to Step three: start your project with the template" title="Direct link to Step three: start your project with the template" translate="no">​</a></h3>
<p>Pull from the template repository and allow you to merge any changes that occurred in the base repository by running the following command:</p>
<p><code>git pull upstream master</code></p>
<p>Commit any changes and push back to your newly created repository.
Congratulations, you have now created a new repository based on a template.</p>
<p>It should be possible to run <code>git pull upstream master</code> to merge any changes in the template into your project in the future.</p>
<p>You will need to update any files that need to be customised to your newly created project. This includes things like project naming, URLS, naming in Kubernetes files and environment variables etc.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://nyejon.com/blog/git-template-projects#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Template repositories are a good starting point for new projects. They help to speed up your development workflow and enable much faster development rates and efficiencies. You should also have a good understanding about what to put into a template repository. Happy templating!</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Software Development" term="Software Development"/>
        <category label="Teams" term="Teams"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Health and fitness]]></title>
        <id>https://nyejon.com/blog/health-and-fitness</id>
        <link href="https://nyejon.com/blog/health-and-fitness"/>
        <updated>2021-11-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[My 80/20 approach to balancing health and fitness with the rest of life's demands.]]></summary>
        <content type="html"><![CDATA[<p>This post is a summary about what works for me, what I have tried and what I have learned regarding health and fitness.</p>
<p>I intend to update this as I learn more and use it to increase my accountability. As the saying goes, <em>"We know that half of what we know about health is wrong, we just don't know which half."</em></p>
<!-- -->
<p>There are a few different aspects to health that one needs to monitor and optimise:</p>
<ul>
<li class="">Exercise and physical health</li>
<li class="">Mental emotional health</li>
<li class="">Nutrition</li>
<li class="">Sleep</li>
<li class="">Medications or supplements</li>
<li class="">Habits or productivity</li>
</ul>
<p>We need to make a distinction between <em>normal</em> and <em>optimal</em>. Often guidance will be given around normal ranges, but we don't want to aim to be normal. We should aim for optimal and target the top 5% for age and gender.</p>
<p>While I am not an athlete or health professional, I have absorbed significant amounts of health-related books and podcasts. The below points have stood out.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="nutrition">Nutrition<a href="https://nyejon.com/blog/health-and-fitness#nutrition" class="hash-link" aria-label="Direct link to Nutrition" title="Direct link to Nutrition" translate="no">​</a></h2>
<p>Diet and nutrition are frequently spoken about with a religious fervour. Ultimately, we don't know what the best diet is and never will.
We can do things to maximise our probability of living a long life given the information we have access to today.</p>
<p>I have tried keto, paleo, and intermittent fasting. Of all three, I felt the best eating keto and had what felt like unlimited energy, but found it unsustainable.</p>
<p>In the end, I have tended towards a mixed diet, focussing on eating good quality grass fed meat, vegetables, and fruits.
This combo ended up being the best mix for me, without being too strict about it.
I probably eat too much chocolate and assorted delicious baked goods provided by my wife. Chocolate brownies are definitely a weakness.
In general, aim to eat less, high quality food instead of copious amounts of low-quality junk.</p>
<p>Typically, I skip breakfast and have coffee with cream before eating a large meal around lunchtime.</p>
<p>I soak my vegetables in olive oil and generally try to avoid oils like sunflower, canola, or soybean.
Recently, I have noticed many products bragging to be "palm oil free". These products are often significantly less healthy.</p>
<p>The fats I limit myself to are:</p>
<ul>
<li class="">olive oil</li>
<li class="">butter</li>
<li class="">coconut oil</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="protein">Protein<a href="https://nyejon.com/blog/health-and-fitness#protein" class="hash-link" aria-label="Direct link to Protein" title="Direct link to Protein" translate="no">​</a></h3>
<p>The primary focus is on getting enough protein, averaged out over the week. The RDA of around 0.8 grams per kilogram of body weight is too low, and the target should be around 2 grams per kilogram. This is especially important to maintain muscle mass as one ages.</p>
<p>It's difficult to get enough protein through whole foods, so I often supplement with whey and in Germany we have some delicious protein puddings which provide around 20 grams of protein per tub.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="glucose-monitoring">Glucose monitoring<a href="https://nyejon.com/blog/health-and-fitness#glucose-monitoring" class="hash-link" aria-label="Direct link to Glucose monitoring" title="Direct link to Glucose monitoring" translate="no">​</a></h3>
<p><a href="https://peterattiamd.com/are-continuous-glucose-monitors-a-waste-of-time-for-people-without-diabetes/" target="_blank" rel="noopener noreferrer" class="">Glucose monitoring</a> for a short time can be incredibly useful to learn how your body reacts to food.</p>
<p>It was good to see how my body reacted to different foods after using a glucose monitor for a couple of weeks.</p>
<p>Blood glucose readings should have a low average of less than 90 mg/dL as well as a low standard deviation. Ideally your blood glucose should never exceed 140 mg/dL.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="alcohol">Alcohol<a href="https://nyejon.com/blog/health-and-fitness#alcohol" class="hash-link" aria-label="Direct link to Alcohol" title="Direct link to Alcohol" translate="no">​</a></h3>
<p>Alcohol is one of those things that one typically wants to drink less of. On the short term it affects sleep, reduces motivation, and interrupts your routines. Over the long term, the health effects are vast.</p>
<p>I use the app <a href="https://lessdrinks.com/" target="_blank" rel="noopener noreferrer" title="Less" class="">https://lessdrinks.com/</a> to track my alcohol consumption. It is surprisingly easy to forget how much alcohol one consumes, and this acts as a good reminder.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="exercise-and-physical-health">Exercise and physical health<a href="https://nyejon.com/blog/health-and-fitness#exercise-and-physical-health" class="hash-link" aria-label="Direct link to Exercise and physical health" title="Direct link to Exercise and physical health" translate="no">​</a></h2>
<p>I like exercise. Without it, life would be miserable.</p>
<p>Sometimes it is not easy, but one feels better after doing some. It builds the mental toughness required to take on other challenges throughout life.</p>
<p>One should be strong, be able to do things for a long time and</p>
<p>I'm not an athlete. I exercise so that I can do things in life without having to worry about whether I am capable of it. Exercise is training for life. It allows one to do fun things when the opportunity arises or get out of a tricky situation. If you have done it in training, you can do it when it matters.</p>
<p>The aspects to work on are endurance, strength, and flexibility. All need to be worked on simultaneously to optimise one's physical health. My choices are running and cycling for endurance, and <a href="https://thenx.com/" target="_blank" rel="noopener noreferrer" class="">callisthenics</a> and weight training for strength. Occasionally I fit in some yoga for flexibility, however this is definitely a pillar I need to work on.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="barefoot-shoes">Barefoot shoes<a href="https://nyejon.com/blog/health-and-fitness#barefoot-shoes" class="hash-link" aria-label="Direct link to Barefoot shoes" title="Direct link to Barefoot shoes" translate="no">​</a></h3>
<p>Foot and leg health is taken for granted. Most people walk around never knowing what it's like to feel the ground.</p>
<p>I have used barefoot shoes since 2012.
The transition took about a year before I could use them for all my activities.
Honestly, there is no going back to regular shoes once you switch.</p>
<p><em>Once you go barefoot, there is no going back. - Me</em></p>
<p>Barefoot shoes have eliminated the knee pain (and other issues) I used to develop while running.
After running a couple of marathons in them, I have only had pain in my muscles from being tired. Recovery is quick.</p>
<p>Other benefits that I have noticed include having naturally strong legs, improved balance and being able to w</p>
<p>One also develops a mental connection to the ground. You get so much more sensory input, that after a while you feel lost without this additional sense.</p>
<p>My favourite brand is Vivobarefoot, although I feel like their quality has started to deteriorate from their early days.</p>
<p>Here are three frequent questions I get about wearing barefoot shoes:</p>
<p><strong>Q. Aren't you slower while running? Professional athletes don't use barefoot shoes.</strong></p>
<p>A: I am slower, but I am not a professional athlete with naturally perfect running form. The benefits outweigh drawbacks. If I want to run a faster time, I should train harder. My running times can improve substantially before I need the minor speed increase of advanced running shoes. What is true for most people: <em>It's not the shoes that stop you from running a 2:10 marathon.</em> Maybe I'd look into racing in advanced running shoes while doing the majority of training in the barefoot shoes.</p>
<p><strong>Q. Won't you injure yourself? You can't run on the road with no padding.</strong></p>
<p>A. I have not injured myself once due to using barefoot shoes and running on the road. On the contrary, I used to injure myself all the time in normal shoes.</p>
<p>If you start slowly, and build up your muscle and tendon strength, your joints will be protected through better running form. Run for years without any injuries and recover faster from big events.</p>
<p><strong>Q. Don't the shoes make you look ridiculous?</strong></p>
<p>A. Another benefit is that you build the mental strength required to accept that you look ridiculous.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Health" term="Health"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Increasing renewables part one]]></title>
        <id>https://nyejon.com/blog/increasing-renewables-part-one</id>
        <link href="https://nyejon.com/blog/increasing-renewables-part-one"/>
        <updated>2021-11-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The world needs to transition to a renewable energy future to limit climate change. Part one of the series investigates the reasons for why we need to update the distribution network to handle more renewables.]]></summary>
        <content type="html"><![CDATA[<p>This is the first post in a multipart series that will investigate various ways to increase the amount of renewable energy on the distribution grid.</p>
<p>It is based on the work of my <a href="https://scholar.sun.ac.za/handle/10019.1/86605" target="_blank" rel="noopener noreferrer" class="">MSc thesis</a>.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://nyejon.com/blog/increasing-renewables-part-one#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>The introduction of renewable generation onto an electricity grid can have profound impact on its reliability, power quality and operation.
I come from a background in South Africa where a significant amount of renewables will be connected to the medium voltage (MV) distribution network.
A MV distribution network typically has voltages in the range of 11-33 kV.
Large plants will be connected to the high voltage (HV) network at 66 kV to 400 kV.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="third-world-problems">Third world problems<a href="https://nyejon.com/blog/increasing-renewables-part-one#third-world-problems" class="hash-link" aria-label="Direct link to Third world problems" title="Direct link to Third world problems" translate="no">​</a></h2>
<p>The power networks in countries such as South Africa, and other third world countries are significantly different to those in the first world.</p>
<p>The power networks can be characterised by:</p>
<ul>
<li class="">large distances between generation and load</li>
<li class="">voltage drop rather than current constraints</li>
<li class="">different load profiles</li>
</ul>
<p>Generally, the amount of renewables that can be installed on the MV networks are limited due to the long, weak MV distribution networks that service most of the areas that renewables can be installed.</p>
<p>Over the next few years most of the potential renewable sites, with a strong connection to the grid, will have been used.
Most of the open land and renewable resources lie where no existing infrastructure exists.
In many cases renewables will have to be connected to weak feeders far away from substations and load centres.
Costs rise dramatically if long dedicated power lines need to be built to access these resources.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="technical-limitations">Technical limitations<a href="https://nyejon.com/blog/increasing-renewables-part-one#technical-limitations" class="hash-link" aria-label="Direct link to Technical limitations" title="Direct link to Technical limitations" translate="no">​</a></h2>
<p>Most distribution systems are passively controlled, designed for one way power flow and control problems are solved during the network planning stage using simple load flow tools.
To connect the amount of renewables to the power network there are many technical challenges that must be overcome.</p>
<ul>
<li class="">Power quality: Voltage regulation, harmonic distortion, rapid voltage changes, flicker and voltage unbalance</li>
<li class="">Protection: Relay co-ordination, anti-islanding, relay blinding, DG protection from fault currents</li>
<li class="">Stability: Transient stability, long term dynamic stability and voltage collapse</li>
</ul>
<p>There are basic guidelines to determine if detailed studies need to be performed when connecting a power plant to the grid.
These guidelines can be summariezed by four main criteria:</p>
<ol>
<li class="">Voltage regulation or voltage rise</li>
<li class="">Rapid voltage changes</li>
<li class="">Thermal limits</li>
<li class="">Protection limits</li>
</ol>
<p>These criteria ensure that voltages and currents will never exceed the defined limits during worst case loading scenarios.
Protection issues are more of a concern when integrating synchronous and induction generators into the distribution network.
Fault current from generation, with power electronic converters, is limited to about double the rated power of the inverter.</p>
<p>The voltage rise, caused by a power plant, is dependent on the amount of power that the DG generates and the short circuit power level at it's point of connection.
The <a href="https://www.epri.com/" target="_blank" rel="noopener noreferrer" class="">EPRI</a> planning guideline, specifies a 1% voltage change limit for renewable generation and a 5% voltage change limit for fixed generation.</p>
<p>On feeders that have a large amount of connected generation, the voltage can be supported along the length of the feeder, depending on where the generators are placed.
There are various methods which will be discussed in subsequent posts, on how to regulate the voltage of the MV network when renewables have been installed.</p>
<p>Ultimately, I forsee the transformation of the distribution system from a passive network to an distributely controlled, intelligent network.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="objectives">Objectives<a href="https://nyejon.com/blog/increasing-renewables-part-one#objectives" class="hash-link" aria-label="Direct link to Objectives" title="Direct link to Objectives" translate="no">​</a></h2>
<p>This series will address some of the issues relating to the installation of renewable generation onto the grid, such as:</p>
<ol>
<li class="">Assess the impact of PV distributed generation on MV distribution feeders voltage and voltage control devices</li>
<li class="">Investigate various methods that can be used to increase penetration levels</li>
<li class="">Provide solutions to combine the various voltage control techniques to increase penetration levels further, without negatively impacting power quality</li>
</ol>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Energy" term="Energy"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Shantaram book review]]></title>
        <id>https://nyejon.com/blog/shantaram-book-review</id>
        <link href="https://nyejon.com/blog/shantaram-book-review"/>
        <updated>2021-11-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A review of the book Shantaram by Gregory David Roberts.]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="shantaram-book.jpg" src="https://nyejon.com/assets/images/shantaram-book-6845720e11a0da7092ec66636db42b69.jpg" width="1199" height="811" class="img_ev3q"></p>
<p>On a holiday in Turkey, I settled down to read the book <em>Shantaram</em> by Gregory David Roberts.</p>
<!-- -->
<p>The book is a work of fiction but is based loosely on the life of Gregory after his escape from an Australian prison.</p>
<p>The story starts with the main character "Lin", who is on the run, having just arrived in Mumbai (Bombay) in the 80's.
Lin ends up living a fascinating life and experiences the joys and hardships of Mumbai at the time.</p>
<p>In the book, it is hard to distinguish where the border lies between fiction and reality.
The descriptions within the book are incredibly detailed.
The story gets introduced in such a way and the character portrayals are so good, that one can mistake them as facts.
These detailed descriptions are most prevalent and appreciated in the first half of the book.
As the book progresses, they increasingly feel dragged out.
Towards the end, one wants to get to the point.</p>
<p>Overall, the book is a particularly enjoyable read. I recommend it but keep in mind, that it takes work to get through.</p>]]></content>
        <author>
            <name>Jonathan Nye</name>
            <email>contact@nyejon.com</email>
            <uri>https://nyejon.com/about</uri>
        </author>
        <category label="Book Review" term="Book Review"/>
    </entry>
</feed>