Страница 1 из 5

Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 5:02 pm
Krz
Я человек в меру забывчивый и иногда что-то может вылететь из головы. По сему, реализовал у себя голосовые напоминания, срабатывающие в указанное время.
Напоминания устанавливаются фразами, начинающимися со слова "Напомни", а далее указывается время в которое, или через сколько, система должна сработать.
Примеры:
  • Напомни через 15 минут выключить суп.
  • Напомни через 4 часа сходить в магазин
  • Напомни через 251 секунду о пельменях
  • Напомни в 15:00 позвонить другу
  • Напомни сегодня в 20:15 выгулять собаку
  • Напомни завтра в 11:59 посмотреть новости
  • Напомни послезавтра в 12:30 заплатить за Интернет

Если команды давать голосом через мобильное приложение или расширение для Chrome, то еще удобней становится.

А дальше... Не пинайте меня, с системой Мажордомо начал разбираться совсем недавно, программную часть клепал на коленке для себя, натужно вспоминая синтаксис PHP.
Возможно, все можно было реализовать проще и красивее, но что получилось, то получилось и оно работает. Конструктивную критику готов принять.

Реализация:
В разделе "Панель управления/Шаблоны поведения" создаем шаблон "Напоминание" (можно дать и другое имя)
По надобности ставим галочки "не проверять другие шаблоны при совпадении" и "Не реагировать на системные сообщения"
У кого подключена морфология обязательно проверить, чтобы галочка "Use morphology" не стояла.
Задаем шаблон:

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

(Н|н)апомни ((через \d+ (часа|час|минут|минуту|минуты|секунд|секунды|секунду))|в \d+:\d+|(завтра|послезавтра|сегодня|на завтра|на послезавтра) в \d+:\d+) (.+) 
Выполнить при совпадении код PHP

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

$u=5;
$naptime = mb_strtolower($matches[2]);
$request = mb_strtolower($matches[6]);
if ($request!='') {
$su=0;
$naptime=str_replace(" на ", " ", $naptime);
if (stristr($naptime, "сегодня") != FALSE) {$naptime = str_replace("сегодня ", "", $naptime); $su=0;}
if (stristr($naptime, "послезавтра") != FALSE) {$naptime = str_replace("послезавтра ", "", $naptime); $su=2;}
if (stristr($naptime, "завтра") != FALSE) {$naptime = str_replace("завтра", "", $naptime); $su=1;}
$a=$su*86400+recognizeTime($naptime,$b);
if(time()<($a-60)){
$nday=date( "j" , $a);
$MonthNames=array("января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря");
$nmes=date( "n" , $a)-1;
$nmonth=$MonthNames[$nmes];
$ntime=date( "H:i" , $a);
$chisl = array(1=> 'первое',2=> 'второе',3=> 'третье',4=> 'четвертое',5=> 'пятое',6=> 'шестое',7=> 'седьмое',8=> 'восьмое',9=> 'девятое',10=> 'десятое',11=> 'одиннадцатое',12=> 'двенадцатое',13=> 'тринадцатое',14=> 'четырнадцатое' ,15=> 'пятнадцатое',16=> 'шестнадцатое',17=> 'семнадцатое',18=> 'восемнадцатое',19=> 'девятнадцатое',20=> 'двадцатое',30=> 'тридцатое',21=> 'двадцать',31=> 'тридцать');
if ($nday<21||$nday==30) {$chtext=$chisl[$nday];} else {$chtext=$chisl[(int)($nday/10)*10+1].' '.$chisl[$nday % 10] ;}
AddScheduledJob($request,"playSound('opoveshenie.mp3'); say('Вы просили напомнить ".$request."',".$u.");",$a, 60);
say("Задание напомнить ".$request." установлено на ".$chtext." ".$nmonth." в ".$ntime,$u);}
else
{say("Назначить напоминание на заданное время невозможно!",$u);}}
else
{say("Непонятно, что напомнить?!",$u);} 
Первая строка задает уровень важности фраз, выводимых командой say (смотри документацию), можно оставить так или выбрать уровень необходимый вам.

Для выделения напоминаний добавил дополнительный звук командой playSound('opoveshenie.mp3');
Если вам звук не нужен удалите ее. В противном случае добавьте звук opoveshenie.mp3 в систему, через раздел "Панель управления/Настройки/Звуковые файлы" (мой вариант прикреплен к сообщению в архиве, перед добавлением в систему распаковать)
opoveshenie.zip
Дополнительное звуковое оповещение
(203.95 КБ) 321 скачивание
Да, еще, напоминание на прошедшее время или на время ближе чем через 60 секунд не устанавливается.
Каждое напоминание срабатывает только один раз, сколько максимально одновременно возможно задать напоминаний не проверял, главное давать разное задание. При перезагрузке системы все "ненапомненные" задания сохраняются.


Отмена напоминаний

На фразу "Отмени напоминание..." система удаляет задание
Примеры фраз:
  • Отмени напоминание выключить суп.
  • Отмени напоминание выгулять собаку
  • Отмени напоминание о пельменях
Реализация
В разделе "Панель управления/Шаблоны поведения" создаем шаблон "Отмена напоминаний" (можно дать и другое имя)
По надобности ставим галочки "не проверять другие шаблоны при совпадении" и "Не реагировать на системные сообщения"
У кого подключена морфология обязательно проверить, чтобы галочка "Use morphology" не стояла.
Задаем шаблон:

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

(О|о)тмени напоминание (.+) 
Выполнить при совпадении код PHP

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

$u=5;
$naptime = mb_strtolower($matches[2]);
ClearScheduledJob($naptime);
say('Напоминание '.$naptime.' отменено!',$u); 
Главное, чтобы фраза напоминания совпадала с той, которой вы создали напоминание, тогда система его отменит.

В данном сообщении откорректированная версия, с исправлением недочетов.

Re: Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 6:15 pm
Logrus
не помню у кого позаимствовал (оставлю здесь, это проще, а свыше скопирую и вдруг ... ))) )
(Н|н)апомни через (.+) минут(|у|ы) (.+)

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

$rnumber = 1;
while (1) {
  $rname = "Remind_$rnumber";
  if (!timeOutExists($rname)) break;
  $rnumber++;
}

if ($matches[2] =='одну' or $matches[2] =='1') {$matches[2]='1';
  setTimeOut($rname,'sayReply("Напоминаю: '.$matches[4].'");',$matches[2]*60,2); 
sayReply("Принято напоминание - напомнить через одну минуту: $matches[4]",2);       
                          }
elseif ($matches[2] =='две' or $matches[2] =='2') {$matches[2]='2';
  setTimeOut($rname,'sayReply("Напоминаю: '.$matches[4].'");',$matches[2]*60,2); 
sayReply("Принято напоминание - напомнить через две минуты: $matches[4]",2);                      
                             }
elseif ($matches[2] =='три' or $matches[2] =='3') {$matches[2]='3';
  setTimeOut($rname,'sayReply("Напоминаю: '.$matches[4].'");',$matches[2]*60,2); 
sayReply("Принято напоминание - напомнить через три минуты: $matches[4]",2);                         
                             }
elseif ($matches[2] =='четыре' or $matches[2] =='4') {$matches[2]='4';
   setTimeOut($rname,'sayReply("Напоминаю: '.$matches[4].'");',$matches[2]*60,2); 
sayReply("Принято напоминание - напомнить через четыре минуты: $matches[4]",2);                         
                                }
else {
setTimeOut($rname,'sayReply("Напоминаю: '.$matches[4].'");',$matches[2]*60,2); 
sayReply("Принято напоминание - напомнить через $matches[2] минут: $matches[4]",2);
}

Re: Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 6:24 pm
Logrus
запомни (.+)

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

$text=$matches[1];
$filename='./texts/memory.txt';
runScript('InFile',array('subject'=>'Текст:','body'=>$text,'filename'=>$filename));
sayReply('Выполнено. Всё запомнила в файл.',1);
скрипт InFile

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

$date=gg('Date.Date');
$timeNow=gg('ThisComputer.timeNow');

$subject=$params['subject'];
$body=$params['body'];
$filename=$params['filename'];

file_put_contents($filename,$date.' : '.$timeNow.PHP_EOL.$body.PHP_EOL,FILE_APPEND);
(что запомнила|из файла|что помнишь|напомни)

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

$arr=file('./texts/memory.txt');
 for($i=0; $i<count($arr); $i++) {
  sayReply($arr[$i],2);
}

Re: Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 6:47 pm
Logrus
Krz писал(а): Да, еще, напоминание на прошедшее время или на время ближе чем через 60 секунд не устанавливается.
не работает:
20:44 Александр: Напомни через одну минуту попить чай
20:43 Александр: Напомни через две минуты попить чай
20:43 Александр: Напомни через три минуты попить чаю

во втором варианте это работает

playSound('opoveshenie')

else
{say('Назначить напоминание на заданное время невозможно!',$u);}}
else
{say('Непонятно, что напомнить?!',$u);}

Re: Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 7:30 pm
TheForum
Logrus, а что у тебя в $date=gg('Date.Date'); ? У меня нету, что подставить? И что ты имеешь ввиду во втором варианте работает? Это в твоем?

Re: Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 7:45 pm
Logrus
чч.мм.гггг что поставишь
СпойлерПоказать

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

if (gg('ThisComputer.DateD') != date('d', time())) {

   $day=array(
       'воскресенье', 'понедельник', 'вторник', 'среда',
       'четверг', 'пятница', 'суббота'
   ); 

   $month=array(
       1 => 'января', 2 => 'февраля', 3 => 'марта', 4 => 'апреля',
       5 => 'мая', 6 => 'июня', 7 => 'июля', 8 => 'августа',
       9 => 'сентября', 10 => 'октября', 11 => 'ноября', 12 => 'декабря'
   );

   $monthAlt=array(
       1 => 'ЯНВАРЬ', 2 => 'ФЕВРАЛЬ', 3 => 'МАРТ', 4 => 'АПРЕЛЬ',
       5 => 'МАЙ', 6 => 'ИЮНЬ', 7 => 'ИЮЛЬ', 8 => 'АВГУСТ',
       9 => 'СЕНТЯБРЬ', 10 => 'ОКТЯБРЬ', 11 => 'НОЯБРЬ', 12 => 'ДЕКАБРЬ'
   );
   // раскидываем дату по свойствам  
   sg('Date.DateD',date('d', time()));
   sg('Date.DateJ',date('j', time()));
   sg('Date.DateM',date('m', time()));
   sg('Date.DateN',date('n', time()));
   sg('Date.DateY',date('Y', time()));
   sg('Date.Date',date('d.m.Y', time()));
   sg('Date.Day',$day[date('w')]);
   sg('Date.Month',$month[date('n')]);
   sg('Date.MonthAlt',$monthAlt[date('n')]);
}
во втором посту что, хз, чей

Re: Реализация голосовых напоминаний

Добавлено: Сб мар 24, 2018 10:18 pm
fandaymon
Krz писал(а):Я человек в меру забывчивый и иногда что-то может вылететь из головы. По сему, реализовал у себя голосовые напоминания, срабатывающие в указанное время.
Сам реализовал напоминания через API.AI, но идея и пример как вытащить нужную информацию прям шаблоном очень достойная - спасибо. И отдельное спасибо за идею с AddScheduledJob. Сам заношу напоминания в гугл календарь, но мысль воспользоватся мажордомо как ещё одним каналом информации меня тоже посещала.
Единственная проблема с данным алгоритмом будет в том, что гугл не всегда распознаёт цифры произнесенные голосом именно как цифры - может распознать и так - через три минуты. Шаблон такое не отберёт...

Re: Реализация голосовых напоминаний

Добавлено: Вс мар 25, 2018 7:27 am
Krz
Да, столкнулся с этим, что распознавание голоса срабатывает не всегда так как надо.
Хочешь: Напомни через 2 минуты помешать суп
Получаешь: Напомни через две минуты помешать суп
Соответственно шаблон не срабатывает.
Опытным путем выяснил, что гугл заменяет на слова только маленькие числа, поэтому использую обходной вариант: Напомни через 120 секунд помешать суп. Ну или называть конкретное время.
С командами набираемыми вручную таких проблем естественно нет.

Re: Реализация голосовых напоминаний

Добавлено: Вс мар 25, 2018 10:41 am
Krz
Вот исправленная версия.
Числа заданные словами (от 1 до 9) исправляются

Шаблон

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

[Нн]апомни ((через (\d+|один|одну|дв[ае]|три|четыре|пять|шесть|семь|восемь|девять) (часа|час|часов|минут|минуту|минуты|секунд|секунды|секунду))|в \d+:\d+|(завтра|послезавтра|сегодня|на завтра|на послезавтра) в \d+:\d+) (.+) 
Код PHP

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

$u=5;
$naptime = mb_strtolower($matches[1]);
$request = mb_strtolower($matches[6]);
$chislo = array('один'=> '1','одну'=> '1','два'=> '2','две'=> '2','три'=> '3','четыре'=> '4','пять'=> '5','шесть'=> '6','семь'=> '7','восемь'=> '8','девять'=> '9');
foreach($chislo as $key => $value) {$naptime =str_replace($key,$value,$naptime);}
if ($request!='') {
$su=0;
$naptime=str_replace(" на ", " ", $naptime);
if (stristr($naptime, "сегодня") != FALSE) {$naptime = str_replace("сегодня ", "", $naptime); $su=0;}
if (stristr($naptime, "послезавтра") != FALSE) {$naptime = str_replace("послезавтра ", "", $naptime); $su=2;}
if (stristr($naptime, "завтра") != FALSE) {$naptime = str_replace("завтра", "", $naptime); $su=1;}
$a=$su*86400+recognizeTime($naptime,$b);
if(time()<($a-30)){
$nday=date( "j" , $a);
$MonthNames=array("января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря");
$nmes=date( "n" , $a)-1;
$nmonth=$MonthNames[$nmes];
$ntime=date( "H:i" , $a);
$chisl = array(1=> 'первое',2=> 'второе',3=> 'третье',4=> 'четвертое',5=> 'пятое',6=> 'шестое',7=> 'седьмое',8=> 'восьмое',9=> 'девятое',10=> 'десятое',11=> 'одиннадцатое',12=> 'двенадцатое',13=> 'тринадцатое',14=> 'четырнадцатое' ,15=> 'пятнадцатое',16=> 'шестнадцатое',17=> 'семнадцатое',18=> 'восемнадцатое',19=> 'девятнадцатое',20=> 'двадцатое',30=> 'тридцатое',21=> 'двадцать',31=> 'тридцать');
if ($nday<21||$nday==30) {$chtext=$chisl[$nday];} else {$chtext=$chisl[(int)($nday/10)*10+1].' '.$chisl[$nday % 10] ;}
AddScheduledJob($request,"playSound('opoveshenie.mp3'); say('Вы просили напомнить ".$request."',".$u.");",$a, 60);
say("Задание напомнить ".$request." установлено на ".$chtext." ".$nmonth." в ".$ntime,$u);}
else
{say("Назначить напоминание на заданное время невозможно!",$u);}}
else
{say("Непонятно, что напомнить?!",$u);} 
P.S.
Время до напоминания ограничил 30-ю секундами. Т.е. задать интервал до напоминания ближе 30 секунд система не даст.

Re: Реализация голосовых напоминаний

Добавлено: Вс мар 25, 2018 6:30 pm
Logrus
из телеги: (на вопрос Алиса не разговаривает, обиделась) "Я ей Спасибо говорил" :)
не любит она чай (
СпойлерПоказать
20:29 Алиса: К Вашим услугам!
20:29 Александр: Спасибо
20:28 Алиса: Вы просили напомнить попить
20:26 Алиса: Вы просили напомнить попить
20:25 Алиса: Задание напомнить попить установлено на двадцать пятое марта в 20:28
20:24 Александр: Напомни через три минуты попить чаю
20:24 Алиса: Задание напомнить попить установлено на двадцать пятое марта в 20:26
20:24 Александр: Напомни через две минуты попить чай
п.с. самое странное она не отменяет попить, хотя оно с таким именем, но отменяет попить чаю 0_0 (точно обиделась)

поставил ограничение 180 с.
СпойлерПоказать
20:51 Алиса: Напоминание попить чай с отменено!
20:51 Александр: Отмени напоминание попить чай с сахаром
20:50 Алиса: Задание напомнить попить чай с установлено на двадцать пятое марта в 20:52
20:50 Александр: Напомни через две минуты попить чай с сахаром
точно обиделась :lol:
СпойлерПоказать
20:54 Алиса: Задание напомнить попить чай с сахаром@@@@напомни через две минуты попить чай с сахаром@@@@напомни через две минуты попить чай с установлено на двадцать пятое марта в 20:56
20:54 Александр: Напомни через две минуты попить чай с сахаром
Собака.PNG
Собака.PNG (26.43 КБ) 6668 просмотров