diff --git a/internal/httpserver/web/index.html b/internal/httpserver/web/index.html index 31fc776..c7e8a81 100644 --- a/internal/httpserver/web/index.html +++ b/internal/httpserver/web/index.html @@ -16,6 +16,10 @@ --accent-dim: #1f6b45; --warn: #e8b339; --pump: #3aa0e8; + --wire-sensor: #33d17a; + --wire-fan: #5b7ba8; + --wire-light: #e8b339; + --wire-pump: #3aa0e8; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } * { box-sizing: border-box; } @@ -26,7 +30,7 @@ padding: 24px; } h1 { font-size: 1.3rem; font-weight: 600; margin: 0 0 4px; } - .subtitle { color: var(--muted); margin: 0 0 24px; font-size: 0.9rem; } + .subtitle { color: var(--muted); margin: 0 0 24px; font-size: 0.9rem; max-width: 640px; } .conn { display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--muted); margin-bottom: 20px; @@ -36,8 +40,12 @@ .conn.offline .dot { background: #d95555; } .board-wrap { display: flex; justify-content: center; margin-bottom: 28px; } - .board { width: 100%; max-width: 520px; } - .board rect.case { fill: var(--panel); stroke: var(--border); stroke-width: 2; } + .board { width: 100%; max-width: 720px; } + .pin { fill: #cbd5e1; } + .pin-label { font-size: 10px; fill: var(--muted); } + .wire { fill: none; stroke-width: 2; opacity: 0.85; } + .peripheral-label { font-size: 12px; fill: var(--text); font-weight: 600; text-anchor: middle; } + .peripheral-sub { font-size: 9px; fill: var(--muted); text-anchor: middle; } .fan-blades { transform-origin: center; transition: opacity .2s; } .fan-blades.on { animation: spin 0.9s linear infinite; } @@ -53,9 +61,9 @@ .grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; - max-width: 1080px; + max-width: 1160px; margin: 0 auto; } .card { @@ -63,7 +71,9 @@ border: 1px solid var(--border); border-radius: 12px; padding: 16px; + transition: box-shadow .3s, border-color .3s; } + .card.flash { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(51,209,122,0.25); } .card h2 { font-size: 0.95rem; margin: 0 0 12px; display: flex; align-items: center; justify-content: space-between; @@ -81,7 +91,7 @@ font-size: 0.88rem; } input[type=range] { width: 100%; } - .row { display: flex; gap: 10px; } + .row { display: flex; gap: 10px; align-items: flex-end; } .row > div { flex: 1; } button { @@ -95,29 +105,92 @@ .status-line { display: flex; justify-content: space-between; font-size: 0.85rem; margin-top: 8px; } .status-line span:last-child { color: var(--text); font-weight: 600; } .value { color: var(--text); font-weight: 600; } + .hint { color: var(--muted); font-size: 0.78rem; margin-top: 10px; } + + .signal-row { + display: flex; align-items: center; justify-content: space-between; + gap: 8px; padding: 6px 0; border-top: 1px solid var(--border); font-size: 0.85rem; + } + .signal-row:first-of-type { border-top: none; } + .signal-row .name { color: var(--muted); } + .signal-row input[type=range] { flex: 1; } + .signal-row .val { width: 44px; text-align: right; font-weight: 600; } + .toggle { + width: 40px; height: 22px; border-radius: 999px; background: var(--panel-2); + border: 1px solid var(--border); position: relative; cursor: pointer; flex-shrink: 0; + } + .toggle.on { background: var(--accent-dim); border-color: var(--accent); } + .toggle .knob { + position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; + background: var(--muted); transition: left .15s, background .15s; + } + .toggle.on .knob { left: 20px; background: var(--accent); } + + .add-signal { border-top: 1px dashed var(--border); margin-top: 12px; padding-top: 12px; } + .add-signal .row2 { display: flex; gap: 8px; margin-top: 6px; } + select { + padding: 7px 9px; border-radius: 7px; border: 1px solid var(--border); + background: var(--panel-2); color: var(--text); font-size: 0.85rem; + }

ESP32 Emulator

-

Виртуальный контроллер гроубокса — датчик + вентилятор + свет + помпа, говорит по тому же MQTT-протоколу, что и настоящее устройство.

+

Виртуальный ESP32-контроллер гроубокса. Слева — какой пин к чему подключён. Показания датчика вы задаёте и публикуете сами (входные сигналы → в автоматику); питание/уровень актуаторов меняются САМИ, когда платформа реально присылает команду (выход из автоматики → сюда).

подключение…
- - + + + + + + ESP32 + WROOM-32 + + USB + + EN + + BOOT - - - - 24°C - 55% + + + + + + + + + + + + + + + + + GPIO4 + GPIO16 + GPIO17 + GPIO18 - датчик - - - + + + + + 24°C + 55% + + Датчик DHT22 + GPIO4 · input + + + + + @@ -125,22 +198,27 @@ - вентилятор + Вентилятор + GPIO16 · relay - - + + + - + - свет + Свет + GPIO17 · relay - - - - - + + + + + + - помпа + Помпа + GPIO18 · relay
@@ -148,13 +226,21 @@