Страница 2 из 3

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 04 май 2026, 22:14
MarkT
И так. Что мы имеем
- Меню холодильника, которое менеджер может прямо сейчас обновить.
- Плагин шлюза управления холодильником есть и готов. Надо настроить
- Кнопку открытия холодильника на странице холодильника по которой можно будет нажать. Сработает вебхук на открытие кнопки и дверь должна фактически открыться. Через шлюз управления.
- Железки (мозги) холодильника приедут завтра и послезавтра
Ну и вроде как бы все. Осталось теперь все это срастить.

На сращивание - 4 дня и до конца недели надо все повесить на холодильник.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 04 май 2026, 23:36
MarkT
Сейчас работаю на логикой внутри страницы холодильника.
Пока останавливаюсь на этом:

1. Общий поток

Клиент сканирует QR и попадает на страницу холодильника, например:

Код: Выделить всё

/sh52001/
.

Жмёт «ОТКРЫТЬ ХОЛОДИЛЬНИК»: физически открывается дверь, на фронте включается “режим сканирования”.

Каждый скан штрих‑кода:
– фронт получает код с камеры,
– вызывает

Код: Выделить всё

scanAndAddToCart(barcode)
,
– та в фоне добавляет товар в корзину так, как будто юзер нажал обычную кнопку “В корзину”.

Woodmart по своему механизму:
– обновляет корзину WooCommerce,
– показывает справа стандартную мини‑корзину (off‑canvas).

Когда клиент закончил набирать товары, жмёт «ПЕРЕЙТИ К ОПЛАТЕ» → редирект на стандартный WooCommerce checkout с уже заполненной корзиной.

2. Что нужно реализовать по слоям

Фронт (JS на странице /sh52001/)

Сканер (камера в браузере).
– выводим оверлей камеры с рамкой под штрих‑код,
– по успешному чтению вызываем

Код: Выделить всё

scanAndAddToCart(barcode)
и закрываем оверлей.

Функция scanAndAddToCart(barcode).
– по штрих‑коду на стороне фронта или бэкенда определяем

Код: Выделить всё

product_id
(штрих‑код → артикул/ID),
– делаем / на REST/ AJAX‑эндпоинт, который:

вызывает

Код: Выделить всё

WC()->cart->add_to_cart( $product_id, 1 );
,

возвращает JSON с результатом;
– при успешном добавлении:

даём отработать стандартному механизму темы Woodmart (мини‑корзина справа, обновление суммы и т.п.),

при первом добавленном товаре меняем состояние основной кнопки на “ПЕРЕЙТИ К ОПЛАТЕ”.

Фактически задача scanAndAddToCart — “программно нажать add to cart” через AJAX, а не изобрести свой mini‑cart.

Состояния UI (одна плавающая кнопка).
«ОТКРЫТЬ ХОЛОДИЛЬНИК» — команда открыть дверь, включить режим сканирования;
«СКАНИРОВАТЬ ТОВАР» — открыть оверлей камеры, ждать штрих‑код;
«ПЕРЕЙТИ К ОПЛАТЕ»

Код: Выделить всё

window.location = wc_get_checkout_url()
или просто

Код: Выделить всё

'/checkout/'
. Текст и цвет кнопки завязаны на внутреннее состояние сеанса холодильника (idle / door_open / есть товары в корзине).

Сохранение сеанса на фронте.
– в

Код: Выделить всё

localStorage
можно хранить:

ID “сеанса холодильника” (если он есть на бэкенде),

последнее состояние (дверь открыта/закрыта, были ли сканы),
– при перезагрузке страницы:

подтягиваем текущее состояние из сервера при необходимости,

ориентируемся по корзине (если в ней уже есть позиции с этого холодильника — сразу предлагаем “Перейти к оплате” или “Сканировать ещё”).

Бэкенд (мини‑плагин типа “fridge-scenarios”)

REST‑/AJAX‑эндпоинт для добавления по штрих‑коду.
– принимает штрих‑код (и, опционально, ID сеанса),
– ищет товар по метаполю / отдельной таблице штрих‑кодов / артикулу,
– выполняет

Код: Выделить всё

WC()->cart->add_to_cart( $product_id, 1 );
,
– возвращает JSON со статусом (ok/error) и, при желании, краткой инфой о товаре. Если вызывать именно WooCommerce‑механику добавления (а не вручную трогать сессию), Woodmart автоматически отработает своё поведение мини‑корзины.

Дополнительные эндпоинты (по необходимости).

Код: Выделить всё

open door / close door
— для связи с железом;

Код: Выделить всё

get current session items
— чтобы фронт мог, при желании, спросить у сервера “что уже набрано” и показать подсказки;
– возможно, endpoint “finish session”, чтобы на бэке помечать, что холодильник закрыт и сеанс завершён.

Корзина WooCommerce уже сама по себе живёт в сессии/куках, поэтому товары, добавленные через этот эндпоинт, никуда не исчезают даже при вылете вкладки — пользователь может сразу идти на

Код: Выделить всё

/checkout/
.

3. Основные плюсы такого подхода

– Не завязаны на наличие кнопок “В корзину” в шаблоне холодильника: всё делается через один AJAX/REST‑вызов.
– Используем готовую мини‑корзину Woodmart как UI для списка взятых товаров (без изобретения собственного мини‑листа).
– Поток для клиента простой: открыть → сканировать → мини‑корзина → переход к оплате, всё в рамках одного экрана.
– Корзина устойчива к вылетам страницы, а логику защиты (QR‑режим, таймаут, повторные открытия двери и т.п.) можно внедрять поверх этой архитектуры, не ломая базовый сценарий.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 04 май 2026, 23:42
MarkT
Сделаем еще два шага сегодня:
1. Кнопка с переходом в режим “СКАНИРОВАТЬ товар” (изменение текста и цвета после клика “ОТКРЫТЬ”).
2. Сканер со стилизацией под лазерный сканер и узкой щелью под EAN 13

Надо еще подумать над логикой "защиты от дурака". Для себя уже пометил, но работать над этим лучше уже не стадии отладки сценариев.

UPD: утром проверил сканнер код читает.
Сегодня будем работать над добавлением товара из холодильника в корзину и оплатой.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 05 май 2026, 10:22
MarkT
Сегодня мебельщики прислали макет.
Лучше левый вариант. Но надо доработать:
1. Столешницу сделать с выносом вперед.
2. Сделать выдвижной ящик под приборы и салфетки

Вверху криво нарисован телек.
На нем будет отображаться меню холодильника
Данная функция реализована через отдельный плагин и уже сейчас работает на раздаче. Вывод через СПЕЦИАЛЬНЫЙ браузер телевизора с обновлением странице раз в N часов.
Пример на фото.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 05 май 2026, 18:41
MarkT
И так. Приехали железяки. Основную заинтересованность представляет девайс на фото.

Встречайте: (H R C F) ESP32-S3 SIM7670G Макетная Плата 4G
Оснащен высокопроизводительным 32-битным двухъядерным процессором Xtensa® LX7 с тактовой частотой до 240 МГц
Поддержка Wi-Fi 2,4 ГГц (802.11 b/g) и Bluetooth® 5 (LE), встроенная антенна
Встроенная объемом 512 КБ и ПЗУ 384 КБ, составная PSRAM объемом 2 МБ и внешняя флэш-память емкостью 16 МБ

ESP32-S3-SIM7670G-4G (далее совместно именуемая «плата разработки») - это многофункциональная высокопроизводительная плата разработки микроконтроллера. Плата содержит модуль связи SIM7670G 4G, универсальный интерфейс камеры , слот совместим с TF-карты, красочную подсветку RGB, слот совместим с батареи 18650, микросхему измерения напряжения батареи, интерфейс зарядки солнечной батареи и другие периферийные устройства.
Используемый ESP32-S3R2 представляет собой интегрированную маломощную систему на кристалле (SoC), которая потребляет Wi-Fi и BLE5.0, а также имеет внешнюю флэш-память объемом 16 МБ и PSRAM объемом 2 МБ. Аппаратный ускоритель шифрования, , HMAC и модуль цифровой подписи (Digital Signature) внутри Soc могут соответствовать требованиям безопасности Интернета вещей. Используемый модуль связи SIM7670G 4G обеспечивает мобильную сеть, а в сочетании с ESP32-S3R2 он может реализовать портативный WIFI, передачу данных IoT и другие функции. Разнообразие рабочих состояний с низким энергопотреблением соответствует потребностям в энергопотреблении таких сценариев применения, как Интернет вещей (IoT), мобильные устройства, наружный мониторинг и умные дома.

Комплект достаточно внушительный.
Состав на фото.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 08 май 2026, 09:13
MarkT
Эволюция от идеи до реального кода отражается в следующем:

Сценарий: ESP32-S3 + SIM7670 (A7670), TCP‑шлюз на Node.js и интеграция с WordPress

Исходные данные:

– Устройство: ESP32-S3 с SIM7670 (A7670), связь через LTE/4G.
– Оператор: Билайн (APN: internet.beeline.ru, логин/пароль: beeline).
– На сервере уже есть Node.js проект с HTTP API:

– API listening on port 3005
– API Key: gsm-secret-key-2026
– API URL: http://localhost:3005

Цель: построить нормальный GSM‑шлюз для холодильников, который:

– держит постоянное TCP‑соединение с устройствами;
– мгновенно передает команды (например, OPEN для замка);
– обменивается телеметрией;
– при этом WordPress работает только с HTTP API шлюза, а не лезет напрямую к железу.

Ниже вся архитектура и протокол в одном месте.

Роли компонентов

Устройство (ESP32-S3 + SIM7670)

– Постоянный TCP‑клиент.
– Подключается к TCP‑серверу, отправляет HELLO с ID и секретом.
– Периодически шлет ping с телеметрией.
– Принимает команды (OPEN и т.п.) и отправляет события (DOOR_OPENED и т.д.).

Node‑шлюз (порт 3005 + отдельный TCP‑порт)

– На Node.js:
– TCP‑сервер для холодильников (отдельный порт, например 4000).
– REST API (уже есть: http://localhost:3005, с API‑ключом).
– Держит карту подключений fridge_id → socket.
– Принимает телеметрию и события от устройств.
– По HTTP‑запросам от WordPress отправляет команды нужным холодильникам по TCP.

WordPress + плагин (например stolovka-fridges-gateway.php)

– Не общается с устройствами напрямую.
– При нажатии в админке «Открыть холодильник» делает HTTP‑запрос к Node‑шлюзу, например:

POST http://localhost:3005/open
X-API-Key: gsm-secret-key-2026
fridge_id=123

– Node‑шлюз находит TCP‑сокет для fridge_id=123 и отправляет через него команду OPEN.

Протокол TCP (JSON по строкам)

Все сообщения – одна строка JSON + символ перевода строки \n. Это сильно упрощает парсинг.

2.1. Устройство → Node

Регистрация (HELLO)

Отправляется сразу после установления TCP‑соединения:

Код: Выделить всё

{"type":"hello","id":"fridge-123","secret":"ABCDEF123456","fw":"1.0.0"}
– id – уникальный ID холодильника (из админки).
– secret – секретный ключ (из админки/БД).
– fw – версия прошивки (по желанию).

Пинг с телеметрией

На регулярном интервале (например, каждые N секунд):

Код: Выделить всё

{"type":"ping","id":"fridge-123","t":4.5,"door":0,"comp":1,"mains":1}
Где:

– t – температура (С).
– door – состояние двери (0/1).
– comp – состояние компрессора (0/1).
– mains – наличие 220В (0/1).

События

Например, дверь открылась:

Код: Выделить всё

{"type":"event","id":"fridge-123","event":"DOOR_OPENED"}
Дверь закрылась:

Код: Выделить всё

{"type":"event","id":"fridge-123","event":"DOOR_CLOSED"}
Можно расширять (ALARM, POWER_LOSS и т.д.).

2.2. Node → Устройство

Подтверждение регистрации

После успешного HELLO:

Код: Выделить всё

{"type":"hello_ok","mode":"idle"}
mode – необязательное поле, можно использовать для режимов (idle/active) или вообще не использовать.

Команда открыть замок

Код: Выделить всё

{"type":"cmd","cmd":"OPEN"}
Устройство:

– срабатывает openLock();
– ждёт, пока концевик двери покажет открытие;
– отправляет событие DOOR_OPENED.

Позднее можно добавить другие команды:

Код: Выделить всё

{"type":"cmd","cmd":"LOCK"}
{"type":"cmd","cmd":"REBOOT"}
Скетч устройства (основные моменты)

Скетч на ESP32-S3 + SIM7670 (через TinyGSM) делает следующее:

– настраивает APN Билайн;
– поднимает модем и GPRS;
– устанавливает TCP‑соединение с Node‑шлюзом;
– отправляет HELLO сразу после connect;
– периодически шлет ping;
– читает входящие строки JSON и выполняет команды.

Настройки APN под Билайн:

Код: Выделить всё

const char APN[] = "internet.beeline.ru";
const char GPRS_USER[] = "beeline";
const char GPRS_PASS[] = "beeline";
После успешного connectTcp() отправляем HELLO:

Код: Выделить всё

void sendHello() {
String payload = "{";
payload += ""type":"hello",";
payload += ""id":"fridge-123","; // TODO: взять из настроек
payload += ""secret":"ABCDEF123456""; // TODO: взять из настроек
payload += "}\n";
client.print(payload);
}
В loop():

Код: Выделить всё

void loop() {
ensureConnected(); // если TCP отвалился, пробуем пересоздать сеть и коннект

if (client.connected()) {
// Периодический пинг
unsigned long now = millis();
if (now - lastPingMs >= PING_INTERVAL_MS) {
lastPingMs = now;
sendPing(); // JSON: type=ping + телеметрия
}

// Обработка входящих команд
handleIncoming(); // парсит строки JSON, ищет type=cmd, cmd=OPEN и т.п.
}

delay(10);
}
Детали отправки ping и обработки команд можно подгонять под свой формат.

Node‑шлюз: TCP‑сервер + HTTP‑API

Идея: Node‑процесс слушает TCP‑порт для устройств и HTTP‑порт (3005) для WordPress.

4.1. TCP‑сервер (удерживает сокеты устройств)

Псевдокод на Node.js (упрощённый пример):

Код: Выделить всё

const net = require('net');

const socketsById = new Map(); // fridge_id -> socket

const server = net.createServer(socket => {
let buffer = '';

socket.on('data', data => {
buffer += data.toString('utf8');
let index;
while ((index = buffer.indexOf('\n')) >= 0) {
const line = buffer.slice(0, index).trim();
buffer = buffer.slice(index + 1);
if (!line) continue;

try {
const msg = JSON.parse(line);

if (msg.type === 'hello') {
const fridgeId = msg.id;
// TODO: проверить секрет msg.secret по БД или конфигу
socketsById.set(fridgeId, socket);
socket.fridgeId = fridgeId;
socket.write(JSON.stringify({ type: 'hello_ok', mode: 'idle' }) + "\n");
}

if (msg.type === 'ping') {
// обновить телеметрию в БД/кэше
}

if (msg.type === 'event') {
// обработать событие (лог, уведомление, HTTP‑hook в WP и т.д.)
}

} catch (e) {
console.error('Bad JSON from device:', e);
}
}
});

socket.on('close', () => {
if (socket.fridgeId) {
socketsById.delete(socket.fridgeId);
}
});

socket.on('error', err => {
console.error('Socket error:', err);
});
});

server.listen(4000, () => {
console.log('TCP gateway listening on port 4000');
});
4.2. HTTP‑API «открыть холодильник» (для WordPress)

В существующем Express‑API (порт 3005) добавляется endpoint:

Код: Выделить всё

app.post('/open', (req, res) => {
const apiKey = req.header('X-API-Key') || req.query.api_key;
if (apiKey !== 'gsm-secret-key-2026') {
return res.status(403).json({ error: 'forbidden' });
}

const fridgeId = req.body.fridge_id || req.query.fridge_id;
if (!fridgeId) {
return res.status(400).json({ error: 'fridge_id required' });
}

const socket = socketsById.get(fridgeId);
if (!socket) {
return res.status(503).json({ error: 'device_offline' });
}

const cmd = JSON.stringify({ type: 'cmd', cmd: 'OPEN' }) + "\n";
socket.write(cmd);

res.json({ status: 'queued' });
});
Теперь любая система (в том числе WordPress) может сделать:

– POST http://localhost:3005/open
– Заголовок X-API-Key: gsm-secret-key-2026
– Тело: fridge_id=fridge-123

Node‑шлюз найдёт сокет холодильника и отправит ему команду OPEN по TCP.

Интеграция с WordPress

В плагине stolovka-fridges-gateway.php:

– Кнопка «Открыть холодильник» в админке вызывает REST‑handler плагина.
– Этот handler делает внутренний HTTP‑запрос к Node‑шлюзу.

Примерно так:

Код: Выделить всё

$response = wp_remote_post('http://localhost:3005/open', [
'headers' => [
'X-API-Key' => 'gsm-secret-key-2026',
],
'body' => [
'fridge_id' => $fridge_id, // ID устройства, привязанное к записи/терминалу
],
]);

if (is_wp_error($response)) {
// обработать ошибку
}
Node‑шлюз дальше сам общается с устройством по TCP.

Вывод

– Для мгновенных команд и большого количества устройств (холодильников) постоянное TCP‑соединение + отдельный Node‑шлюз – нормальная и правильная архитектура.
– WordPress в такой схеме работает только с HTTP API Node‑шлюза, не общаясь напрямую с железом.
– Устройство (ESP32-S3 + SIM7670) остаётся максимально простым: TCP‑клиент, который шлет HELLO, pинг и события, и выполняет команды, приходящие от Node‑шлюза.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 08 май 2026, 09:14
MarkT
Контроллер в собранном виде:

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 08 май 2026, 12:35
MarkT
Ну.... С первым коннектом!!! ;)
Оператор мегафон.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 09 май 2026, 17:09
MarkT
Спустя сутки после первого коннекта, было принято решение немного изменить структуру железа по связи. Об это расскажем немного позднее и после того, как будем уже обкатываться на прототипе.
Т.е. новая схема железа будет входить уже в рабочую (боевую) модель.
Основной причиной введением новой схемы стало глобальное отключение интернета (по белым спискам). В случае отсутствия оного команды на устройство будут приходить через CMC сообщения. Так же будут приходить критические предупреждения на сервер о слишком высокой температуре в холодильнике, отсутствии питания холодильника, долго открытой двери. Это критические показатели, при которых эксплуатация холодильника с продукцией внутри недопустима.
На текущий момент идет работа над сценариями и логикой работы данного канала.

Re: Умный фуд‑вендинг: от железа до оплаты

Добавлено: 12 май 2026, 01:27
MarkT
За несколько дней эволюционировал от ардуино нано к живому умному холодильнику на ESP32 - и всё это ради одного честного моргнувшего светодиода на плате

За последние дни был небольшой, но показательный эволюционный путь железа и софта - от «давайте прикрутим ардуино нано и реле» до нормальной архитектуры с ESP32-S3 - 4G модемом - Node-шлюзом - WordPress-плагином и фронтендом на сайте.

Из железа в итоге выбрал связку:
  • контроллер на базе ESP32-S3
  • 4G модем (SIM7670 / A7670 класс)
  • питание и обвязка под холодильник
Ардуино нано по дороге естественным образом отсеялась - слишком мало ресурсов и слишком много костылей ради сетевого стека.

Со стороны сервера родился отдельный Node.js-шлюз - который:
  • принимает HTTP-запросы от сайта
  • общается с железом по своему протоколу
  • публикует команды открытия через MQTT / TCP (внутренности можно менять, фронту всё равно)
Изначально была идея «постучаться в железку напрямую» - но в процессе стало понятно, что нужен отдельный слой - единая точка входа для всех холодильников - логирование - безопасность и нормальный API.

Что сделано на стороне сайта

Параллельно пришлось приручить фронт:
  • сделан отдельный плагин «шлюза холодильников» на WordPress
  • в нём таблица холодильников с их ID - статусами - последним контактом и т.д.
  • у каждого холодильника есть свой fridge_id вида sh52001 (буквенный префикс + номер)
  • эти ID живут в базе и используются как ключи во всей системе
Для доступа с фронта реализована простая, но рабочая модель:

есть специальная ссылка формата:
  • домен/?fridge_id=sh52001
При заходе по такой ссылке плагин:
  • проверяет, что fridge_id валидный (регулярка типа буквы+цифры)
  • проверяет наличие такого холодильника в базе
если всё ок - заводит сессию холодильника и кладёт в cookie:
  • текущий fridge_id
  • время жизни сессии
делает редирект на страницу вида:
/sh52001/
Если fridge_id кривой или холодильника нет в базе:
  • рендерится аккуратное сообщение «Неверная ссылка на холодильник - попробуйте отсканировать QR-код ещё раз или обратитесь к сотруднику»
Так добились двух вещей:
  • QR-код является условным «ключом» - без него сессия холодильника не заведётся
  • сама страница /sh52001/ не содержит в себе секретов - она просто оболочка для UI и знает fridge_id через сессию - а не из URL
Кнопка «Открыть холодильник» и фронтенд

Для фронта сделан отдельный плагин плавающей кнопки. Он рендерит модуль вида:
  • div class="fridge-module fridge-module--idle" data-fridge-id="sh52001"
  • button ОТКРЫТЬ ХОЛОДИЛЬНИК
  • div для статусов
Ключевая идея - холодильник не знает сам про себя ничего - всё завязано на fridge_id - который плагин получает из сессии шлюза:

Основная логика берётся из функции sfg_get_current_fridge_id() шлюзового плагина - она:
  • читает fridge_id из cookies / сессии
  • валидирует его
  • при проблемах возвращает пустую строку - а на фронте уже показываем «Неверная ссылка»
JS-код кнопки тоже пришлось довести до ума. В итоге он делает:
  • считывает fridge_id из data-fridge-id
если fridgeId пустой - пишет:
  • «Неверная ссылка - отсканируйте QR-код ещё раз» и никуда не стучится
если ID есть - отправляет AJAX на REST-эндпоинт WordPress:
  • POST /wp-json/sfg/v1/open
  • тело - { fridge_id: 'sh52001' }

На ответ «ok» от REST меняем подпись кнопки и состояние модуля - дальше уже подключается логика «сканирования товаров», но это отдельная тема.

Связка WordPress → Node-шлюз

REST-контроллер в плагине шлюза реализует маршрут /sfg/v1/open. Внутри он:
  • принимает fridge_id из POST
  • валидирует по БД (есть ли такой холодильник)
  • и только после этого стучится в Node-шлюз
Дальше WordPress:
  • проверяет, что wp_remote_post отработал без ошибок
  • проверяет, что Node вернул JSON со статусом ok
  • и уже этот статус отдаёт фронту
Сначала был оставлен старый порт, и в логах красовалось:
  • cURL error 7 - Failed to connect to localhost port 3005
После смены на 4000 всё поехало - тот самый «Node gateway request failed» оказался обычной ошибкой порта.

Node-шлюз и команда OPEN

На стороне Node в итоге получился простой HTTP-обработчик:
  • принимает POST /api/fridge/open
  • проверяет X-API-Key
  • парсит fridge_id
  • публикует команду для конкретного холодильника - через MQTT или TCP-сокет
  • возвращает JSON вида:

Код: Выделить всё

{ "status": "ok", "fridge_id": "sh52001", "message": "Fridge MQTT command published" }
Эту часть отладил сначала через curl с сервера:

Код: Выделить всё

curl -X POST -H "X-API-Key: ..." -d "fridge_id=sh52001" http - 127.0.0.1 - 4000 - api - fridge - open
Когда curl стабильно начал возвращать status ok - стало ясно, что дальше надо просто заставить WordPress дергать тот же URL с теми же параметрами.

ESP32 - и зачем всё это было

Самое вкусное в этой истории - финальная проверка. На плате ESP32-S3 с модемом поднимается прошивка - которая:
  • держит связь с сервером
  • принимает команду OPEN для конкретного fridge_id
и на неё реагирует:
  • мигает светодиодом
  • дёргает пин реле (в боевом варианте)
На момент написания этого поста итог всей многодневной архитектуры выглядел так:
  • сканируем QR-код на холодильнике
  • открывается фронтенд
  • жмём «ОТКРЫТЬ ХОЛОДИЛЬНИК»
  • WordPress отправляет REST-запрос на Node
  • Node публикует команду OPEN
  • ESP32 получает её - и честно моргает светодиодом на плате
То есть весь стек:
  • QR-код
  • сессия холодильника
  • WordPress-плагин (сессии - БД - REST)
  • фронтовая кнопка
  • Node-шлюз
  • ESP32 + 4G модем
— пока приводит к одному визуальному эффекту - «моргнул LED».

Вывод

В процессе стало ясно несколько вещей:
  • правильнее сразу проектировать архитектуру с отдельным шлюзом между сайтом и железом - а не пытаться «допилить» ардуино нано и прямые запросы
  • WordPress как фронт и панель управления отлично уживается с Node-шлюзом и ESP32 - если всё общается через нормальный HTTP API
  • очень легко залипнуть в дебаге там - где виноват один порт или пустой data-fridge-id
Зато теперь:
  • есть готовый каркас для масштабирования на десятки - сотни холодильников
  • есть понятный протокол от фронта до железа
  • и есть честно заработанный моргнувший светодиод - как символ того, что цепочка «клиент у холодильника → сайт → сервер → железо» реально замкнулась