Skip to content

Commit 067f6fe

Browse files
committed
Added Conditional Gate logic (reduces the need for variables and virtual switches)
1 parent 5d24735 commit 067f6fe

7 files changed

Lines changed: 650 additions & 467 deletions

File tree

docs/docs/conditional-gates.html

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Conditional Gates - Smart (Components) Toolkit for Homey</title>
7+
<script src="https://cdn.tailwindcss.com"></script>
8+
<style>
9+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
10+
body {
11+
font-family: 'Inter', sans-serif;
12+
background-color: #f8fafc;
13+
color: #1a202c;
14+
}
15+
code {
16+
background: #f1f5f9;
17+
padding: 0.2rem 0.4rem;
18+
border-radius: 0.25rem;
19+
font-size: 0.9em;
20+
color: #1e293b;
21+
}
22+
pre {
23+
background: #f1f5f9;
24+
border: 1px solid #e2e8f0;
25+
padding: 1rem;
26+
border-radius: 0.5rem;
27+
overflow-x: auto;
28+
color: #1e293b;
29+
}
30+
</style>
31+
</head>
32+
<body class="min-h-screen flex flex-col">
33+
<nav class="bg-white shadow-sm border-b border-gray-200 sticky top-0 z-50">
34+
<div class="container mx-auto px-4 py-3">
35+
<div class="flex justify-between items-center">
36+
<a href="../README.md" class="text-xl font-bold text-purple-600 hover:text-purple-800">Smart (Components) Toolkit</a>
37+
<div class="space-x-4 text-sm">
38+
<a href="getting-started.html" class="text-gray-600 hover:text-purple-600">Getting Started</a>
39+
<a href="devices.html" class="text-gray-600 hover:text-purple-600">Devices</a>
40+
<a href="conditional-gates.html" class="text-gray-900 font-semibold">Conditional Gates</a>
41+
<a href="waiter-gates.html" class="text-gray-600 hover:text-purple-600">Waiter Gates</a>
42+
</div>
43+
</div>
44+
</div>
45+
</nav>
46+
47+
<div class="container mx-auto px-4 py-8 max-w-4xl flex-grow">
48+
<div class="mb-6">
49+
<h1 class="text-4xl font-bold mb-2 text-gray-900">Conditional Gates</h1>
50+
<p class="text-gray-600">Virtual "circuit breakers" for your flows that act as advanced latches.</p>
51+
</div>
52+
53+
<!-- Introduction -->
54+
<section class="mb-8">
55+
<h2 class="text-2xl font-semibold mb-4 text-purple-600">What are Conditional Gates?</h2>
56+
<p class="mb-4 text-gray-700">Conditional Gates are virtual logic gates (Go / No Go circuits) that exist purely in memory. They allow you to pause flows until a specific "Gate" is opened (set to GO).</p>
57+
<p class="mb-4 text-gray-700">Think of them as a traffic light for your flows:</p>
58+
<ul class="list-disc ml-6 space-y-2 text-gray-700">
59+
<li><strong>GO (Open):</strong> Flows continue immediately.</li>
60+
<li><strong>NO GO (Closed):</strong> Flows wait (pause) until the gate opens or the timeout expires.</li>
61+
</ul>
62+
</section>
63+
64+
<!-- Flow Cards -->
65+
<section class="mb-8">
66+
<h2 class="text-2xl font-semibold mb-4 text-purple-600">Flow Cards</h2>
67+
68+
<div class="space-y-6">
69+
<!-- Start Card -->
70+
<div class="bg-white rounded-lg p-6 border border-gray-200 shadow-sm">
71+
<h3 class="text-xl font-semibold mb-2 text-green-600">Conditional Gate (Wait for GO)</h3>
72+
<p class="text-sm text-gray-500 mb-3">Type: <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs font-semibold">CONDITION</span></p>
73+
<p class="mb-4 text-gray-700">Pauses the flow until the specified gate becomes <strong>GO</strong>.</p>
74+
75+
<h4 class="font-semibold mb-2 text-gray-900">Parameters:</h4>
76+
<ul class="space-y-2 text-sm text-gray-600 mb-4">
77+
<li><strong>Default State:</strong> The initial state if this gate hasn't been used before (usually NO GO).</li>
78+
<li><strong>Timeout:</strong> How long to wait for the gate to open. (Set to 0 for instant check without waiting).</li>
79+
<li><strong>Gate Name / ID:</strong> The unique name of your circuit (e.g., "KitchenMode", "NightLatch").</li>
80+
</ul>
81+
82+
<div class="bg-blue-50 p-4 rounded text-sm text-blue-800">
83+
<strong>Note:</strong> Gates persist in memory! If you set "Default: GO", the gate will remain GO until you explicitly close it using the Modify card. The "Default" setting only applies the very first time the gate is created.
84+
</div>
85+
</div>
86+
87+
<!-- Modify Card -->
88+
<div class="bg-white rounded-lg p-6 border border-gray-200 shadow-sm">
89+
<h3 class="text-xl font-semibold mb-2 text-blue-600">Modify Conditional Gate</h3>
90+
<p class="text-sm text-gray-500 mb-3">Type: <span class="bg-green-100 text-green-800 px-2 py-1 rounded text-xs font-semibold">ACTION</span></p>
91+
<p class="mb-4 text-gray-700">Changes the state of a gate (Open/Close) or updates the timeout of active waiters.</p>
92+
93+
<h4 class="font-semibold mb-2 text-gray-900">Parameters:</h4>
94+
<ul class="space-y-2 text-sm text-gray-600 mb-4">
95+
<li><strong>Gate Name / ID:</strong> Select the gate to modify.</li>
96+
<li><strong>New State:</strong> Set to GO (releases waiting flows), NO GO (stops future flows), or Toggle.</li>
97+
<li><strong>New Timeout:</strong> Update the timeout for currently waiting flows. Set to -1 to leave unchanged.</li>
98+
</ul>
99+
</div>
100+
</div>
101+
</section>
102+
103+
<!-- Examples -->
104+
<section class="mb-8">
105+
<h2 class="text-2xl font-semibold mb-4 text-purple-600">Examples</h2>
106+
107+
<!-- Example 1 -->
108+
<div class="bg-white rounded-lg p-6 border border-gray-200 shadow-sm mb-6">
109+
<h3 class="text-lg font-semibold mb-3 text-purple-600">1. Manual Approval (The "Ask Permission" Flow)</h3>
110+
<p class="mb-3 text-gray-700">Trigger a flow, but wait for manual confirmation (e.g., via a button or app) before proceeding.</p>
111+
112+
<div class="mb-4">
113+
<h4 class="font-semibold text-gray-900 mb-2">Flow 1: The Request</h4>
114+
<pre class="text-sm"><code>WHEN: Washing Machine finished
115+
AND: Conditional Gate "EmptyWasher" (Default: NO GO, Timeout: 1 hour)
116+
THEN: Send push notification "Washer emptied!"</code></pre>
117+
</div>
118+
119+
<div>
120+
<h4 class="font-semibold text-gray-900 mb-2">Flow 2: The Approval</h4>
121+
<pre class="text-sm"><code>WHEN: Virtual Button "Washer Emptied" pressed
122+
THEN: Modify Conditional Gate "EmptyWasher" -> Set to GO
123+
THEN: Modify Conditional Gate "EmptyWasher" -> Set to NO GO (Reset for next time)</code></pre>
124+
</div>
125+
</div>
126+
127+
<!-- Example 2 -->
128+
<div class="bg-white rounded-lg p-6 border border-gray-200 shadow-sm">
129+
<h3 class="text-lg font-semibold mb-3 text-purple-600">2. "Latch" Logic</h3>
130+
<p class="mb-3 text-gray-700">Prevent a flow from running until a specific condition (Latch) is set, and queue up requests.</p>
131+
<pre class="text-sm"><code>WHEN: Motion Detected
132+
AND: Conditional Gate "NightModeLatch" (Default: NO GO, Timeout: 0)
133+
THEN: Turn on hallway lights dimly</code></pre>
134+
<p class="text-sm text-gray-600 mt-2">Here, Timeout 0 acts as a filter. If "NightModeLatch" is NO GO, the flow stops immediately. If it is GO, lights turn on.</p>
135+
</div>
136+
</section>
137+
138+
</div>
139+
140+
<footer class="bg-white border-t border-gray-200 mt-12 py-6 text-center text-gray-600">
141+
<p>Smart (Components) Toolkit for Homey | <a href="https://github.com/Tiwas/SmartComponentsToolkit" class="text-purple-600 hover:text-purple-300">GitHub</a></p>
142+
</footer>
143+
</body>
144+
</html>

docs/index.html

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,33 @@ <h3 class="text-xl font-semibold text-purple-600">State Capture Device</h3>
224224
<p><a href="docs/state-capture-device.html" class="text-purple-600 hover:text-purple-800 font-semibold">Read State Capture Device guide &rarr;</a></p>
225225
</div>
226226

227+
<!-- Conditional Gates -->
228+
<div class="bg-white rounded-lg p-6 shadow-sm border border-gray-200 mb-6">
229+
<div class="flex items-center gap-3 mb-4">
230+
<h3 class="text-xl font-semibold text-purple-600">Conditional Gates</h3>
231+
</div>
232+
<p class="text-gray-700 mb-4">Virtual "Go/No Go" circuits to pause and release flows based on logic states.</p>
233+
<div class="overflow-x-auto mb-4">
234+
<table class="w-full text-left text-sm">
235+
<tbody class="text-gray-700">
236+
<tr class="border-b border-gray-200">
237+
<td class="py-2 font-semibold w-32">Wait condition</td>
238+
<td>Pause flow until Gate is Open (GO)</td>
239+
</tr>
240+
<tr class="border-b border-gray-200">
241+
<td class="py-2 font-semibold">Persistence</td>
242+
<td>Gates remember their state until restarted</td>
243+
</tr>
244+
<tr>
245+
<td class="py-2 font-semibold">Control</td>
246+
<td>Open/Close gates from any flow</td>
247+
</tr>
248+
</tbody>
249+
</table>
250+
</div>
251+
<p><a href="docs/conditional-gates.html" class="text-purple-600 hover:text-purple-800 font-semibold">Read Conditional Gates guide &rarr;</a></p>
252+
</div>
253+
227254
<!-- Waiter Gates (BETA) -->
228255
<div class="bg-white rounded-lg p-6 shadow-sm border border-gray-200 border-l-4 border-l-yellow-500 mb-6">
229256
<div class="flex items-center gap-3 mb-4">
@@ -379,6 +406,7 @@ <h2 class="text-2xl font-bold text-gray-900 mb-6">Documentation</h2>
379406
<li><a href="docs/devices.html" class="text-purple-600 hover:text-purple-800">Device Types Guide</a></li>
380407
<li><a href="docs/state-device.html" class="text-purple-600 hover:text-purple-800">State Device</a></li>
381408
<li><a href="docs/state-capture-device.html" class="text-purple-600 hover:text-purple-800">State Capture Device</a></li>
409+
<li><a href="docs/conditional-gates.html" class="text-purple-600 hover:text-purple-800">Conditional Gates</a></li>
382410
<li><a href="docs/waiter-gates.html" class="text-purple-600 hover:text-purple-800">Waiter Gates (BETA)</a></li>
383411
<li><a href="docs/flow-cards.html" class="text-purple-600 hover:text-purple-800">Flow Cards Reference</a></li>
384412
</ul>

no.tiwas.booleantoolbox/.homeychangelog.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,8 @@
3737
},
3838
"1.8.2": {
3939
"en": "Fixed some errors with IDs in waiter gates."
40+
},
41+
"1.9.0": {
42+
"en": "Added conditional gates for better flow control without variables"
4043
}
4144
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
{
2+
"title": {
3+
"en": "Modify Conditional Gate",
4+
"no": "Endre Betinget Port",
5+
"nl": "Wijzig Voorwaardelijke Poort",
6+
"de": "Bedingtes Tor Ändern"
7+
},
8+
"titleFormatted": {
9+
"en": "Modify gate [[gate_name]] (Set state: [[new_state]], Set timeout: [[new_timeout_value]] [[new_timeout_unit]])",
10+
"no": "Endre port [[gate_name]] (Sett status: [[new_state]], Sett timeout: [[new_timeout_value]] [[new_timeout_unit]])",
11+
"nl": "Wijzig poort [[gate_name]] (Zet status: [[new_state]], Zet timeout: [[new_timeout_value]] [[new_timeout_unit]])",
12+
"de": "Tor [[gate_name]] ändern (Status setzen: [[new_state]], Timeout setzen: [[new_timeout_value]] [[new_timeout_unit]])"
13+
},
14+
"hint": {
15+
"en": "Modifies a Conditional Gate. Set Timeout to -1 for no change.",
16+
"no": "Endrer en Betinget Port. Sett Timeout til -1 for ingen endring.",
17+
"nl": "Wijzigt een Voorwaardelijke Poort. Zet Timeout op -1 voor geen wijziging.",
18+
"de": "Ändert ein Bedingtes Tor. Setze Timeout auf -1 für keine Änderung."
19+
},
20+
"args": [
21+
{
22+
"type": "autocomplete",
23+
"name": "gate_name",
24+
"title": {
25+
"en": "Gate Name / ID",
26+
"no": "Port Navn / ID",
27+
"nl": "Poort Naam / ID",
28+
"de": "Tor Name / ID"
29+
},
30+
"placeholder": {
31+
"en": "Select Gate Name",
32+
"no": "Velg Port Navn",
33+
"nl": "Selecteer Poort Naam",
34+
"de": "Wähle Tor Name"
35+
}
36+
},
37+
{
38+
"type": "dropdown",
39+
"name": "new_state",
40+
"title": {
41+
"en": "New State",
42+
"no": "Ny Status",
43+
"nl": "Nieuwe Status",
44+
"de": "Neuer Status"
45+
},
46+
"values": [
47+
{ "id": "NO_CHANGE", "title": { "en": "Don't change", "no": "Ikke endre", "nl": "Niet wijzigen", "de": "Nicht ändern" } },
48+
{ "id": "GO", "title": { "en": "Set to GO", "no": "Sett til GO", "nl": "Zet op GO", "de": "Setze auf GO" } },
49+
{ "id": "NO_GO", "title": { "en": "Set to NO GO", "no": "Sett til NO GO", "nl": "Zet op NO GO", "de": "Setze auf NO GO" } },
50+
{ "id": "TOGGLE", "title": { "en": "Toggle", "no": "Veksle", "nl": "Omschakelen", "de": "Umschalten" } }
51+
],
52+
"defaultValue": "NO_CHANGE"
53+
},
54+
{
55+
"type": "number",
56+
"name": "new_timeout_value",
57+
"title": {
58+
"en": "New Timeout (-1 = no change)",
59+
"no": "Ny Timeout (-1 = ingen endring)",
60+
"nl": "Nieuwe Timeout (-1 = geen wijziging)",
61+
"de": "Neuer Timeout (-1 = keine Änderung)"
62+
},
63+
"min": -1,
64+
"step": 1,
65+
"defaultValue": -1
66+
},
67+
{
68+
"type": "dropdown",
69+
"name": "new_timeout_unit",
70+
"title": {
71+
"en": "Timeout unit",
72+
"no": "Timeout enhet",
73+
"nl": "Timeout eenheid",
74+
"de": "Timeout Einheit"
75+
},
76+
"values": [
77+
{ "id": "s", "title": { "en": "Seconds", "no": "Sekunder", "nl": "Seconden", "de": "Sekunden" } },
78+
{ "id": "m", "title": { "en": "Minutes", "no": "Minutter", "nl": "Minuten", "de": "Minuten" } },
79+
{ "id": "h", "title": { "en": "Hours", "no": "Timer", "nl": "Uren", "de": "Stunden" } }
80+
],
81+
"defaultValue": "s"
82+
}
83+
]
84+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"title": {
3+
"en": "Conditional Gate",
4+
"no": "Betinget Port",
5+
"nl": "Voorwaardelijke Poort",
6+
"de": "Bedingtes Tor"
7+
},
8+
"titleFormatted": {
9+
"en": "Conditional Gate: Wait for GO (default: [[default_state]], timeout: [[timeout_value]] [[timeout_unit]], Name/ID: [[gate_name]])",
10+
"no": "Betinget Port: Vent på GO (standard: [[default_state]], timeout: [[timeout_value]] [[timeout_unit]], Navn/ID: [[gate_name]])",
11+
"nl": "Voorwaardelijke Poort: Wacht op GO (standaard: [[default_state]], timeout: [[timeout_value]] [[timeout_unit]], Naam/ID: [[gate_name]])",
12+
"de": "Bedingtes Tor: Warte auf GO (Standard: [[default_state]], Timeout: [[timeout_value]] [[timeout_unit]], Name/ID: [[gate_name]])"
13+
},
14+
"hint": {
15+
"en": "Pauses flow until the specified Gate is GO. Use 'Modify Conditional Gate' to control it by Name/ID.",
16+
"no": "Pauser flyten til angitt Port er GO. Bruk 'Endre Betinget Port' for å styre den med Navn/ID.",
17+
"nl": "Pauzeert flow totdat de opgegeven Poort GO is. Gebruik 'Wijzig Voorwaardelijke Poort' om te bedienen via Naam/ID.",
18+
"de": "Pausiert Flow bis das angegebene Tor GO ist. Verwenden Sie 'Bedingtes Tor ändern' zur Steuerung über Name/ID."
19+
},
20+
"args": [
21+
{
22+
"type": "dropdown",
23+
"name": "default_state",
24+
"title": {
25+
"en": "Default State (if new)",
26+
"no": "Standardstatus (hvis ny)",
27+
"nl": "Standaardstatus (indien nieuw)",
28+
"de": "Standardstatus (wenn neu)"
29+
},
30+
"values": [
31+
{ "id": "NO_GO", "title": { "en": "NO GO (Closed)", "no": "NO GO (Stengt)", "nl": "NO GO (Gesloten)", "de": "NO GO (Geschlossen)" } },
32+
{ "id": "GO", "title": { "en": "GO (Open)", "no": "GO (Åpen)", "nl": "GO (Open)", "de": "GO (Offen)" } }
33+
],
34+
"defaultValue": "NO_GO"
35+
},
36+
{
37+
"type": "number",
38+
"name": "timeout_value",
39+
"title": {
40+
"en": "Timeout duration",
41+
"no": "Timeout varighet",
42+
"nl": "Timeout duur",
43+
"de": "Timeout Dauer"
44+
},
45+
"min": 0,
46+
"step": 1,
47+
"defaultValue": 60
48+
},
49+
{
50+
"type": "dropdown",
51+
"name": "timeout_unit",
52+
"title": {
53+
"en": "Timeout unit",
54+
"no": "Timeout enhet",
55+
"nl": "Timeout eenheid",
56+
"de": "Timeout Einheit"
57+
},
58+
"values": [
59+
{ "id": "s", "title": { "en": "Seconds", "no": "Sekunder", "nl": "Seconden", "de": "Sekunden" } },
60+
{ "id": "m", "title": { "en": "Minutes", "no": "Minutter", "nl": "Minuten", "de": "Minuten" } },
61+
{ "id": "h", "title": { "en": "Hours", "no": "Timer", "nl": "Uren", "de": "Stunden" } }
62+
],
63+
"defaultValue": "s"
64+
},
65+
{
66+
"type": "autocomplete",
67+
"name": "gate_name",
68+
"title": {
69+
"en": "Gate Name / ID",
70+
"no": "Port Navn / ID",
71+
"nl": "Poort Naam / ID",
72+
"de": "Tor Name / ID"
73+
},
74+
"placeholder": {
75+
"en": "e.g. KitchenCheck",
76+
"no": "f.eks. KjøkkenSjekk",
77+
"nl": "bijv. KeukenCheck",
78+
"de": "z.B. KüchenCheck"
79+
}
80+
}
81+
]
82+
}

0 commit comments

Comments
 (0)