Newer
Older
smart-home-server / docs / control-scripts-guide.md

Руководство по написанию Control Scripts

Control Scripts — это PHP-классы автоматизации, живущие в server/ControlScripts/Scopes/. Все файлы в этой папке загружаются автоматически при старте сервера.


Структура класса

<?php

namespace ControlScripts\Scopes;

use \SHServ\Entities\Device;

class MyScope extends \SHServ\Middleware\ControlScripts 
              implements \SHServ\Implements\ControlScriptsInterface {

    // Объявить связи relay <-> button для синхронизации индикаторов
    public function register_sync_map(): void { }

    // Подписаться на события от устройств
    public function register_events_handlers(): void { }

    // Зарегистрировать action-скрипты (запуск вручную через UI/API)
    public function register_actions_scripts(): void { }

    // Зарегистрировать regular-скрипты (запуск по cron)
    public function register_regular_scripts(): void { }
}

Action-скрипты

Запускаются вручную через POST /api/v1/scripts/actions/run или из UI.

$this->add_action_script([
    "alias"       => "kitchen_light_toggle",   // уникальный alias
    "name"        => "Свет на кухне",
    "icon"        => '<i class="ph ph-lightbulb"></i>',  // Phosphor Icons
    "description" => "Включить/выключить основной свет",
    "author"      => "Eugene Sukhodolskiy"
], function($params) {
    $relay_api = $this->devices()->by_alias("kitchen_relay")->device_api();

    if ($relay_api instanceof \SHServ\Tools\DeviceAPI\Relay) {
        $relay_api->toggle_channel(0);
    }

    return ["result" => true];
});

Включение/выключение конкретного action-скрипта:

  • GET /api/v1/scripts/actions/alias/{alias}/enable
  • GET /api/v1/scripts/actions/alias/{alias}/disable

Regular-скрипты

Запускаются периодически через cron: GET /cron/regular-scripts.

$this->add_regular_script([
    "alias" => "check_door_sensor",
    "name"  => "Проверка датчика двери",
], function() {
    $sensor = $this->devices()->by_alias("door_sensor");
    // ...
});

Включение/выключение:

  • GET /api/v1/scripts/actions/regular/{alias}/enable
  • GET /api/v1/scripts/actions/regular/{alias}/disable

Event-хендлеры

Подписка на события от устройств. Обработчик вызывается после ответа устройству (через fastcgi_finish_request), поэтому может занимать время.

// Нажатие кнопки (канал 0) конкретного устройства
$this->add_event_handler("button@my_btns(0).press", function(Device $device, array $data) {
    $relay = $this->devices()->by_alias("my_relay");
    $relay->device_api()->toggle_channel(0);
});

// Приход устройства онлайн
$this->add_event_handler("button@my_btns.online", function(Device $device, array $data) {
    // синхронизировать индикаторы
    $this->helper()->sync_btn_channels($this->sync_map(), $device->alias);
});

Паттерны имён событий

Паттерн Пример Когда срабатывает
{event_name} button_press Любое устройство, любое событие с таким именем
{type}.{event_name} button.button_press Все устройства типа button
{type}@{alias}.{event_name} button@kitchen_btns.online Конкретное устройство
{type}({ch}).{event_name} button(2).button_press Все устройства типа, канал 2
{type}@{alias}({ch}).{event_name} button@kitchen_btns(2).button_press Конкретное устройство, канал 2

Известные event_name (от устройств)

Устройство event_name Описание
button press Нажатие кнопки
button online Устройство вышло в сеть
relay limit_switch_activated Сработал концевик
hatch limit_switch_activated Сработал концевик закрытия
hatch calibration_failed Не удалась калибровка
sensor presence_changed Изменение присутствия в помещении

Sync map

Описывает связи «какой канал реле ↔ какие каналы кнопок». Используется для автоматической синхронизации индикаторов кнопок с состоянием реле.

public function register_sync_map(): void {
    $this->add_sync_connection([
        ["type" => "relay",  "alias" => "kitchen_relay", "channel" => 0],
        ["type" => "button", "alias" => "kitchen_btns",  "channel" => 1],
        ["type" => "button", "alias" => "hall_btns",     "channel" => 0],
    ]);
}

Первый элемент в массиве — обычно реле (источник состояния). Остальные — кнопки, чьи индикаторы синхронизируются.

Хелперы синхронизации

// При нажатии кнопки — переключить реле и синхронизировать все кнопки
$relay_api->toggle_channel($relay_channel);
$this->helper()->sync_relay_to_btns($this->sync_map(), $relay_alias);

// При появлении кнопки онлайн — синхронизировать её индикаторы с реле
$this->helper()->sync_btn_channels($this->sync_map(), $btn_alias);

Доступные методы базового класса

$this->devices()         // → Models\Devices (поиск по alias, id, hard_id)
$this->helper()          // → DeviceScriptsHelper (синхронизация)
$this->sync_map()        // → текущий sync_map_storage
$this->add_event_handler($name, $cb)
$this->add_action_script($attrs, $cb)
$this->add_regular_script($attrs, $cb)
$this->add_sync_connection($entries)

Управление Scope через API

Включение/выключение целого Scope (всех его скриптов):

  • GET /api/v1/scripts/actions/scope/{name}/enable
  • GET /api/v1/scripts/actions/scope/{name}/disable

Scope отключается через БД — при следующем запуске сервера его скрипты не зарегистрируются.


Общий trait Common

server/ControlScripts/Common.php — trait с готовыми хелперами для Scope-классов:

use \ControlScripts\Common;

// Зарегистрировать глобальный sync_map (все реле и кнопки системы)
$this->register_global_device_sync_map();

// Установить индикаторы заглушённых каналов при появлении кнопки онлайн
$this->btn_on_online("my_btns", [/* muted channels */]);

// Установить обработчики нажатий для кнопок из sync_map
$this->set_btns_click_handlers("my_btns");