Если вы строите свой умный дом на Raspberry Pi с MQTT и PHP, рано или поздно вам понадобится не просто создавать правила автоматизации, а редактировать их из браузера. Кажется, что достаточно добавить ссылку «Редактировать» и подставить данные в форму — но на практике всё ломается: скрипты не запускаются, данные не сохраняются, а JS выдаёт «Unexpected token».
Рассказываю, как сделать это надёжно, без костылей и с поддержкой сложных условий (включая JS-скрипты и расписания).
Правило автоматизации — это не просто «если температура > 25, включи свет». Это:
Поэтому таблица в MySQL должна включать все поля:
CREATE TABLE automations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
condition_type ENUM('simple','script') NOT NULL DEFAULT 'simple',
trigger_topic VARCHAR(255) NOT NULL,
condition_operator ENUM('>', '<', '==', ...) NOT NULL,
condition_value VARCHAR(50) NOT NULL,
condition_script TEXT NULL, -- ← КЛЮЧЕВОЕ ПОЛЕ!
condition_duration INT DEFAULT 0,
action_topic VARCHAR(255) NOT NULL,
action_payload TEXT NOT NULL,
schedule_type ENUM('none','daily','weekly') DEFAULT 'none',
schedule_time TIME NULL,
schedule_days SET('mon','tue',...) DEFAULT NULL,
dependency_topic VARCHAR(255) NULL,
dependency_value VARCHAR(50) NULL,
enabled TINYINT(1) DEFAULT 1,
persistent TINYINT(1) DEFAULT 0,
...
) ENGINE=InnoDB;
❗ Ошибка №1: забыли condition_script. Тогда при INSERT/UPDATE — ошибка «Unknown column».
Вы добавили condition_type, но не добавили condition_script в вызов fillForm(). Результат: action_topic получает значение condition_duration (число), а action_payload — вообще что-то не то.
Если в action_payload есть {"state": "ON"}, то при вставке в onclick без экранирования получается:
<a onclick="fillForm(..., "{\"state\": \"ON\"}", ...)">Ред.</a>
Браузер видит "{\" — и думает, что строка закончилась. Ошибка: Unexpected string.
Решение:
<?= htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8') ?>
Если PHP выдаёт ошибку до тега <script>, страница обрывается — и fillForm не определена.
Включайте отладку:
error_reporting(E_ALL);
ini_set('display_errors', 1);
И смотрите логи: tail -f /var/log/apache2/error.log.
В цикле вывода правил:
<a href="#" onclick="fillForm(
<?= htmlspecialchars(json_encode($rule['name']), ENT_QUOTES, 'UTF-8') ?>,
<?= htmlspecialchars(json_encode($rule['condition_type']), ENT_QUOTES, 'UTF-8') ?>,
<?= htmlspecialchars(json_encode($rule['trigger_topic']), ENT_QUOTES, 'UTF-8') ?>,
<?= htmlspecialchars(json_encode($rule['condition_operator']), ENT_QUOTES, 'UTF-8') ?>,
<?= htmlspecialchars(json_encode($rule['condition_value']), ENT_QUOTES, 'UTF-8') ?>,
<?= htmlspecialchars(json_encode($rule['condition_script'] ?? ''), ENT_QUOTES, 'UTF-8') ?>,
<?= (int)$rule['condition_duration'] ?>,
<?= htmlspecialchars(json_encode($rule['action_topic']), ENT_QUOTES, 'UTF-8') ?>,
<?= htmlspecialchars(json_encode($rule['action_payload']), ENT_QUOTES, 'UTF-8') ?>,
/* ... остальные поля ... */
<?= (int)$rule['id'] ?>
)">✏️ Ред.</a>
А в JS — чёткое соответствие аргументов:
function fillForm(
name, condition_type, trigger_topic, condition_operator, condition_value, condition_script,
condition_duration,
action_topic, action_payload, confirmation_topic, confirmation_timeout, max_retries, retry_delay,
delay_seconds, schedule_type, schedule_time, schedule_days_str, time_restriction_start, time_restriction_end,
dependency_topic, dependency_value, enabled, id
) {
document.querySelector("[name='name']").value = name;
document.querySelector("[name='condition_type']").value = condition_type;
document.querySelector("[name='condition_script']").value = condition_script;
// ... и так далее ...
document.getElementById('rule_id').value = id;
}
Если вам не нравится возиться с JS — сделайте edit_rule.php?id=123. Там:
$rule = $pdo->prepare("SELECT * FROM automations WHERE id = ?");
$rule->execute([$_GET['id']]);
$rule = $rule->fetch();
// Подставляете $rule['name'] прямо в value="" — никаких JSON/JS!
Это проще, безопаснее и не ломается при спецсимволах.
Редактирование — это не «просто форма». Это баланс между:
Теперь ваши правила можно не только создавать, но и менять на лету — без перезагрузки сервера и без SSH.
Удачи в автоматизации! 🏠⚡
Обновленный скрипт добавления правил для автоматизации logic.php
Блог только запустил, все статьи генерирую через нейросеть т.к. лень, возможны ошибки. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.
Комментарии
Пока нет комментариев. Будьте первым!