This commit is contained in:
Mateusz Gruszczyński
2026-09-01 22:20:10 +02:00
parent 1cb62c8d0b
commit 16e0d94564
47 changed files with 2565 additions and 117 deletions
+62
View File
@@ -176,6 +176,20 @@
<div class="list-grid" id="groupList"></div>
</section>
<section class="view" data-view="flows">
<div class="section-heading">
<div><span class="eyebrow" data-i18n="flow.eyebrow">Visual logic</span>
<h1 data-i18n="nav.flows">Flow</h1>
</div><div class="section-actions"><button class="secondary" type="button" data-action="import-flow" data-i18n="flow.import">Import Flow</button><button class="primary" type="button" data-action="new-flow" data-i18n="flow.new">New Flow</button></div>
</div>
<div class="panel flow-info-panel">
<div><strong data-i18n="flow.infoTitle">One place for schedules and automations</strong>
<p data-i18n="flow.infoText">Build the logic from blocks. GREE Controller translates Flow into generated schedules and automations. Generated entries are read-only outside this editor.</p></div>
<span class="badge" data-i18n="flow.sourceOfTruth">Flow = source of truth</span>
</div>
<div class="list-grid" id="flowList"></div>
</section>
<section class="view" data-view="schedules">
<div class="section-heading">
<div><span class="eyebrow" data-i18n="schedules.calendar">Calendar</span>
@@ -694,6 +708,53 @@
</section>
</main>
<section id="flowEditor" class="flow-editor" hidden aria-label="Flow editor">
<header class="flow-editor-bar">
<div class="flow-editor-title"><button type="button" class="icon-button" data-action="close-flow-editor" aria-label="Back"></button><div><span class="eyebrow" data-i18n="flow.editorEyebrow">Flow editor</span><input id="flowName" maxlength="100" data-i18n-placeholder="flow.namePlaceholder" placeholder="My automation"></div></div>
<div class="flow-editor-actions"><button class="secondary" type="button" data-action="flow-templates" data-i18n="flow.templates">Templates</button><button class="secondary" type="button" data-action="import-flow" data-i18n="flow.import">Import</button><button class="secondary" type="button" data-action="export-flow" data-i18n="flow.export">Export</button><button class="secondary" type="button" data-action="flow-dry-run" data-i18n="flow.dryRun">Dry-run</button><button class="secondary" type="button" data-action="flow-logs" data-i18n="flow.logs">Logs</button><label class="flow-enabled"><input type="checkbox" id="flowEnabled" checked><span data-i18n="common.enabled">Enabled</span></label><span id="flowCompileStatus" class="badge"></span><button class="primary" type="button" data-action="save-flow" data-i18n="actions.save">Save</button></div>
</header>
<div class="flow-editor-body">
<aside class="flow-palette">
<div class="flow-palette-head"><strong data-i18n="flow.blocks">Blocks</strong><small data-i18n="flow.paletteHint">Add a block, then connect its output to the next block.</small></div>
<div class="flow-palette-group"><span data-i18n="flow.time">Time</span>
<button type="button" data-flow-add="weekday" data-i18n="flow.node.weekday">Dni tygodnia</button><button type="button" data-flow-add="time_range" data-i18n="flow.node.timeRange">Przedział godzin</button><button type="button" data-flow-add="date_range" data-i18n="flow.node.dateRange">Zakres dat</button><button type="button" data-flow-add="night_mode" data-i18n="flow.node.nightMode">Tryb nocny</button></div>
<div class="flow-palette-group"><span data-i18n="flow.sensors">Sensors</span>
<button type="button" data-flow-add="outdoor_temperature" data-i18n="flow.node.outdoorTemperature">Temperatura zewn.</button><button type="button" data-flow-add="device_temperature" data-i18n="flow.node.deviceTemperature">Temperatura urządzenia</button><button type="button" data-flow-add="zone_temperature" data-i18n="flow.node.zoneTemperature">Temperatura strefy</button><button type="button" data-flow-add="house_mode" data-i18n="flow.node.houseMode">Tryb domu</button><button type="button" data-flow-add="device_state" data-i18n="flow.node.deviceState">Stan urządzenia</button><button type="button" data-flow-add="zone_state" data-i18n="flow.node.zoneState">Stan termostatu</button><button type="button" data-flow-add="group_state" data-i18n="flow.node.groupState">Stan grupy</button><button type="button" data-flow-add="ha_state" data-i18n="flow.node.haState">HA: stan</button><button type="button" data-flow-add="ha_numeric" data-i18n="flow.node.haNumeric">HA: wartość</button><button type="button" data-flow-add="ha_attribute" data-i18n="flow.node.haAttribute">HA: atrybut</button><button type="button" data-flow-add="ha_available" data-i18n="flow.node.haAvailable">HA: dostępność</button><button type="button" data-flow-add="constant" data-i18n="flow.node.constant">Stała testowa</button></div>
<div class="flow-palette-group"><span data-i18n="flow.logic">Logic</span><button type="button" data-flow-add="logic_and" data-i18n="flow.node.and">AND</button><button type="button" data-flow-add="logic_or" data-i18n="flow.node.or">OR</button><button type="button" data-flow-add="logic_not" data-i18n="flow.node.not">NOT</button></div>
<div class="flow-palette-group"><span data-i18n="flow.actions">Actions</span>
<button type="button" data-flow-add="zone_thermostat" data-i18n="flow.node.thermostat">Termostat</button><button type="button" data-flow-add="device_action" data-i18n="flow.node.greeDevice">Urządzenie GREE</button><button type="button" data-flow-add="group_action" data-i18n="flow.node.group">Grupa</button></div>
</aside>
<div class="flow-workspace-wrap">
<div id="flowWorkspace" class="flow-workspace" tabindex="0">
<svg id="flowEdges" class="flow-edges" aria-hidden="true"></svg><div id="flowNodes" class="flow-nodes"></div>
<div id="flowEmptyHint" class="flow-empty-hint"><strong data-i18n="flow.emptyCanvas">Start by adding blocks</strong><span data-i18n="flow.emptyCanvasHint">Conditions go on the left, actions on the right.</span></div>
</div>
<div class="flow-natural-preview"><strong data-i18n="flow.interpretation">Interpretation</strong><span id="flowInterpretation"></span></div>
</div>
<aside id="flowInspector" class="flow-inspector"><div class="empty compact"><strong data-i18n="flow.selectBlock">Select a block</strong><span data-i18n="flow.selectBlockHint">Its settings will appear here.</span></div></aside>
</div>
</section>
<input id="flowImportFile" type="file" accept="application/json,.json,.flow.json" hidden>
<dialog id="flowTemplateDialog" class="flow-tool-dialog">
<div class="dialog-head"><div><span class="eyebrow" data-i18n="flow.templateLibrary">Flow library</span><h2 data-i18n="flow.templates">Templates</h2></div><button type="button" data-close>×</button></div>
<p class="field-note" data-i18n="flow.templatesHint">Ready-made layouts create an editable graph using existing zones, devices and groups.</p>
<div id="flowTemplateList" class="flow-template-list"></div>
</dialog>
<dialog id="flowTestDialog" class="flow-tool-dialog">
<div class="dialog-head"><div><span class="eyebrow" data-i18n="flow.testMode">Flow diagnostics</span><h2 id="flowTestTitle" data-i18n="flow.dryRun">Dry-run</h2></div><button type="button" data-close>×</button></div>
<div id="flowSimulationControls" class="flow-simulation-controls">
<p class="field-note" data-i18n="flow.dryRunHint">Dry-run does not change thermostat, device, group, schedule or automation state.</p>
<label><span data-i18n="flow.simulationTime">Simulation date and time</span><input id="flowSimulationAt" type="datetime-local"></label>
<div><strong data-i18n="flow.simulationOverrides">Sensor overrides</strong><p class="field-note" data-i18n="flow.simulationOverridesHint">Leave blank to use the current application or Home Assistant state.</p><div id="flowSimulationOverrides" class="flow-simulation-overrides"></div></div>
<div class="dialog-actions"><button class="primary" type="button" data-action="run-flow-dry-run" data-i18n="flow.runSimulation">Run simulation</button></div>
</div>
<div id="flowTestResults" class="flow-test-results"></div>
</dialog>
<nav class="bottom-nav" data-i18n-aria="nav.navigation" aria-label="Navigation">
<button class="active" data-nav="dashboard"><span></span><b data-i18n="nav.dashboard">Dashboard</b></button>
<button data-nav="devices"><span></span><b data-i18n="nav.devices">Devices</b></button>
@@ -708,6 +769,7 @@
</div>
<div class="menu-list">
<button data-go="groups"><span data-i18n="nav.groups">Groups</span><span></span></button>
<button data-go="flows"><span data-i18n="nav.flows">Flow</span><span></span></button>
<button data-go="schedules"><span data-i18n="nav.schedules">Schedules</span><span></span></button>
<button data-go="automations"><span data-i18n="nav.automations">Automations</span><span></span></button>
<button data-go="simulation"><span data-i18n="nav.simulation">Simulator</span><span></span></button>