Modules/devices/devices links actions inc php
Материал из MajorDoMo инфо
ᐂ В корневой раздел ᐃ В директорию расположения файла
<?php
// Начинаем измерение времени выполнения функции homebridge_update
startMeasure('homebridge_update');
// Переменная для отладки синхронизации, инициализируется значением 0
$debug_sync = 0;
// Проверяем, не является ли устройство системным, не архивировано ли оно и доступен ли HomeBridge
if (!$device1['SYSTEM_DEVICE'] && !$device1['ARCHIVED'] && $this->isHomeBridgeAvailable()) {
// Отправляем обновленный статус в HomeKit
require DIR_MODULES . 'devices/homebridgeSendUpdate.inc.php';
}
endMeasure('homebridge_update');
// Начинаем измерение времени выполнения функции checkingLinks
startMeasure('checkingLinks');
// Получаем значение связанного объекта и преобразуем его в число с плавающей точкой
$value = (float)gg($device1['LINKED_OBJECT'] . '.value');
// Получаем статус связанного объекта и преобразуем его в число с плавающей точкой
$status = (float)gg($device1['LINKED_OBJECT'] . '.status');
// Выполняем SQL-запрос для получения связанных устройств
$links = SQLSelect("SELECT devices_linked.*, devices.LINKED_OBJECT FROM devices_linked LEFT JOIN devices ON devices_linked.DEVICE2_ID=devices.ID WHERE devices_linked.IS_ACTIVE=1 AND DEVICE1_ID=" . (int)$device1['ID']);
// Подсчитываем общее количество связанных устройств
$total = count($links);
// Начинаем цикл по всем связанным устройствам
for ($i = 0; $i < $total; $i++) {
// Проверяем доступ к устройству
if (!checkAccess('sdevice', $links[$i]['ID'])) continue;
// Получаем тип связи
$link_type = $links[$i]['LINK_TYPE'];
// Десериализуем настройки связи
$settings = unserialize($links[$i]['LINK_SETTINGS']);
if ($device1['TYPE'] == 'button' && !$status) continue;
if ($device1['TYPE'] == 'motion' && $settings['action_type'] != 'sync' && $settings['action_type'] != 'sync_inverted' && !$status) continue;
$object = $links[$i]['LINKED_OBJECT'];
// Формируем имя таймера
$timer_name = 'linkTimer' . $links[$i]['ID'];
// Инициализируем строку для действия
$action_string = '';
// -----------------------------------------------------------------
// Проверяем тип связи
if ($link_type == 'switch_it') {
// Формируем строку действия в зависимости от типа действия
if ($settings['action_type'] == 'turnoff') {
// Выключаем объект
$action_string = 'callMethodSafe("' . $object . '.turnOff' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} elseif ($settings['action_type'] == 'turnon') {
// Включаем объект
$action_string = 'callMethodSafe("' . $object . '.turnOn' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} elseif ($settings['action_type'] == 'switch') {
// Переключаем объект
$action_string = 'callMethodSafe("' . $object . '.switch' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} elseif ($settings['action_type'] == 'close') {
// Закрываем объект
$action_string = 'callMethodSafe("' . $object . '.close' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} elseif ($settings['action_type'] == 'open') {
// Открываем объект
$action_string = 'callMethodSafe("' . $object . '.open' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} elseif ($settings['action_type'] == 'sync') {
// Синхронизируем статус объекта
if ($status) {
$action_string = 'callMethodSafe("' . $object . '.turnOn' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} else {
$action_string = 'callMethodSafe("' . $object . '.turnOff' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
}
} elseif ($settings['action_type'] == 'sync_inverted') {
// Синхронизируем инвертированный статус объекта
if (!$status) {
$action_string = 'callMethodSafe("' . $object . '.turnOn' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
} else {
$action_string = 'callMethodSafe("' . $object . '.turnOff' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
}
}
// Добавляем задержку, если нужно
if ($settings['action_delay'] != '') {
$settings['action_delay'] = (int)processTitle($settings['action_delay']);
if ($settings['action_delay'] > 0) {
$action_string = 'setTimeout(\'' . $timer_name . '\',\'' . $action_string . '\',' . (int)$settings['action_delay'] . ');';
}
}
} elseif ($link_type == 'switch_timer') {
// Формируем таймерное действие
$timer_name = $object . '_switch_timer';
$action_string = '';
if ($settings['darktime']) {
// проверка активен ли режим DarknessMode
$action_string .= 'if (gg("DarknessMode.active")) {';
}
// включение
$action_string .= 'callMethodSafe("' . $object . '.turnOn' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
if ($settings['action_delay'] != '') {
$settings['action_delay'] = (int)processTitle($settings['action_delay']);
if ($settings['action_delay'] > 0) {
$action_string .= 'setTimeout(\'' . $timer_name . '\',\'' . 'callMethod("' . $object . '.turnOff' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));' . '\',' . (int)$settings['action_delay'] . ');';
}
}
if ($settings['darktime']) {
$action_string .= '}';
}
} elseif ($link_type == 'set_color') {
$action_string = 'callMethodSafe("' . $object . '.setColor' . '",array("color"=>"' . $settings['action_color'] . '","link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
// Добавляем задержку выключения, если нужно
if ($settings['action_delay'] != '') {
$settings['action_delay'] = (int)processTitle($settings['action_delay']);
if ($settings['action_delay'] > 0) {
$action_string = 'setTimeout(\'' . $timer_name . '\',\'' . $action_string . '\',' . (int)$settings['action_delay'] . ');';
}
}
// -----------------------------------------------------------------
// -----------------------------------------------------------------
// Код для обработки действий по типу 'sensor_switch'
} elseif ($link_type == 'sensor_switch') {
// Если тип действия равен 'turnoff' и статус объекта активен, то выключаем объект
if ($settings['action_type'] == 'turnoff' && gg($object . '.status')) {
$action_string = 'callMethodSafe("' . $object . '.turnOff' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
// Если тип действия равен 'turnon' и статус объекта не активен, то включаем объект
} elseif ($settings['action_type'] == 'turnon' && !gg($object . '.status')) {
$action_string = 'callMethodSafe("' . $object . '.turnOn' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
// Если тип действия равен 'open' и статус объекта активен, то открываем объект
} elseif ($settings['action_type'] == 'open' && gg($object . '.status')) {
$action_string = 'callMethodSafe("' . $object . '.open' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
// Если тип действия равен 'close' и статус объекта не активен, то закрываем объект
} elseif ($settings['action_type'] == 'close' && !gg($object . '.status')) {
$action_string = 'callMethodSafe("' . $object . '.close' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
}
// Если указан тип источника значения, то получаем среднее, минимальное или максимальное значение за указанный период
if ($settings['source_value_type'] != '') {
// Преобразуем время периода в целое число
$period = (int)$settings['source_value_time'];
// Если период меньше 1, устанавливаем его равным 1
if ($period < 1) $period = 1;
// Если тип источника значения равен 'avg', получаем среднее значение за указанный период
if ($settings['source_value_type'] == 'avg') {
$value = getHistoryAvg($device1['LINKED_OBJECT'] . '.value', (-1) * $period);
// Если тип источника значения равен 'min', получаем минимальное значение за указанный период
} elseif ($settings['source_value_type'] == 'min') {
$value = getHistoryMin($device1['LINKED_OBJECT'] . '.value', (-1) * $period);
// Если тип источника значения равен 'max', получаем максимальное значение за указанный период
} elseif ($settings['source_value_type'] == 'max') {
$value = getHistoryMax($device1['LINKED_OBJECT'] . '.value', (-1) * $period);
}
}
// Если указан тип условия и значение соответствует условию, то выполняем действие
if ($settings['condition_type'] == 'above' && $value >= (float)$settings['condition_value']) {
// Выполняем действие
} elseif ($settings['condition_type'] == 'below' && $value < (float)$settings['condition_value']) {
// Выполняем действие
} else {
// Если условие не выполняется, то не выполняем действие
$action_string = '';
}
} elseif ($link_type == 'sensor_pass') {
// Код для обработки действий по типу 'sensor_pass'
// Передаем значение объекта
$action_string = 'sg("' . $object . '.value' . '","' . $value . '");';
// Код для обработки действий по типу 'open_sensor_pass'
} elseif ($link_type == 'open_sensor_pass') {
// Передаем статус объекта
$action_string = 'sg("' . $object . '.status' . '","' . $status . '");';
// Код для обработки действий по типу 'thermostat_switch'
} elseif ($link_type == 'thermostat_switch') {
// Определяем значение для установки
$set_value = 0;
// Получаем текущий статус реле
$current_relay_status = gg($device1['LINKED_OBJECT'] . '.relay_status');
// Получаем текущий статус цели
$current_target_status = gg($object . '.status');
// Если нужно инвертировать статус, то инвертируем значение
if ($settings['invert_status']) {
$set_value = $current_relay_status ? 0 : 1;
} else {
$set_value = $current_relay_status;
}
// Если значение установлено и текущий статус цели не активен, то включаем объект
if ($set_value && !$current_target_status) {
$action_string = 'callMethodSafe("' . $object . '.turnOn' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
// Если значение не установлено и текущий статус цели активен, то выключаем объект
} elseif (!$set_value && $current_target_status) {
$action_string = 'callMethodSafe("' . $object . '.turnOff' . '",array("link_source"=>"' . $device1['LINKED_OBJECT'] . '"));';
}
}
// Определяем директорию для дополнений
$addons_dir = dirname(__FILE__) . '/addons';
if (is_dir($addons_dir)) {
// Получаем список файлов в директории дополнений
$addon_files = scandir($addons_dir);
foreach ($addon_files as $file) {
if (preg_match('/\_links_actions\.php$/', $file)) {
// Подключаем дополнительные скрипты для обработки действий
require($addons_dir . '/' . $file);
}
}
}
// -----------------------------------------------------------------
if ($action_string != '') {
//DebMes("Action string: ".$action_string,'logic_test');
try {
$code = $action_string;
// Выполняем код действия
$success = eval($code);
if ($success === false) {
// Регистрируем ошибку, если код выполнился неудачно
registerError('linked_device', sprintf('Error in linked device code "%s". Code: %s', $link_type, $code));
}
} catch (Exception $e) {
// Регистрируем ошибку, если возникло исключение
registerError('linked_device', sprintf('Error in script "%s": ' . $e->getMessage(), $link_type));
}
}
// Завершаем измерение времени выполнения функции checkingLinks
endMeasure('checkingLinks');
}