Modules/devices/processCommand inc php: различия между версиями
Материал из MajorDoMo инфо
Elmax (обсуждение | вклад) (Заготовка) |
Elmax (обсуждение | вклад) (+ файл processCommand.inc.php) |
||
| Строка 3: | Строка 3: | ||
<pre> | <pre> | ||
<?php | |||
// Проверяет, отключены ли простые устройства в файле конфигурации ROOT . config.php. Если да, прекращает выполнение скрипта. | |||
if (defined('DISABLE_SIMPLE_DEVICES') && DISABLE_SIMPLE_DEVICES == 1) return; | |||
/* | |||
* array('level' => $level, 'message' => $ph, 'member_id' => $member_id, 'source' => $source) | |||
* $details['BREAK'] = 1 / 0 | |||
*/ | |||
// Этот блок кода, вероятно, предназначен для обработки лога или отладки, так как он содержит пример использования переменной $details['BREAK']. | |||
// Однако, поскольку он закомментирован, его выполнение в текущем состоянии скрипта не происходит. | |||
// Включаем файлы локализации для текущего языка сайта и по умолчанию. | |||
@include_once(ROOT . 'languages/' . $this->name . '_' . SETTINGS_SITE_LANGUAGE . '.php'); | |||
@include_once(ROOT . 'languages/' . $this->name . '_default' . '.php'); | |||
// Если в деталях команды указано источник (терминал), то получаем информацию о терминале. | |||
if ($details['source']) { | |||
$terminal = getTerminalByID(str_replace("terminal", "", $details['source'])); | |||
// Если у терминала есть ID местоположения, сохраняем его. | |||
if ($terminal['LOCATION_ID']) { | |||
$location_id = $terminal['LOCATION_ID']; | |||
} | |||
} | |||
/* | |||
* Этот фрагмент кода анализирует входящую команду на предмет наличия указаний на задержку выполнения, | |||
* или продолжительность выполнения действия. | |||
* Если такие указания присутствуют, код вычисляет соответствующие значения в секундах | |||
* и сохраняет их в переменных $period_delay и $period_run_for соответственно. | |||
* Также код сохраняет найденное совпадение в переменную $add_phrase, чтобы потом добавить его к сообщению. | |||
*/ | |||
// Получаем текстовую команду из массива $details, который содержит детали сообщения. | |||
$command = $details['message']; | |||
// Инициализируем переменную $run_code как пустую строку. Эта переменная будет использоваться для хранения кода, который нужно выполнить. | |||
$run_code = ''; | |||
// Инициализируем переменную $opposite_code как пустую строку. Эта переменная будет использоваться для хранения кода, который будет выполнен в качестве противодействия к основному коду. | |||
$opposite_code = ''; | |||
// Инициализируем переменную $add_phrase как пустую строку. Эта переменная будет использоваться для хранения дополнительной фразы, которая будет добавлена к сообщению. | |||
$add_phrase = ''; | |||
// Инициализируем переменную $period_delay как 0. Эта переменная будет использоваться для хранения задержки выполнения команды в секундах. | |||
$period_delay = 0; | |||
// Инициализируем переменную $period_run_for как 0. Эта переменная будет использоваться для хранения продолжительности выполнения команды в секундах. | |||
$period_run_for = 0; | |||
// Проверяем, содержит ли команда фразу, указывающую на необходимость выполнения действия после определенного времени. | |||
if (preg_match('/' . LANG_PATTERN_DO_AFTER . ' (\d+?) (' . LANG_PATTERN_SECOND . '|' . LANG_PATTERN_MINUTE . '|' . LANG_PATTERN_HOUR . ')/uis', textToNumbers($command), $m)) { | |||
// Получаем числовое значение времени задержки из найденного совпадения. | |||
$period_number = $m[1]; | |||
// Добавляем найденное совпадение к переменной $add_phrase, чтобы потом добавить его к сообщению. | |||
$add_phrase = ' ' . $m[0]; | |||
// Определяем единицу измерения времени (секунды, минуты, часы) и вычисляем задержку в секундах. | |||
if (preg_match('/' . LANG_PATTERN_SECOND . '/uis', $m[2])) { | |||
// Если единица измерения - секунды, то задержка равна числовому значению. | |||
$period_delay = $period_number; | |||
} elseif (preg_match('/' . LANG_PATTERN_MINUTE . '/uis', $m[2])) { | |||
// Если единица измерения - минуты, то задержка равна числовому значению, умноженному на 60. | |||
$period_delay = $period_number * 60; | |||
} elseif (preg_match('/' . LANG_PATTERN_HOUR . '/uis', $m[2])) { | |||
// Если единица измерения - часы, то задержка равна числовому значению, умноженному на 3600. | |||
$period_delay = $period_number * 60 * 60; | |||
} | |||
// Удаляем обработанную часть команды, чтобы оставить только саму команду без указания времени задержки. | |||
$command = trim(str_replace($m[0], '', textToNumbers($command))); | |||
} elseif (preg_match('/' . LANG_PATTERN_DO_FOR . ' (\d+?) (' . LANG_PATTERN_SECOND . '|' . LANG_PATTERN_MINUTE . '|' . LANG_PATTERN_HOUR . ')/uis', textToNumbers($command), $m)) { | |||
// Получаем числовое значение времени выполнения из найденного совпадения. | |||
$period_number = $m[1]; | |||
// Добавляем найденное совпадение к переменной $add_phrase, чтобы потом добавить его к сообщению. | |||
$add_phrase = ' ' . $m[0]; | |||
// Определяем единицу измерения времени (секунды, минуты, часы) и вычисляем продолжительность выполнения в секундах. | |||
if (preg_match('/' . LANG_PATTERN_SECOND . '/uis', $m[2])) { | |||
// Если единица измерения - секунды, то продолжительность выполнения равна числовому значению. | |||
$period_run_for = $period_number; | |||
} elseif (preg_match('/' . LANG_PATTERN_MINUTE . '/uis', $m[2])) { | |||
// Если единица измерения - минуты, то продолжительность выполнения равна числовому значению, умноженному на 60. | |||
$period_run_for = $period_number * 60; | |||
} elseif (preg_match('/' . LANG_PATTERN_HOUR . '/uis', $m[2])) { | |||
// Если единица измерения - часы, то продолжительность выполнения равна числовому значению, умноженному на 3600. | |||
$period_run_for = $period_number * 60 * 60; | |||
} | |||
// Удаляем обработанную часть команды, чтобы оставить только саму команду без указания времени выполнения. | |||
$command = trim(str_replace($m[0], '', textToNumbers($command))); | |||
} | |||
// Инициализируем переменную $processed как 0. Эта переменная будет использоваться для отслеживания, была ли команда обработана. | |||
$processed = 0; | |||
// Инициализируем переменную $reply_confirm как 0. Эта переменная будет использоваться для подтверждения выполнения команды. | |||
$reply_confirm = 0; | |||
// Инициализируем переменную $reply_say как пустую строку. Эта переменная будет использоваться для хранения сообщения, которое будет отправлено в ответ на команду. | |||
$reply_say = ''; | |||
// Инициализируем переменную $phpmorphy_loaded как 0. Эта переменная будет использоваться для отслеживания, загружена ли библиотека phpMorphy. | |||
$phpmorphy_loaded = 0; | |||
// Проверяем, существует ли файл библиотеки phpMorphy. | |||
if (file_exists(ROOT . "lib/phpmorphy/common.php")) { | |||
// Подключаем файл библиотеки phpMorphy. | |||
require_once(ROOT . "lib/phpmorphy/common.php"); | |||
$opts = array( | |||
// Указываем тип хранения данных. | |||
'storage' => PHPMORPHY_STORAGE_MEM, | |||
// Включаем предсказание по суффиксу. | |||
'predict_by_suffix' => true, | |||
// Включаем предсказание по базе данных. | |||
'predict_by_db' => true, | |||
// Указываем, что грамматическая информация должна быть представлена в виде текста. | |||
'graminfo_as_text' => true, | |||
); | |||
// Указываем путь к словарям phpMorphy. | |||
$dir = ROOT . 'lib/phpmorphy/dicts'; | |||
// Получаем код текущего языка сайта. | |||
$lang = SETTINGS_SITE_LANGUAGE_CODE; | |||
try { | |||
// Создаем экземпляр класса phpMorphy. | |||
$morphy = new phpMorphy($dir, $lang, $opts); | |||
// Сохраняем ссылку на созданный экземпляр в свойстве объекта. | |||
$this->morphy = &$morphy; | |||
} catch (phpMorphy_Exception $e) { | |||
// Выводим сообщение об ошибке и прерываем выполнение скрипта. | |||
die('Error occured while creating phpMorphy instance: ' . PHP_EOL . $e); | |||
} | |||
// Разбиваем команду на слова. | |||
$words = explode(' ', $command); | |||
// Инициализируем массив для хранения отфильтрованных слов. | |||
$words_filtered = array(); | |||
// Инициализируем счетчик отфильтрованных слов. | |||
$filtered_count = 0; | |||
// Инициализируем массив для хранения базовых форм слов. | |||
$base_forms = array(); | |||
// Инициализируем массив для хранения базовых форм отфильтрованных слов. | |||
$base_forms_filtered = array(); | |||
// Получаем общее количество слов в команде. | |||
$totals = count($words); | |||
for ($is = 0; $is < $totals; $is++) { | |||
// Инициализируем переменную для отслеживания, было ли слово фильтровано. | |||
$filtered = 0; | |||
// Преобразуем слово в верхний регистр. | |||
$upper = mb_strtoupper($words[$is], 'UTF-8'); | |||
// Получаем длину слова. | |||
$len = mb_strlen($words[$is], 'UTF-8'); | |||
// Если длина слова больше или равна 3, считаем его достаточно длинным для анализа. | |||
if ($len >= 3) { | |||
// Добавляем слово в массив отфильтрованных слов. | |||
$words_filtered[] = $words[$is]; | |||
// Помечаем слово как отфильтрованное. | |||
$filtered = 1; | |||
// Увеличиваем счетчик отфильтрованных слов. | |||
$filtered_count++; | |||
} | |||
// Если слово является числом, добавляем его в массив базовых форм. | |||
if (preg_match('/^(\d+)$/', $words[$is])) { | |||
$base_forms[$is] = array($words[$is]); | |||
// Если слово не содержит специальных символов, получаем его базовую форму. | |||
} elseif (!preg_match('/[\(\)\+\.]/', $words[$is])) { | |||
// Преобразуем слово в верхний регистр. | |||
$Word = mb_strtoupper($words[$is], 'UTF-8'); | |||
// Получаем базовую форму слова. | |||
$base_forms[$is] = $morphy->getBaseForm($Word); | |||
// Добавляем исходное слово в массив базовых форм. | |||
$base_forms[$is][] = $words[$is]; | |||
// Если слово содержит специальные символы, добавляем его в массив базовых форм без изменений. | |||
} else { | |||
$base_forms[$is] = array($words[$is]); | |||
} | |||
// Если слово было отфильтровано, добавляем его базовую форму в массив отфильтрованных базовых форм. | |||
if ($filtered) { | |||
$base_forms_filtered[$filtered_count - 1] = $base_forms[$is]; | |||
} | |||
} | |||
// Генерируем все возможные комбинации базовых форм слов. | |||
$combos = $this->generate_combinations($base_forms); | |||
// Если количество отфильтрованных слов меньше общего количества слов, генерируем дополнительные комбинации. | |||
if ($filtered_count < $totals) { | |||
// Генерируем комбинации для отфильтрованных базовых форм. | |||
$add_combos = $this->generate_combinations($base_forms_filtered); | |||
// Добавляем каждую сгенерированную комбинацию в общий массив комбинаций. | |||
foreach ($add_combos as $cmb) { | |||
$combos[] = $cmb; | |||
} | |||
} | |||
// Инициализируем массив для хранения строк, полученных из комбинаций. | |||
$lines = array(); | |||
// Получаем общее количество комбинаций. | |||
$totals = count($combos); | |||
// Преобразуем каждую комбинацию в строку и добавляем ее в массив строк. | |||
for ($is = 0; $is < $totals; $is++) { | |||
$lines[] = implode(' ', $combos[$is]); | |||
} | |||
// Помечаем, что библиотека phpMorphy была успешно загружена. | |||
$phpmorphy_loaded = 1; | |||
} | |||
// Получаем список устройств из базы данных. | |||
$devices = SQLSelect("SELECT ID, TITLE, ALT_TITLES, TYPE, LINKED_OBJECT, LOCATION_ID FROM devices"); | |||
// Проходим по каждому устройству в полученном списке. | |||
foreach ($devices as $device) { | |||
// Если у устройства есть альтернативные названия. | |||
if (trim($device['ALT_TITLES']) != '') { | |||
// Разбиваем альтернативные названия по запятой. | |||
$nicknames = explode(',', trim($device['ALT_TITLES'])); | |||
// Проходим по каждому альтернативному названию. | |||
foreach ($nicknames as $nickname) { | |||
// Копируем текущее устройство. | |||
$add_rec = $device; | |||
// Заменяем название устройства на альтернативное. | |||
$add_rec['TITLE'] = $nickname; | |||
// Добавляем измененное устройство обратно в список устройств. | |||
$devices[] = $add_rec; | |||
} | |||
} | |||
} | |||
// Получаем список групп устройств из базы данных. | |||
$groups = SQLSelect("SELECT * FROM devices_groups"); | |||
// Получаем общее количество групп. | |||
$total = count($groups); | |||
// Проходим по каждой группе в полученном списке. | |||
for ($i = 0; $i < $total; $i++) { | |||
// Копируем текущую группу. | |||
$add_rec = $groups[$i]; | |||
// Устанавливаем тип группы как 'group'. | |||
$add_rec['TYPE'] = 'group'; | |||
// Добавляем группу обратно в список устройств. | |||
$devices[] = $add_rec; | |||
} | |||
// Получаем список комнат с устройствами из базы данных. | |||
$rooms = SQLSelect("SELECT locations.ID, locations.TITLE, COUNT(*) AS TOTAL FROM locations, devices WHERE locations.ID=devices.LOCATION_ID GROUP BY locations.ID"); | |||
// Проходим по каждой комнате в полученном списке. | |||
foreach ($rooms as $room) { | |||
//lights | |||
//if ($room['TITLE']=='Кабинет') { | |||
// Инициализируем массив для хранения типов устройств в комнате. | |||
$device_types = array(); | |||
// Получаем список устройств типа 'relay' в текущей комнате. | |||
$room_devices = SQLSelect("SELECT * FROM devices WHERE LOCATION_ID=" . $room['ID'] . " AND TYPE='relay'"); | |||
// Проходим по каждому устройству в полученном списке. | |||
foreach ($room_devices as $device) { | |||
// Получаем тип нагрузки устройства. | |||
$loadType = gg($device['LINKED_OBJECT'] . '.loadType'); | |||
// Добавляем устройство в массив типов устройств. | |||
$device_types[$loadType][] = $device; | |||
} | |||
// Если в комнате есть устройства типа 'light'. | |||
if (isset($device_types['light'])) { | |||
// Инициализируем массив для новой группы устройств. | |||
$add_rec = array(); | |||
// Устанавливаем тип группы как 'group'. | |||
$add_rec['TYPE'] = 'group'; | |||
// Устанавливаем название группы. | |||
$add_rec['TITLE'] = LANG_DEVICES_LOADTYPE_LIGHT . ' ' . $room['TITLE']; | |||
// Добавляем устройства типа 'light' в группу. | |||
$add_rec['DEVICES'] = $device_types['light']; | |||
// Устанавливаем типы применения группы. | |||
$add_rec['APPLY_TYPES'] = 'relay'; | |||
// Добавляем группу обратно в список устройств. | |||
$devices[] = $add_rec; | |||
// Инициализируем массив для новой группы устройств. | |||
$add_rec = array(); | |||
// Устанавливаем тип группы как 'group'. | |||
$add_rec['TYPE'] = 'group'; | |||
// Устанавливаем альтернативное название группы. | |||
$add_rec['TITLE'] = LANG_DEVICES_LOADTYPE_LIGHT_ALT . ' ' . $room['TITLE']; | |||
// Добавляем устройства типа 'light' в группу. | |||
$add_rec['DEVICES'] = $device_types['light']; | |||
// Устанавливаем типы применения группы. | |||
$add_rec['APPLY_TYPES'] = 'relay'; | |||
// Добавляем группу обратно в список устройств. | |||
$devices[] = $add_rec; | |||
} | |||
//} | |||
} | |||
// Если библиотека phpMorphy была успешно загружена. | |||
if ($phpmorphy_loaded) { | |||
// Получаем общее количество устройств. | |||
$total = count($devices); | |||
// Инициализируем массив для хранения дополнительных устройств. | |||
$add_devices = array(); | |||
// Проходим по каждому устройству в полученном списке. | |||
for ($i = 0; $i < $total; $i++) { | |||
// Получаем название устройства. | |||
$device_title = $devices[$i]['TITLE']; | |||
// Разбиваем название устройства на слова и преобразуем их в верхний регистр. | |||
$words = explode(' ', mb_strtoupper($device_title, 'UTF-8')); | |||
// Инициализируем массив для хранения базовых форм слов. | |||
$base_forms = array(); | |||
// Получаем общее количество слов. | |||
$totals = count($words); | |||
// Проходим по каждому слову в полученном списке. | |||
for ($is = 0; $is < $totals; $is++) { | |||
// Если слово является числом, добавляем его в массив базовых форм. | |||
if (preg_match('/^(\d+)$/', $words[$is])) { | |||
$base_forms[$is] = array($words[$is]); | |||
// Если слово не содержит специальных символов, получаем его базовую форму. | |||
} elseif (!preg_match('/[\(\)\+\.]/', $words[$is])) { | |||
// Преобразуем слово в верхний регистр. | |||
$Word = mb_strtoupper($words[$is], 'UTF-8'); | |||
// Получаем базовую форму слова. | |||
$base_form = $morphy->getBaseForm($Word); | |||
// Если базовая форма представлена в виде массива. | |||
if (is_array($base_form)) { | |||
$base_forms[$is] = $base_form; | |||
// Если базовая форма не представлена в виде массива. | |||
} else { | |||
$base_forms[$is] = array(); | |||
} | |||
// Если исходное слово не содержится в массиве базовых форм. | |||
if (!in_array($words[$is], $base_forms[$is])) { | |||
// Добавляем исходное слово в массив базовых форм. | |||
$base_forms[$is][] = $words[$is]; | |||
} | |||
// Если слово содержит специальные символы, добавляем его в массив базовых форм без изменений. | |||
} else { | |||
$base_forms[$is] = array($words[$is]); | |||
} | |||
} | |||
// Генерируем все возможные комбинации базовых форм слов. | |||
$combos = $this->generate_combinations($base_forms); | |||
// Инициализируем массив для хранения фраз, полученных из комбинаций. | |||
$phrases = array(); | |||
// Проходим по каждой комбинации в полученном списке. | |||
foreach ($combos as $combo) { | |||
// Вычисляем все возможные перестановки для текущей комбинации. | |||
$mutations = $this->computePermutations($combo); | |||
// Проходим по каждой перестановке в полученном списке. | |||
foreach ($mutations as $m) { | |||
// Преобразуем каждую перестановку в строку и добавляем ее в массив фраз. | |||
$phrases[] = implode(' ', $m); | |||
} | |||
} | |||
// Инициализируем массив для хранения новых названий устройств. | |||
$device_titles = array(); | |||
// Получаем общее количество фраз. | |||
$totals = count($phrases); | |||
// Проходим по каждой фразе в полученном списке. | |||
for ($is = 0; $is < $totals; $is++) { | |||
// Получаем новое название устройства. | |||
$new_title = $phrases[$is]; | |||
// Добавляем новое название устройства в массив новых названий. | |||
$device_titles[] = $new_title; | |||
// Копируем текущее устройство. | |||
$new_device = $devices[$i]; | |||
// Заменяем название устройства на новое. | |||
$new_device['TITLE'] = $new_title; | |||
// Сохраняем оригинальное название устройства. | |||
$new_device['ORIGINAL_TITLE'] = $device_title; | |||
// Добавляем измененное устройство в массив дополнительных устройств. | |||
$add_devices[] = $new_device; | |||
} | |||
} | |||
// Проходим по каждому устройству в массиве дополнительных устройств. | |||
foreach ($add_devices as $device) { | |||
// Добавляем устройство обратно в список устройств. | |||
$devices[] = $device; | |||
} | |||
} | |||
// Выводим содержимое переменной $lines для отладки. | |||
//dprint($lines,false); | |||
// Выводим содержимое переменной $devices для отладки. | |||
//dprint($devices); | |||
// Инициализируем переменную $compare_title командой. | |||
$compare_title = $command; | |||
// Проверяем, содержит ли команда фразу, указывающую на необходимость включения устройства. | |||
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNON . '/uis', $compare_title, $m)) { | |||
// Если да, удаляем эту фразу из команды. | |||
$compare_title = trim(str_replace($m[0], ' ', $compare_title)); | |||
} | |||
// Проверяем, содержит ли команда фразу, указывающую на необходимость выключения устройства. | |||
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNOFF . '/uis', $compare_title, $m)) { | |||
// Если да, удаляем эту фразу из команды. | |||
$compare_title = trim(str_replace($m[0], ' ', $compare_title)); | |||
} | |||
// Удаляем начальные слова "ть" и "те" из команды, если они присутствуют. | |||
$compare_title = trim(preg_replace('/^ть /', '', $compare_title)); | |||
$compare_title = trim(preg_replace('/^те /', '', $compare_title)); | |||
// Если после всех преобразований команда стала пустой, прекращаем выполнение скрипта. | |||
if ($compare_title == '') { | |||
return; | |||
} | |||
// Получаем общее количество устройств. | |||
$total = count($devices); | |||
// Проходим по каждому устройству в полученном списке. | |||
for ($i = 0; $i < $total; $i++) { | |||
// Инициализируем переменную для отслеживания, было ли найдено соответствие устройства. | |||
$device_matched = 0; | |||
// Если указано местоположение терминала. | |||
if ($location_id) { | |||
// Ищем строгое соответствие по названию и местоположению. | |||
foreach ($devices as $key => $value) { | |||
// Если ID местоположения устройства совпадает с ID местоположения терминала и название устройства совпадает с командой. | |||
if (in_array($location_id, $value) && strtolower($devices[$key]['TITLE']) == strtolower($compare_title)) { | |||
// Обновляем индекс текущего устройства. | |||
$i = $key; | |||
// Помечаем, что устройство найдено. | |||
$device_matched = 1; | |||
// Прерываем цикл. | |||
break; | |||
} | |||
} | |||
// Если устройство не найдено. | |||
if (!$device_matched) { | |||
// Ищем строгое соответствие по названию. | |||
foreach ($devices as $key => $value) { | |||
// Если название устройства совпадает с командой. | |||
if (in_array(strtolower($compare_title), strtolower($value))) { | |||
// Обновляем индекс текущего устройства. | |||
$i = $key; | |||
// Помечаем, что устройство найдено. | |||
$device_matched = 1; | |||
// Прерываем цикл. | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
// Ищем по старому принципу. | |||
if (preg_match('/' . preg_quote($devices[$i]['TITLE']) . '/uis', $compare_title)) { | |||
// Помечаем, что устройство найдено. | |||
$device_matched = 1; | |||
} elseif (preg_match('/' . preg_quote($compare_title) . '/uis', $devices[$i]['TITLE'])) { | |||
// Помечаем, что устройство найдено. | |||
$device_matched = 1; | |||
// Если библиотека phpMorphy была успешно загружена. | |||
} elseif ($phpmorphy_loaded) { | |||
if (preg_match('/' . preg_quote($devices[$i]['TITLE']) . '/isu', implode('@@@@', $lines), $matches)) { | |||
// Помечаем, что устройство найдено. | |||
$device_matched = 1; | |||
} | |||
} | |||
/* | |||
if (preg_match('/свет над столом/uis',$devices[$i]['TITLE'])) { | |||
dprint($devices[$i]['TITLE'].' - '.$compare_title.': '.$device_matched); | |||
} | |||
*/ | |||
// Если устройство было найдено. | |||
if ($device_matched) { | |||
// Найдено устройство. | |||
// Получаем ID устройства. | |||
$device_id = $devices[$i]['ID']; | |||
// Получаем тип устройства. | |||
$device_type = $devices[$i]['TYPE']; | |||
// Если у устройства есть оригинальное название. | |||
if ($devices[$i]['ORIGINAL_TITLE'] != '') { | |||
// Используем оригинальное название. | |||
$device_title = $devices[$i]['ORIGINAL_TITLE']; | |||
// Если оригинального названия нет. | |||
} else { | |||
// Используем текущее название. | |||
$device_title = $devices[$i]['TITLE']; | |||
} | |||
// Записываем сообщение о том, что устройство было найдено. | |||
DebMes("Device found for $command ($device_title)", 'simple_devices'); | |||
// Получаем связанный объект устройства. | |||
$linked_object = $devices[$i]['LINKED_OBJECT']; | |||
if ($device_type == 'sensor_percentage' || $device_type == 'sensor_humidity') { | |||
// Формируем сообщение для датчиков с процентами и влажностью. | |||
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . '%'; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif ($device_type == 'sensor_light') { | |||
// Формируем сообщение для датчиков света. | |||
$reply_say = $device_title . ' ' . gg($linked_object . '.value'); | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif ($device_type == 'sensor_temp') { | |||
// Формируем сообщение для датчиков температуры. | |||
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . ' ' . LANG_DEVICES_DEGREES; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif (preg_match('/sensor/', $device_type)) { | |||
// Формируем сообщение для других датчиков. | |||
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . ''; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif ($device_type == 'counter') { | |||
// Формируем сообщение для счетчиков. | |||
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . ' ' . gg($linked_object . '.unit'); | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif ($device_type == 'openclose') { | |||
// Формируем сообщение для устройств открытия/закрытия. | |||
$reply_say = $device_title . ' ' . (gg($linked_object . '.status') ? LANG_DEVICES_STATUS_CLOSED : LANG_DEVICES_STATUS_OPEN); | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif ($device_type == 'smoke' || $device_type == 'leak') { | |||
// Формируем сообщение для датчиков дыма и утечек. | |||
$reply_say = $device_title . ' ' . (gg($linked_object . '.status') ? LANG_DEVICES_STATUS_ALARM : LANG_DEVICES_NORMAL_VALUE); | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
} elseif ($device_type == 'button') { | |||
// Добавляем код для имитации нажатия кнопки. | |||
$run_code .= "callMethod('$linked_object.pressed');"; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
$reply_confirm = 1; | |||
} elseif ( | |||
$device_type == 'controller' || | |||
$device_type == 'relay' || | |||
$device_type == 'dimmer' || | |||
$device_type == 'rgb' | |||
) { | |||
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNON . '/uis', $command)) { | |||
// Формируем сообщение для включения устройства. | |||
$reply_say = LANG_TURNING_ON . ' ' . $device_title . $add_phrase; | |||
// Добавляем код для включения устройства. | |||
$run_code .= "callMethod('$linked_object.turnOn');"; | |||
// Добавляем код для выключения устройства в качестве противодействия. | |||
$opposite_code .= "callMethod('$linked_object.turnOff');"; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
//$reply_confirm = 1; | |||
} elseif (preg_match('/' . LANG_DEVICES_PATTERN_TURNOFF . '/uis', $command)) { | |||
// Формируем сообщение для выключения устройства. | |||
$reply_say = LANG_TURNING_OFF . ' ' . $device_title . $add_phrase; | |||
// Добавляем код для выключения устройства. | |||
$run_code .= "callMethod('$linked_object.turnOff');"; | |||
// Добавляем код для включения устройства в качестве противодействия. | |||
$opposite_code .= "callMethod('$linked_object.turnOn');"; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
//$reply_confirm = 1; | |||
} | |||
} elseif ($device_type == 'openable') { | |||
if (preg_match('/' . LANG_DEVICES_PATTERN_OPEN . '/uis', $command)) { | |||
// Формируем сообщение для открытия устройства. | |||
$reply_say = LANG_TURNING_OPEN . ' ' . $device_title . $add_phrase; | |||
// Добавляем код для открытия устройства. | |||
$run_code .= "callMethod('$linked_object.Open');"; | |||
// Добавляем код для закрытия устройства в качестве противодействия. | |||
$opposite_code .= "callMethod('$linked_object.Close');"; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
//$reply_confirm = 1; | |||
} elseif (preg_match('/' . LANG_DEVICES_PATTERN_CLOSE . '/uis', $command)) { | |||
// Формируем сообщение для закрытия устройства. | |||
$reply_say = LANG_TURNING_CLOSE . ' ' . $device_title . $add_phrase; | |||
// Добавляем код для закрытия устройства. | |||
$run_code .= "callMethod('$linked_object.Close');"; | |||
// Добавляем код для открытия устройства в качестве противодействия. | |||
$opposite_code .= "callMethod('$linked_object.Open');"; | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
//$reply_confirm = 1; | |||
} | |||
} elseif ($device_type == 'group') { | |||
// Разбиваем типы применения группы по запятой. | |||
$applies_to = explode(',', $devices[$i]['APPLY_TYPES']); | |||
// Если устройства группы представлены в виде массива. | |||
if (is_array($devices[$i]['DEVICES'])) { | |||
// Инициализируем массив для хранения связанных объектов устройств в группе. | |||
$devices_in_group = array(); | |||
// Проходим по каждому устройству в группе. | |||
foreach ($devices[$i]['DEVICES'] as $group_device) { | |||
// Добавляем связанный объект устройства в массив. | |||
$devices_in_group[] = $group_device['LINKED_OBJECT']; | |||
} | |||
// Если устройства группы не представлены в виде массива. | |||
} else { | |||
// Получаем связанные объекты устройств в группе по свойству. | |||
$devices_in_group = getObjectsByProperty('group' . $devices[$i]['SYS_NAME'], 1); | |||
} | |||
// Выводим содержимое переменной $devices_in_group для отладки. | |||
//dprint($devices_in_group); | |||
// Если устройства группы не представлены в виде массива, пропускаем текущую итерацию цикла. | |||
if (!is_array($devices_in_group)) continue; | |||
if ( | |||
in_array('relay', $applies_to) || | |||
in_array('dimmer', $applies_to) || | |||
in_array('rgb', $applies_to) || | |||
0 | |||
) { | |||
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNON . '/uis', $command)) { | |||
// Формируем сообщение для включения устройства. | |||
$reply_say = LANG_TURNING_ON . ' ' . $device_title . $add_phrase; | |||
foreach ($devices_in_group as $linked_object) { | |||
// Добавляем код для включения каждого устройства в группе. | |||
$run_code .= "callMethod('$linked_object.turnOn');"; | |||
// Добавляем код для выключения каждого устройства в группе в качестве противодействия. | |||
$opposite_code .= "callMethod('$linked_object.turnOff');"; | |||
} | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
//$reply_confirm = 1; | |||
} elseif (preg_match('/' . LANG_DEVICES_PATTERN_TURNOFF . '/uis', $command)) { | |||
// Формируем сообщение для выключения устройства. | |||
$reply_say = LANG_TURNING_OFF . ' ' . $device_title . $add_phrase; | |||
foreach ($devices_in_group as $linked_object) { | |||
// Добавляем код для выключения каждого устройства в группе. | |||
$run_code .= "callMethod('$linked_object.turnOff');"; | |||
// Добавляем код для включения каждого устройства в группе в качестве противодействия. | |||
$opposite_code .= "callMethod('$linked_object.turnOn');"; | |||
} | |||
// Помечаем, что команда была обработана. | |||
$processed = 1; | |||
// Помечаем, что необходимо подтверждение выполнения команды. | |||
//$reply_confirm = 1; | |||
} | |||
} | |||
// Определяем путь к директории дополнений. | |||
$addons_dir = dirname(__FILE__) . '/addons'; | |||
// Если директория дополнений существует. | |||
if (is_dir($addons_dir)) { | |||
// Получаем список файлов в директории дополнений. | |||
$addon_files = scandir($addons_dir); | |||
// Проходим по каждому файлу в полученном списке. | |||
foreach ($addon_files as $file) { | |||
// Если имя файла соответствует шаблону. | |||
if (preg_match('/\_commands\.php$/', $file)) { | |||
// Подключаем файл дополнения. | |||
require($addons_dir . '/' . $file); | |||
} | |||
} | |||
} | |||
// Если команда была обработана, прерываем цикл. | |||
if ($processed) break; | |||
if ($run_code != '' && $period_delay > 0) { | |||
// Если есть код для выполнения и задержка больше 0, устанавливаем таймер для выполнения кода после задержки. | |||
setTimeout('delay' . md5($run_code), $run_code, $period_delay); | |||
} elseif ($run_code != '' && $period_run_for > 0 && $opposite_code != '') { | |||
// Если есть код для выполнения, продолжительность выполнения больше 0 и есть код для противодействия, выполняем код. | |||
eval($run_code); | |||
// Устанавливаем таймер для выполнения кода противодействия после указанного времени. | |||
setTimeout('opposite' . md5($run_code), $opposite_code, $period_run_for); | |||
} elseif ($run_code != '') { | |||
// Если есть код для выполнения, выполняем его. | |||
eval($run_code); | |||
/* | |||
* TODO использовать eval считается небезопасным, поскольку он выполняет произвольный PHP-код, представленный в виде строки. | |||
* Это может создать уязвимости в безопасности и снизить производительность, поскольку он компилирует и выполняет код каждый раз, | |||
* когда он вызывается. Это может привести к увеличению нагрузки на сервер и снижению производительности. | |||
*/ | |||
} | |||
if ($reply_say != '') { | |||
// Если есть сообщение для ответа, отправляем его. | |||
sayReplySafe($reply_say, 2); | |||
} | |||
if ($reply_confirm) { | |||
// Разбиваем строку подтверждения команды по символу '|'. | |||
$items = explode('|', LANG_DEVICES_COMMAND_CONFIRMATION); | |||
// Удаляем пробелы в начале и конце каждого элемента массива. | |||
$items = array_map('trim', $items); | |||
// Отправляем случайное сообщение из массива подтверждений. | |||
sayReplySafe($items[array_rand($items)], 2); | |||
} | |||
if ($processed) { | |||
// Если команда была обработана, помечаем это. | |||
$details['PROCESSED'] = 1; | |||
// Помечаем, что необходимо прервать выполнение. | |||
$details['BREAK'] = 1; | |||
} | |||
} | |||
} | |||
} | |||
</pre> | </pre> | ||
Текущая версия от 21:38, 9 апреля 2024
ᐂ В корневой раздел ᐃ В директорию расположения файла
<?php
// Проверяет, отключены ли простые устройства в файле конфигурации ROOT . config.php. Если да, прекращает выполнение скрипта.
if (defined('DISABLE_SIMPLE_DEVICES') && DISABLE_SIMPLE_DEVICES == 1) return;
/*
* array('level' => $level, 'message' => $ph, 'member_id' => $member_id, 'source' => $source)
* $details['BREAK'] = 1 / 0
*/
// Этот блок кода, вероятно, предназначен для обработки лога или отладки, так как он содержит пример использования переменной $details['BREAK'].
// Однако, поскольку он закомментирован, его выполнение в текущем состоянии скрипта не происходит.
// Включаем файлы локализации для текущего языка сайта и по умолчанию.
@include_once(ROOT . 'languages/' . $this->name . '_' . SETTINGS_SITE_LANGUAGE . '.php');
@include_once(ROOT . 'languages/' . $this->name . '_default' . '.php');
// Если в деталях команды указано источник (терминал), то получаем информацию о терминале.
if ($details['source']) {
$terminal = getTerminalByID(str_replace("terminal", "", $details['source']));
// Если у терминала есть ID местоположения, сохраняем его.
if ($terminal['LOCATION_ID']) {
$location_id = $terminal['LOCATION_ID'];
}
}
/*
* Этот фрагмент кода анализирует входящую команду на предмет наличия указаний на задержку выполнения,
* или продолжительность выполнения действия.
* Если такие указания присутствуют, код вычисляет соответствующие значения в секундах
* и сохраняет их в переменных $period_delay и $period_run_for соответственно.
* Также код сохраняет найденное совпадение в переменную $add_phrase, чтобы потом добавить его к сообщению.
*/
// Получаем текстовую команду из массива $details, который содержит детали сообщения.
$command = $details['message'];
// Инициализируем переменную $run_code как пустую строку. Эта переменная будет использоваться для хранения кода, который нужно выполнить.
$run_code = '';
// Инициализируем переменную $opposite_code как пустую строку. Эта переменная будет использоваться для хранения кода, который будет выполнен в качестве противодействия к основному коду.
$opposite_code = '';
// Инициализируем переменную $add_phrase как пустую строку. Эта переменная будет использоваться для хранения дополнительной фразы, которая будет добавлена к сообщению.
$add_phrase = '';
// Инициализируем переменную $period_delay как 0. Эта переменная будет использоваться для хранения задержки выполнения команды в секундах.
$period_delay = 0;
// Инициализируем переменную $period_run_for как 0. Эта переменная будет использоваться для хранения продолжительности выполнения команды в секундах.
$period_run_for = 0;
// Проверяем, содержит ли команда фразу, указывающую на необходимость выполнения действия после определенного времени.
if (preg_match('/' . LANG_PATTERN_DO_AFTER . ' (\d+?) (' . LANG_PATTERN_SECOND . '|' . LANG_PATTERN_MINUTE . '|' . LANG_PATTERN_HOUR . ')/uis', textToNumbers($command), $m)) {
// Получаем числовое значение времени задержки из найденного совпадения.
$period_number = $m[1];
// Добавляем найденное совпадение к переменной $add_phrase, чтобы потом добавить его к сообщению.
$add_phrase = ' ' . $m[0];
// Определяем единицу измерения времени (секунды, минуты, часы) и вычисляем задержку в секундах.
if (preg_match('/' . LANG_PATTERN_SECOND . '/uis', $m[2])) {
// Если единица измерения - секунды, то задержка равна числовому значению.
$period_delay = $period_number;
} elseif (preg_match('/' . LANG_PATTERN_MINUTE . '/uis', $m[2])) {
// Если единица измерения - минуты, то задержка равна числовому значению, умноженному на 60.
$period_delay = $period_number * 60;
} elseif (preg_match('/' . LANG_PATTERN_HOUR . '/uis', $m[2])) {
// Если единица измерения - часы, то задержка равна числовому значению, умноженному на 3600.
$period_delay = $period_number * 60 * 60;
}
// Удаляем обработанную часть команды, чтобы оставить только саму команду без указания времени задержки.
$command = trim(str_replace($m[0], '', textToNumbers($command)));
} elseif (preg_match('/' . LANG_PATTERN_DO_FOR . ' (\d+?) (' . LANG_PATTERN_SECOND . '|' . LANG_PATTERN_MINUTE . '|' . LANG_PATTERN_HOUR . ')/uis', textToNumbers($command), $m)) {
// Получаем числовое значение времени выполнения из найденного совпадения.
$period_number = $m[1];
// Добавляем найденное совпадение к переменной $add_phrase, чтобы потом добавить его к сообщению.
$add_phrase = ' ' . $m[0];
// Определяем единицу измерения времени (секунды, минуты, часы) и вычисляем продолжительность выполнения в секундах.
if (preg_match('/' . LANG_PATTERN_SECOND . '/uis', $m[2])) {
// Если единица измерения - секунды, то продолжительность выполнения равна числовому значению.
$period_run_for = $period_number;
} elseif (preg_match('/' . LANG_PATTERN_MINUTE . '/uis', $m[2])) {
// Если единица измерения - минуты, то продолжительность выполнения равна числовому значению, умноженному на 60.
$period_run_for = $period_number * 60;
} elseif (preg_match('/' . LANG_PATTERN_HOUR . '/uis', $m[2])) {
// Если единица измерения - часы, то продолжительность выполнения равна числовому значению, умноженному на 3600.
$period_run_for = $period_number * 60 * 60;
}
// Удаляем обработанную часть команды, чтобы оставить только саму команду без указания времени выполнения.
$command = trim(str_replace($m[0], '', textToNumbers($command)));
}
// Инициализируем переменную $processed как 0. Эта переменная будет использоваться для отслеживания, была ли команда обработана.
$processed = 0;
// Инициализируем переменную $reply_confirm как 0. Эта переменная будет использоваться для подтверждения выполнения команды.
$reply_confirm = 0;
// Инициализируем переменную $reply_say как пустую строку. Эта переменная будет использоваться для хранения сообщения, которое будет отправлено в ответ на команду.
$reply_say = '';
// Инициализируем переменную $phpmorphy_loaded как 0. Эта переменная будет использоваться для отслеживания, загружена ли библиотека phpMorphy.
$phpmorphy_loaded = 0;
// Проверяем, существует ли файл библиотеки phpMorphy.
if (file_exists(ROOT . "lib/phpmorphy/common.php")) {
// Подключаем файл библиотеки phpMorphy.
require_once(ROOT . "lib/phpmorphy/common.php");
$opts = array(
// Указываем тип хранения данных.
'storage' => PHPMORPHY_STORAGE_MEM,
// Включаем предсказание по суффиксу.
'predict_by_suffix' => true,
// Включаем предсказание по базе данных.
'predict_by_db' => true,
// Указываем, что грамматическая информация должна быть представлена в виде текста.
'graminfo_as_text' => true,
);
// Указываем путь к словарям phpMorphy.
$dir = ROOT . 'lib/phpmorphy/dicts';
// Получаем код текущего языка сайта.
$lang = SETTINGS_SITE_LANGUAGE_CODE;
try {
// Создаем экземпляр класса phpMorphy.
$morphy = new phpMorphy($dir, $lang, $opts);
// Сохраняем ссылку на созданный экземпляр в свойстве объекта.
$this->morphy = &$morphy;
} catch (phpMorphy_Exception $e) {
// Выводим сообщение об ошибке и прерываем выполнение скрипта.
die('Error occured while creating phpMorphy instance: ' . PHP_EOL . $e);
}
// Разбиваем команду на слова.
$words = explode(' ', $command);
// Инициализируем массив для хранения отфильтрованных слов.
$words_filtered = array();
// Инициализируем счетчик отфильтрованных слов.
$filtered_count = 0;
// Инициализируем массив для хранения базовых форм слов.
$base_forms = array();
// Инициализируем массив для хранения базовых форм отфильтрованных слов.
$base_forms_filtered = array();
// Получаем общее количество слов в команде.
$totals = count($words);
for ($is = 0; $is < $totals; $is++) {
// Инициализируем переменную для отслеживания, было ли слово фильтровано.
$filtered = 0;
// Преобразуем слово в верхний регистр.
$upper = mb_strtoupper($words[$is], 'UTF-8');
// Получаем длину слова.
$len = mb_strlen($words[$is], 'UTF-8');
// Если длина слова больше или равна 3, считаем его достаточно длинным для анализа.
if ($len >= 3) {
// Добавляем слово в массив отфильтрованных слов.
$words_filtered[] = $words[$is];
// Помечаем слово как отфильтрованное.
$filtered = 1;
// Увеличиваем счетчик отфильтрованных слов.
$filtered_count++;
}
// Если слово является числом, добавляем его в массив базовых форм.
if (preg_match('/^(\d+)$/', $words[$is])) {
$base_forms[$is] = array($words[$is]);
// Если слово не содержит специальных символов, получаем его базовую форму.
} elseif (!preg_match('/[\(\)\+\.]/', $words[$is])) {
// Преобразуем слово в верхний регистр.
$Word = mb_strtoupper($words[$is], 'UTF-8');
// Получаем базовую форму слова.
$base_forms[$is] = $morphy->getBaseForm($Word);
// Добавляем исходное слово в массив базовых форм.
$base_forms[$is][] = $words[$is];
// Если слово содержит специальные символы, добавляем его в массив базовых форм без изменений.
} else {
$base_forms[$is] = array($words[$is]);
}
// Если слово было отфильтровано, добавляем его базовую форму в массив отфильтрованных базовых форм.
if ($filtered) {
$base_forms_filtered[$filtered_count - 1] = $base_forms[$is];
}
}
// Генерируем все возможные комбинации базовых форм слов.
$combos = $this->generate_combinations($base_forms);
// Если количество отфильтрованных слов меньше общего количества слов, генерируем дополнительные комбинации.
if ($filtered_count < $totals) {
// Генерируем комбинации для отфильтрованных базовых форм.
$add_combos = $this->generate_combinations($base_forms_filtered);
// Добавляем каждую сгенерированную комбинацию в общий массив комбинаций.
foreach ($add_combos as $cmb) {
$combos[] = $cmb;
}
}
// Инициализируем массив для хранения строк, полученных из комбинаций.
$lines = array();
// Получаем общее количество комбинаций.
$totals = count($combos);
// Преобразуем каждую комбинацию в строку и добавляем ее в массив строк.
for ($is = 0; $is < $totals; $is++) {
$lines[] = implode(' ', $combos[$is]);
}
// Помечаем, что библиотека phpMorphy была успешно загружена.
$phpmorphy_loaded = 1;
}
// Получаем список устройств из базы данных.
$devices = SQLSelect("SELECT ID, TITLE, ALT_TITLES, TYPE, LINKED_OBJECT, LOCATION_ID FROM devices");
// Проходим по каждому устройству в полученном списке.
foreach ($devices as $device) {
// Если у устройства есть альтернативные названия.
if (trim($device['ALT_TITLES']) != '') {
// Разбиваем альтернативные названия по запятой.
$nicknames = explode(',', trim($device['ALT_TITLES']));
// Проходим по каждому альтернативному названию.
foreach ($nicknames as $nickname) {
// Копируем текущее устройство.
$add_rec = $device;
// Заменяем название устройства на альтернативное.
$add_rec['TITLE'] = $nickname;
// Добавляем измененное устройство обратно в список устройств.
$devices[] = $add_rec;
}
}
}
// Получаем список групп устройств из базы данных.
$groups = SQLSelect("SELECT * FROM devices_groups");
// Получаем общее количество групп.
$total = count($groups);
// Проходим по каждой группе в полученном списке.
for ($i = 0; $i < $total; $i++) {
// Копируем текущую группу.
$add_rec = $groups[$i];
// Устанавливаем тип группы как 'group'.
$add_rec['TYPE'] = 'group';
// Добавляем группу обратно в список устройств.
$devices[] = $add_rec;
}
// Получаем список комнат с устройствами из базы данных.
$rooms = SQLSelect("SELECT locations.ID, locations.TITLE, COUNT(*) AS TOTAL FROM locations, devices WHERE locations.ID=devices.LOCATION_ID GROUP BY locations.ID");
// Проходим по каждой комнате в полученном списке.
foreach ($rooms as $room) {
//lights
//if ($room['TITLE']=='Кабинет') {
// Инициализируем массив для хранения типов устройств в комнате.
$device_types = array();
// Получаем список устройств типа 'relay' в текущей комнате.
$room_devices = SQLSelect("SELECT * FROM devices WHERE LOCATION_ID=" . $room['ID'] . " AND TYPE='relay'");
// Проходим по каждому устройству в полученном списке.
foreach ($room_devices as $device) {
// Получаем тип нагрузки устройства.
$loadType = gg($device['LINKED_OBJECT'] . '.loadType');
// Добавляем устройство в массив типов устройств.
$device_types[$loadType][] = $device;
}
// Если в комнате есть устройства типа 'light'.
if (isset($device_types['light'])) {
// Инициализируем массив для новой группы устройств.
$add_rec = array();
// Устанавливаем тип группы как 'group'.
$add_rec['TYPE'] = 'group';
// Устанавливаем название группы.
$add_rec['TITLE'] = LANG_DEVICES_LOADTYPE_LIGHT . ' ' . $room['TITLE'];
// Добавляем устройства типа 'light' в группу.
$add_rec['DEVICES'] = $device_types['light'];
// Устанавливаем типы применения группы.
$add_rec['APPLY_TYPES'] = 'relay';
// Добавляем группу обратно в список устройств.
$devices[] = $add_rec;
// Инициализируем массив для новой группы устройств.
$add_rec = array();
// Устанавливаем тип группы как 'group'.
$add_rec['TYPE'] = 'group';
// Устанавливаем альтернативное название группы.
$add_rec['TITLE'] = LANG_DEVICES_LOADTYPE_LIGHT_ALT . ' ' . $room['TITLE'];
// Добавляем устройства типа 'light' в группу.
$add_rec['DEVICES'] = $device_types['light'];
// Устанавливаем типы применения группы.
$add_rec['APPLY_TYPES'] = 'relay';
// Добавляем группу обратно в список устройств.
$devices[] = $add_rec;
}
//}
}
// Если библиотека phpMorphy была успешно загружена.
if ($phpmorphy_loaded) {
// Получаем общее количество устройств.
$total = count($devices);
// Инициализируем массив для хранения дополнительных устройств.
$add_devices = array();
// Проходим по каждому устройству в полученном списке.
for ($i = 0; $i < $total; $i++) {
// Получаем название устройства.
$device_title = $devices[$i]['TITLE'];
// Разбиваем название устройства на слова и преобразуем их в верхний регистр.
$words = explode(' ', mb_strtoupper($device_title, 'UTF-8'));
// Инициализируем массив для хранения базовых форм слов.
$base_forms = array();
// Получаем общее количество слов.
$totals = count($words);
// Проходим по каждому слову в полученном списке.
for ($is = 0; $is < $totals; $is++) {
// Если слово является числом, добавляем его в массив базовых форм.
if (preg_match('/^(\d+)$/', $words[$is])) {
$base_forms[$is] = array($words[$is]);
// Если слово не содержит специальных символов, получаем его базовую форму.
} elseif (!preg_match('/[\(\)\+\.]/', $words[$is])) {
// Преобразуем слово в верхний регистр.
$Word = mb_strtoupper($words[$is], 'UTF-8');
// Получаем базовую форму слова.
$base_form = $morphy->getBaseForm($Word);
// Если базовая форма представлена в виде массива.
if (is_array($base_form)) {
$base_forms[$is] = $base_form;
// Если базовая форма не представлена в виде массива.
} else {
$base_forms[$is] = array();
}
// Если исходное слово не содержится в массиве базовых форм.
if (!in_array($words[$is], $base_forms[$is])) {
// Добавляем исходное слово в массив базовых форм.
$base_forms[$is][] = $words[$is];
}
// Если слово содержит специальные символы, добавляем его в массив базовых форм без изменений.
} else {
$base_forms[$is] = array($words[$is]);
}
}
// Генерируем все возможные комбинации базовых форм слов.
$combos = $this->generate_combinations($base_forms);
// Инициализируем массив для хранения фраз, полученных из комбинаций.
$phrases = array();
// Проходим по каждой комбинации в полученном списке.
foreach ($combos as $combo) {
// Вычисляем все возможные перестановки для текущей комбинации.
$mutations = $this->computePermutations($combo);
// Проходим по каждой перестановке в полученном списке.
foreach ($mutations as $m) {
// Преобразуем каждую перестановку в строку и добавляем ее в массив фраз.
$phrases[] = implode(' ', $m);
}
}
// Инициализируем массив для хранения новых названий устройств.
$device_titles = array();
// Получаем общее количество фраз.
$totals = count($phrases);
// Проходим по каждой фразе в полученном списке.
for ($is = 0; $is < $totals; $is++) {
// Получаем новое название устройства.
$new_title = $phrases[$is];
// Добавляем новое название устройства в массив новых названий.
$device_titles[] = $new_title;
// Копируем текущее устройство.
$new_device = $devices[$i];
// Заменяем название устройства на новое.
$new_device['TITLE'] = $new_title;
// Сохраняем оригинальное название устройства.
$new_device['ORIGINAL_TITLE'] = $device_title;
// Добавляем измененное устройство в массив дополнительных устройств.
$add_devices[] = $new_device;
}
}
// Проходим по каждому устройству в массиве дополнительных устройств.
foreach ($add_devices as $device) {
// Добавляем устройство обратно в список устройств.
$devices[] = $device;
}
}
// Выводим содержимое переменной $lines для отладки.
//dprint($lines,false);
// Выводим содержимое переменной $devices для отладки.
//dprint($devices);
// Инициализируем переменную $compare_title командой.
$compare_title = $command;
// Проверяем, содержит ли команда фразу, указывающую на необходимость включения устройства.
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNON . '/uis', $compare_title, $m)) {
// Если да, удаляем эту фразу из команды.
$compare_title = trim(str_replace($m[0], ' ', $compare_title));
}
// Проверяем, содержит ли команда фразу, указывающую на необходимость выключения устройства.
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNOFF . '/uis', $compare_title, $m)) {
// Если да, удаляем эту фразу из команды.
$compare_title = trim(str_replace($m[0], ' ', $compare_title));
}
// Удаляем начальные слова "ть" и "те" из команды, если они присутствуют.
$compare_title = trim(preg_replace('/^ть /', '', $compare_title));
$compare_title = trim(preg_replace('/^те /', '', $compare_title));
// Если после всех преобразований команда стала пустой, прекращаем выполнение скрипта.
if ($compare_title == '') {
return;
}
// Получаем общее количество устройств.
$total = count($devices);
// Проходим по каждому устройству в полученном списке.
for ($i = 0; $i < $total; $i++) {
// Инициализируем переменную для отслеживания, было ли найдено соответствие устройства.
$device_matched = 0;
// Если указано местоположение терминала.
if ($location_id) {
// Ищем строгое соответствие по названию и местоположению.
foreach ($devices as $key => $value) {
// Если ID местоположения устройства совпадает с ID местоположения терминала и название устройства совпадает с командой.
if (in_array($location_id, $value) && strtolower($devices[$key]['TITLE']) == strtolower($compare_title)) {
// Обновляем индекс текущего устройства.
$i = $key;
// Помечаем, что устройство найдено.
$device_matched = 1;
// Прерываем цикл.
break;
}
}
// Если устройство не найдено.
if (!$device_matched) {
// Ищем строгое соответствие по названию.
foreach ($devices as $key => $value) {
// Если название устройства совпадает с командой.
if (in_array(strtolower($compare_title), strtolower($value))) {
// Обновляем индекс текущего устройства.
$i = $key;
// Помечаем, что устройство найдено.
$device_matched = 1;
// Прерываем цикл.
break;
}
}
}
}
// Ищем по старому принципу.
if (preg_match('/' . preg_quote($devices[$i]['TITLE']) . '/uis', $compare_title)) {
// Помечаем, что устройство найдено.
$device_matched = 1;
} elseif (preg_match('/' . preg_quote($compare_title) . '/uis', $devices[$i]['TITLE'])) {
// Помечаем, что устройство найдено.
$device_matched = 1;
// Если библиотека phpMorphy была успешно загружена.
} elseif ($phpmorphy_loaded) {
if (preg_match('/' . preg_quote($devices[$i]['TITLE']) . '/isu', implode('@@@@', $lines), $matches)) {
// Помечаем, что устройство найдено.
$device_matched = 1;
}
}
/*
if (preg_match('/свет над столом/uis',$devices[$i]['TITLE'])) {
dprint($devices[$i]['TITLE'].' - '.$compare_title.': '.$device_matched);
}
*/
// Если устройство было найдено.
if ($device_matched) {
// Найдено устройство.
// Получаем ID устройства.
$device_id = $devices[$i]['ID'];
// Получаем тип устройства.
$device_type = $devices[$i]['TYPE'];
// Если у устройства есть оригинальное название.
if ($devices[$i]['ORIGINAL_TITLE'] != '') {
// Используем оригинальное название.
$device_title = $devices[$i]['ORIGINAL_TITLE'];
// Если оригинального названия нет.
} else {
// Используем текущее название.
$device_title = $devices[$i]['TITLE'];
}
// Записываем сообщение о том, что устройство было найдено.
DebMes("Device found for $command ($device_title)", 'simple_devices');
// Получаем связанный объект устройства.
$linked_object = $devices[$i]['LINKED_OBJECT'];
if ($device_type == 'sensor_percentage' || $device_type == 'sensor_humidity') {
// Формируем сообщение для датчиков с процентами и влажностью.
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . '%';
// Помечаем, что команда была обработана.
$processed = 1;
} elseif ($device_type == 'sensor_light') {
// Формируем сообщение для датчиков света.
$reply_say = $device_title . ' ' . gg($linked_object . '.value');
// Помечаем, что команда была обработана.
$processed = 1;
} elseif ($device_type == 'sensor_temp') {
// Формируем сообщение для датчиков температуры.
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . ' ' . LANG_DEVICES_DEGREES;
// Помечаем, что команда была обработана.
$processed = 1;
} elseif (preg_match('/sensor/', $device_type)) {
// Формируем сообщение для других датчиков.
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . '';
// Помечаем, что команда была обработана.
$processed = 1;
} elseif ($device_type == 'counter') {
// Формируем сообщение для счетчиков.
$reply_say = $device_title . ' ' . gg($linked_object . '.value') . ' ' . gg($linked_object . '.unit');
// Помечаем, что команда была обработана.
$processed = 1;
} elseif ($device_type == 'openclose') {
// Формируем сообщение для устройств открытия/закрытия.
$reply_say = $device_title . ' ' . (gg($linked_object . '.status') ? LANG_DEVICES_STATUS_CLOSED : LANG_DEVICES_STATUS_OPEN);
// Помечаем, что команда была обработана.
$processed = 1;
} elseif ($device_type == 'smoke' || $device_type == 'leak') {
// Формируем сообщение для датчиков дыма и утечек.
$reply_say = $device_title . ' ' . (gg($linked_object . '.status') ? LANG_DEVICES_STATUS_ALARM : LANG_DEVICES_NORMAL_VALUE);
// Помечаем, что команда была обработана.
$processed = 1;
} elseif ($device_type == 'button') {
// Добавляем код для имитации нажатия кнопки.
$run_code .= "callMethod('$linked_object.pressed');";
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
$reply_confirm = 1;
} elseif (
$device_type == 'controller' ||
$device_type == 'relay' ||
$device_type == 'dimmer' ||
$device_type == 'rgb'
) {
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNON . '/uis', $command)) {
// Формируем сообщение для включения устройства.
$reply_say = LANG_TURNING_ON . ' ' . $device_title . $add_phrase;
// Добавляем код для включения устройства.
$run_code .= "callMethod('$linked_object.turnOn');";
// Добавляем код для выключения устройства в качестве противодействия.
$opposite_code .= "callMethod('$linked_object.turnOff');";
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
//$reply_confirm = 1;
} elseif (preg_match('/' . LANG_DEVICES_PATTERN_TURNOFF . '/uis', $command)) {
// Формируем сообщение для выключения устройства.
$reply_say = LANG_TURNING_OFF . ' ' . $device_title . $add_phrase;
// Добавляем код для выключения устройства.
$run_code .= "callMethod('$linked_object.turnOff');";
// Добавляем код для включения устройства в качестве противодействия.
$opposite_code .= "callMethod('$linked_object.turnOn');";
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
//$reply_confirm = 1;
}
} elseif ($device_type == 'openable') {
if (preg_match('/' . LANG_DEVICES_PATTERN_OPEN . '/uis', $command)) {
// Формируем сообщение для открытия устройства.
$reply_say = LANG_TURNING_OPEN . ' ' . $device_title . $add_phrase;
// Добавляем код для открытия устройства.
$run_code .= "callMethod('$linked_object.Open');";
// Добавляем код для закрытия устройства в качестве противодействия.
$opposite_code .= "callMethod('$linked_object.Close');";
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
//$reply_confirm = 1;
} elseif (preg_match('/' . LANG_DEVICES_PATTERN_CLOSE . '/uis', $command)) {
// Формируем сообщение для закрытия устройства.
$reply_say = LANG_TURNING_CLOSE . ' ' . $device_title . $add_phrase;
// Добавляем код для закрытия устройства.
$run_code .= "callMethod('$linked_object.Close');";
// Добавляем код для открытия устройства в качестве противодействия.
$opposite_code .= "callMethod('$linked_object.Open');";
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
//$reply_confirm = 1;
}
} elseif ($device_type == 'group') {
// Разбиваем типы применения группы по запятой.
$applies_to = explode(',', $devices[$i]['APPLY_TYPES']);
// Если устройства группы представлены в виде массива.
if (is_array($devices[$i]['DEVICES'])) {
// Инициализируем массив для хранения связанных объектов устройств в группе.
$devices_in_group = array();
// Проходим по каждому устройству в группе.
foreach ($devices[$i]['DEVICES'] as $group_device) {
// Добавляем связанный объект устройства в массив.
$devices_in_group[] = $group_device['LINKED_OBJECT'];
}
// Если устройства группы не представлены в виде массива.
} else {
// Получаем связанные объекты устройств в группе по свойству.
$devices_in_group = getObjectsByProperty('group' . $devices[$i]['SYS_NAME'], 1);
}
// Выводим содержимое переменной $devices_in_group для отладки.
//dprint($devices_in_group);
// Если устройства группы не представлены в виде массива, пропускаем текущую итерацию цикла.
if (!is_array($devices_in_group)) continue;
if (
in_array('relay', $applies_to) ||
in_array('dimmer', $applies_to) ||
in_array('rgb', $applies_to) ||
0
) {
if (preg_match('/' . LANG_DEVICES_PATTERN_TURNON . '/uis', $command)) {
// Формируем сообщение для включения устройства.
$reply_say = LANG_TURNING_ON . ' ' . $device_title . $add_phrase;
foreach ($devices_in_group as $linked_object) {
// Добавляем код для включения каждого устройства в группе.
$run_code .= "callMethod('$linked_object.turnOn');";
// Добавляем код для выключения каждого устройства в группе в качестве противодействия.
$opposite_code .= "callMethod('$linked_object.turnOff');";
}
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
//$reply_confirm = 1;
} elseif (preg_match('/' . LANG_DEVICES_PATTERN_TURNOFF . '/uis', $command)) {
// Формируем сообщение для выключения устройства.
$reply_say = LANG_TURNING_OFF . ' ' . $device_title . $add_phrase;
foreach ($devices_in_group as $linked_object) {
// Добавляем код для выключения каждого устройства в группе.
$run_code .= "callMethod('$linked_object.turnOff');";
// Добавляем код для включения каждого устройства в группе в качестве противодействия.
$opposite_code .= "callMethod('$linked_object.turnOn');";
}
// Помечаем, что команда была обработана.
$processed = 1;
// Помечаем, что необходимо подтверждение выполнения команды.
//$reply_confirm = 1;
}
}
// Определяем путь к директории дополнений.
$addons_dir = dirname(__FILE__) . '/addons';
// Если директория дополнений существует.
if (is_dir($addons_dir)) {
// Получаем список файлов в директории дополнений.
$addon_files = scandir($addons_dir);
// Проходим по каждому файлу в полученном списке.
foreach ($addon_files as $file) {
// Если имя файла соответствует шаблону.
if (preg_match('/\_commands\.php$/', $file)) {
// Подключаем файл дополнения.
require($addons_dir . '/' . $file);
}
}
}
// Если команда была обработана, прерываем цикл.
if ($processed) break;
if ($run_code != '' && $period_delay > 0) {
// Если есть код для выполнения и задержка больше 0, устанавливаем таймер для выполнения кода после задержки.
setTimeout('delay' . md5($run_code), $run_code, $period_delay);
} elseif ($run_code != '' && $period_run_for > 0 && $opposite_code != '') {
// Если есть код для выполнения, продолжительность выполнения больше 0 и есть код для противодействия, выполняем код.
eval($run_code);
// Устанавливаем таймер для выполнения кода противодействия после указанного времени.
setTimeout('opposite' . md5($run_code), $opposite_code, $period_run_for);
} elseif ($run_code != '') {
// Если есть код для выполнения, выполняем его.
eval($run_code);
/*
* TODO использовать eval считается небезопасным, поскольку он выполняет произвольный PHP-код, представленный в виде строки.
* Это может создать уязвимости в безопасности и снизить производительность, поскольку он компилирует и выполняет код каждый раз,
* когда он вызывается. Это может привести к увеличению нагрузки на сервер и снижению производительности.
*/
}
if ($reply_say != '') {
// Если есть сообщение для ответа, отправляем его.
sayReplySafe($reply_say, 2);
}
if ($reply_confirm) {
// Разбиваем строку подтверждения команды по символу '|'.
$items = explode('|', LANG_DEVICES_COMMAND_CONFIRMATION);
// Удаляем пробелы в начале и конце каждого элемента массива.
$items = array_map('trim', $items);
// Отправляем случайное сообщение из массива подтверждений.
sayReplySafe($items[array_rand($items)], 2);
}
if ($processed) {
// Если команда была обработана, помечаем это.
$details['PROCESSED'] = 1;
// Помечаем, что необходимо прервать выполнение.
$details['BREAK'] = 1;
}
}
}
}