Контексты в шаблонах поведения

Если вы только начинаете осваивать систему MajorDoMo и чего-то не знаете или не можете понять, то задавайте свои вопросы в этой ветке.

Модератор: immortal

Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Рабочий пример многоуровневого шаблона (Включи|Выключи)

Сообщение Bagir » Чт авг 04, 2022 4:20 pm

Раз уж много мы много говорили про эту тему, покажу свой вариант многоуровнего шаблона (Включи|Выключи)
1 уровеньПоказать
Название: Включи или Выключи
Шаблон: (Включи|Выключи)
использовать как контекс: Да
Выполнить при совпадении:

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

saveToCache('VAR:original'.$from_user_id, $original);
say('Что именно '.$original.'ть?');
По истечении времени выполнить:

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

say('Попробуем в другой раз');
2 уровеньПоказать
Название: Свет Освещение
Шаблон: (свет|освещение)
использовать как контекс: Да
Выполнить при совпадении:

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

$ss = trim(checkFromCache('VAR:original'.$from_user_id).' '.mb_strtolower($original));
saveToCache('VAR:original'.$from_user_id, $ss);
say('Где именно?');
По истечении времени выполнить:

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

say('Разговор про свет закончен');
Дополнение для реакции без указания места
3 уровеньПоказать
Название: кухня
Шаблон: кухн
использовать как контекс: Нет
Выполнить при совпадении:

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

$ss = trim(checkFromCache('VAR:original'.$from_user_id).' '.mb_strtolower($original));

if (preg_match('/включи/isu',$ss)) {
  cm('RelayX.turnOn');
  say('Включаю свет на кухне');
} elseif (preg_match('/выключи/isu',$ss)) {
  cm('RelayX.turnOff'); 
  say('Выключаю свет на кухне');
} else {
  say("Непонятно: $ss");
}

saveToCache('VAR:original'.$from_user_id, '');
Обратите внимание, Название и Шаблон у меня разные. Дело в том, что название видно в панели управления, и не режет глаз закорючками. К тому же название читается при команде "Помощь". Очень надеюсь, что этот момент не будет изменен в системе в будущем. Если поле "Шаблон" пустое, то значение берется из "Названия".
Вариант работает с диалогами разных пользователей одновременно. Посмотреть значения временных переменных можно в cached_values по SQL запросу SELECT * FROM `cached_values` WHERE KEYWORD LIKE '%original%'
Единственный момент, если пользователь ведет диалог частями, и долго не продолжает, то срабатывает код "По истечении времени выполнить:". Тут бы неплохо очищать временную переменную этого пользователя, но $from_user_id тут не сработает т.к. на момент выполнения кода, контекст уже сброшен. Поэтому текст не законченного диалога так и будет висеть в переменной. В принципе, это не страшно, т.к. текст будет затерт при новом диалоге на первом уровне. Вторые (и до последнего) уровни должны уже дополнять текст. Последний уровень его стирает.

Очень бы хотелось получить полный текст истории диалога штатными средствами. Но об этом я писал ранее. Дубли в SQL таблице, при переходах сразу на несколько уровней, я нашел как устранить. Об этом писал ранее. Но сделать возврат без исправления кода файлов не получится.
:!: В идеале я вижу это так:
По массиву $matches[] у меня нет предложений
$original содержит последнюю фразу пользователя без изменений
$history - всю историю диалога в контексте.
Возможно, путаница и отсутствие этого сильно понижает внимание народа к Шаблонам поведения. А штука классная. Мне нравится. Все свои голосовые приблуды я использую только для передачи текста в чат МД.
Последний раз редактировалось Bagir Пт авг 05, 2022 10:04 am, всего редактировалось 3 раза.
За это сообщение автора Bagir поблагодарил:
homester (Чт авг 04, 2022 5:04 pm)
Рейтинг: 1.16%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Контексты в шаблонах поведения

Сообщение Bagir » Чт авг 04, 2022 6:36 pm

Ещё есть задумка реализовать активацию шаблона комнаты (устройства) без указания места. Например если сообщение поступило от пользователя "Кухня", значит команда "Включи свет" включит его именно на кухне. Но я столкнулся с неприятностью. Обычно код из шаблона запускает функция checkPattern(). У нас же есть афишированная функция context_activate(), которая принимает id шаблона. Но нам нужно ещё указать от какого пользователя. Полные параметры этой функции ID, no_action, $history, $from_user_id. Как мы видим, передать id пользователя мы можем. Но всё дело в том, что context_activate() для выполнения кода модуля вызывает checkPattern(), и не передает ей параметр $from_user_id. Соответственно наш код в шаблоне тоже его не получит, и не будет знать, в какую временную переменную смотреть.
Вечером постараюсь что-нибудь придумать.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Logrus
Сообщения: 2079
Зарегистрирован: Пт апр 07, 2017 12:20 pm
Благодарил (а): 313 раз
Поблагодарили: 457 раз

Re: Контексты в шаблонах поведения

Сообщение Logrus » Чт авг 04, 2022 7:29 pm

сапер ошибается дважды, вот после выбора мдм и пхп :D
https://www.php.net/manual/ru/function. ... d-vars.php

что выведет на последнем уровне к примеру ;)
За это сообщение автора Logrus поблагодарил:
Bagir (Чт авг 04, 2022 7:39 pm)
Рейтинг: 1.16%
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Контексты в шаблонах поведения

Сообщение Bagir » Чт авг 04, 2022 7:40 pm

Logrus писал(а):
Чт авг 04, 2022 7:29 pm
get_defined_vars()
Век живи и век учись. Офигенная годната, сейчас поиграюсь.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Контексты в шаблонах поведения

Сообщение Bagir » Чт авг 04, 2022 8:49 pm

sergejey писал(а):
Пн дек 29, 2014 6:03 pm
И последний штрих -- инициировать переход системы состояние нужного контекста можно следующим кодом:

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

context_activate(10); 
10 это ID нашего контекста. Код может быть вызван например по таймеру или датчику движения и Алиса может спросить, "а не хотите ли включить музыку?". Ну или по условному событию -- температура на улице понизилась и Алиса может предложить по-раньше начинать прогрев помещения. В общем, всё зависит от вашей фантазии, как обычно.
Я кое что нашел. Когда я пробую выполнить этой функцией код шаблона, который, включает свет в комнате, то первый раз всё получается, но шаблон с этим id остается активный ещё стандартные 60 секунд, даже не смотря на то, что шаблон не помечен как контекст. Соответственно в этот период долбиться другими командами к Алисе смысла нет. Все равно ничего не сработает. Так как всё это время мы находимся на уровне шаблона, который вообще не должен быть контекстом.
Я конечно могу решить эту проблемку, но какой в этом смысл, если после этого, мой примеры кода больше ни у кого не будут работать.

:!: Вкратце проблема звучит так:
Использование функции context_activate() на шаблонах, не указанных как контекст, ведет к залипанию на стандартные 60 секунд в этом шаблоне. По идее нам поможет функция context_clear($user_id). Попробуем.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Контексты в шаблонах поведения

Сообщение Bagir » Чт авг 04, 2022 9:43 pm

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

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

if ($from_user_id==5) {
 say('Запуск без указания комнаты'); //debug
 context_activate(31,0,'',$from_user_id);
 context_clear($from_user_id);
} else {
 say('Где именно?');
}
где 5 это id моего пользователя "Кухня", а 31 это id шаблона вкл/выкл света на кухне.
context_clear() нужна чтобы сбросить контекст, который на 60 секунд зависнет на шаблоне комнаты, после использования context_activate(). Кстати, я сам не знаю, вправе ли мы использовать context_activate() на шаблонах, не помеченных как контекст, от сюда и ноги растут...
Кстати, эта добавка ни чуть не портит идею работы с фразами вида "Включи свет на кухне и в зале", т.к. код шаблона включи -> свет выполняется только если не указано конкретное место. Ложка дегтя... Как я и говорил ранее, context_activate() вызывает runPatternAction(), при этом не передавая ей $user_id. Для данной затеи это как мешком по голове. Придется поправить файл context.inc.php Функция context_activate строка

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

$pt->runPatternAction( (int)$context['ID']);
добавить проброс параметров пользователя

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

$pt->runPatternAction( (int)$context['ID'],0,'', $user_id); 
Тогда все работает. Возможно в будущем при обновлениях, мы вообще ограничимся использованием только одной функции context_activate(). Кто знает.
:!: А сейчас, чтобы не править код в файлах, мы потихонечку, пока никто не видит :mrgreen: , подключаем в нашем коде шаблона модуль patterns, и вызываем функцию runPatternAction() сразу с передачей ей всех нужных параметров. Единственный момент, мы тоже залипнем в шаблоне на 60 секунд. т.к. context_clear() запускала функция context_activate(). Чтож, сделаем это сами. Вот пример, у меня на тесте, полет нормальный. Ходил по разным комнатам, говоря одну фразу "Включи свет". Загорается там где сказал.

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

if ($from_user_id==5) {
 say('Запуск без указания комнаты'); //debug
         include_once(DIR_MODULES . 'patterns/patterns.class.php');
         $pt = new patterns();
         $pt->runPatternAction(31,0,'', $from_user_id);
         context_clear($from_user_id);
} else {
 say('Где именно?');
}
До завтра поиграюсь и выложу тут. Всем добра.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Пример реакции без указания места

Сообщение Bagir » Чт авг 04, 2022 11:19 pm

Завалить не удалось, вели диалоги с двух комнат одновременно. Работает без ошибок, тестим дальше. Чем удобно данное решение. Пришел на кухню, сказал включи свет, свет зажегся на кухне. Пришел в баню, сказал тоже самое, свет включился в бане. А вот сказал это в телефон, и Алиса спросила "Где именно?" т.к. пользователь в телефоне не привязан к комнате.
На уровне 2, моего примера немного выше, меняем код на этот:

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

$ss = trim(checkFromCache('VAR:original'.$from_user_id).' '.mb_strtolower($original));
saveToCache('VAR:original'.$from_user_id, $ss);

// массив связей id пользователя и id шаблона комнаты (устройства)
$a = array(5=>31, 99=>99);

// Выполнить код шаблона сразу если не сказали где, или спросить место
if (array_key_exists($from_user_id, $a)) {
 //context_activate(31,0,'',$from_user_id); возможно в будущем заменит инклайд модуля
 include_once(DIR_MODULES . 'patterns/patterns.class.php');
 $pt = new patterns();
 $pt->runPatternAction($a[$from_user_id], 0, '', $from_user_id);
 context_clear($from_user_id);
 clearTimeOut('user_' . $from_user_id . '_contexttimeout');
} else {
 say('Где именно?');
}
5, 31, 99 это для примера, меняем всё на свои. строку //context_activate можно удалить. Будет так будет.
Последний раз редактировалось Bagir Пт авг 05, 2022 10:34 am, всего редактировалось 1 раз.
За это сообщение автора Bagir поблагодарили (всего 2):
xor (Пт авг 05, 2022 9:27 am) • dimka (Сб дек 09, 2023 4:27 pm)
Рейтинг: 2.33%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Контексты в шаблонах поведения

Сообщение Bagir » Пт авг 05, 2022 10:33 am

Не большое дополнение. Нужно еще добавить строку кода, которая чистит таймер. чтобы не выполнялся код шаблона "По истечении времени выполнить:" Вчера ночью с тихим звуком не услышал. У меня там просто сообщения, что разговор завершен.

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

 clearTimeOut('user_' . $from_user_id . '_contexttimeout');
Раз уж мы сами хозяйничаем функциями модуля patterns, надо сделать всё до конца. Код в примере уже поправил.
Посмотреть мои шаблоны можно в конекте. Только что обновил. Ранее у меня был только один микрофон в серверной. Поэтому особо не развивал управление системой текстом (голосом). Сейчас, с появлением Я.колонок, в этом появилась большая необходимость. Шаблоны (Включи|Выключи) у меня трех уровневые. Второй уровень это группа устройств (Вентиляция, Свет, Телик). Третий это место (комната) в которой расположено устройство. Переход со второго на третий может быть без указания комнаты, если пользователь закреплен за ней.
Сегодня вечером поработаю со словами "Напомни через"
За это сообщение автора Bagir поблагодарил:
xor (Пт авг 05, 2022 1:03 pm)
Рейтинг: 1.16%
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Аватара пользователя
xor
Сообщения: 2038
Зарегистрирован: Сб ноя 22, 2014 8:45 pm
Благодарил (а): 284 раза
Поблагодарили: 629 раз

Re: Контексты в шаблонах поведения

Сообщение xor » Пт авг 05, 2022 1:06 pm

Bagir писал(а):
Пт авг 05, 2022 10:33 am

Сегодня вечером поработаю со словами "Напомни через"
А зачем напоминания через шаблоны? это штатная функция у я.колонки. у себя выкинул из шаблонов напоминания, запрос из вики, калькулятор...
Аватара пользователя
Bagir
Сообщения: 1613
Зарегистрирован: Вт сен 17, 2013 6:46 pm
Откуда: Ярославская область город Углич
Благодарил (а): 212 раз
Поблагодарили: 374 раза

Re: Контексты в шаблонах поведения

Сообщение Bagir » Пт авг 05, 2022 2:50 pm

xor писал(а):
Пт авг 05, 2022 1:06 pm
А зачем напоминания через шаблоны? это штатная функция у я.колонки.
Это да, просто я пока не сильно на неё подсел. И Я.колонки не во всех комнатах. Пока что пара штук только. В серверной Микрофон через мою прогу SDM. Есть второй микрофон, только там же пока валяется выключенный. Не протягивал никуда. Из минусов у меня только что нет ключевого слова, но зато диалоги может МД начинать. Пока ещё не знаю, по какой дороге пойду.
Напоминалка то у меня работает. "Напомни через <x> минут <текст>" Вот только Я.колонка цифры прописью присылает. Новому коду шаблона (включи|выключи) не мешает.
Хотел поработать с фразой "через <x> минут", которая добавляется к команде. Не так уж мне это и нужно, просто пока в этой теме сижу, доделать и в сторону.
Windows 10, HTTP, MegaD, Z-Wave, 1-Wire, CONNECT
Ответить