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

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Аватара пользователя
Krz
Сообщения: 22
Зарегистрирован: Сб мар 24, 2018 3:51 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 КБ) 390 скачиваний
Да, еще, напоминание на прошедшее время или на время ближе чем через 60 секунд не устанавливается.
Каждое напоминание срабатывает только один раз, сколько максимально одновременно возможно задать напоминаний не проверял, главное давать разное задание. При перезагрузке системы все "ненапомненные" задания сохраняются.


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

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

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

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

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

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

В данном сообщении откорректированная версия, с исправлением недочетов.
Последний раз редактировалось Krz Вс мар 25, 2018 10:43 am, всего редактировалось 1 раз.
Изображение
Изображение
Logrus
Сообщения: 2113
Зарегистрирован: Пт апр 07, 2017 12:20 pm

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

Сообщение 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);
}
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Logrus
Сообщения: 2113
Зарегистрирован: Пт апр 07, 2017 12:20 pm

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

Сообщение 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);
}
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Logrus
Сообщения: 2113
Зарегистрирован: Пт апр 07, 2017 12:20 pm

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

Сообщение Logrus »

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

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

playSound('opoveshenie')

else
{say('Назначить напоминание на заданное время невозможно!',$u);}}
else
{say('Непонятно, что напомнить?!',$u);}
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
TheForum
Сообщения: 146
Зарегистрирован: Сб авг 06, 2016 2:11 am
Откуда: Рига

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

Сообщение TheForum »

Logrus, а что у тебя в $date=gg('Date.Date'); ? У меня нету, что подставить? И что ты имеешь ввиду во втором варианте работает? Это в твоем?
Немного желания, терпения и времени - и все получится :)
Logrus
Сообщения: 2113
Зарегистрирован: Пт апр 07, 2017 12:20 pm

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

Сообщение Logrus »

чч.мм.гггг что поставишь
SPOILERSPOILER_SHOW

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

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')]);
}
во втором посту что, хз, чей
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
fandaymon
Сообщения: 1576
Зарегистрирован: Сб янв 13, 2018 5:00 pm

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

Сообщение fandaymon »

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

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

Сообщение Krz »

Да, столкнулся с этим, что распознавание голоса срабатывает не всегда так как надо.
Хочешь: Напомни через 2 минуты помешать суп
Получаешь: Напомни через две минуты помешать суп
Соответственно шаблон не срабатывает.
Опытным путем выяснил, что гугл заменяет на слова только маленькие числа, поэтому использую обходной вариант: Напомни через 120 секунд помешать суп. Ну или называть конкретное время.
С командами набираемыми вручную таких проблем естественно нет.
Изображение
Изображение
Аватара пользователя
Krz
Сообщения: 22
Зарегистрирован: Сб мар 24, 2018 3:51 pm
Откуда: Сибирь

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

Сообщение 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 секунд система не даст.
Изображение
Изображение
Logrus
Сообщения: 2113
Зарегистрирован: Пт апр 07, 2017 12:20 pm

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

Сообщение Logrus »

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

поставил ограничение 180 с.
SPOILERSPOILER_SHOW
20:51 Алиса: Напоминание попить чай с отменено!
20:51 Александр: Отмени напоминание попить чай с сахаром
20:50 Алиса: Задание напомнить попить чай с установлено на двадцать пятое марта в 20:52
20:50 Александр: Напомни через две минуты попить чай с сахаром
точно обиделась :lol:
SPOILERSPOILER_SHOW
20:54 Алиса: Задание напомнить попить чай с сахаром@@@@напомни через две минуты попить чай с сахаром@@@@напомни через две минуты попить чай с установлено на двадцать пятое марта в 20:56
20:54 Александр: Напомни через две минуты попить чай с сахаром
Собака.PNG
Собака.PNG (26.43 КБ) 7941 просмотр
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Ответить