Всем привет!
Кто не хочет роскошь иметь помощника, который всегда прислушивается к вашему звонку, предвидит все ваши потребности и при необходимости принимает меры? Эта роскошь теперь доступна благодаря голосовым помощникам на основе искусственного интеллекта.
Голосовые помощники поставляются в небольших упаковках и могут выполнять различные действия, услышав вашу команду. Они могут включать свет, отвечать на вопросы, играть музыку, размещать онлайн-заказы и делать все виды искусственного интеллекта.
Голосовых помощников не следует путать с виртуальными помощниками, которые являются людьми, которые работают удаленно и поэтому могут выполнять все виды задач. Голосовые помощники основаны на технологии. По мере того, как голосовые помощники становятся более надежными, их полезность как в личной, так и в деловой сферах будет расти.
Что такое голосовой помощник?
Голосовой помощник или интеллектуальный личный помощник — это программный агент, который может выполнять задачи или услуги для человека на основе словесных команд, то есть путем интерпретации человеческой речи и ответа посредством синтезированных голосов. Пользователи могут задавать вопросы своему помощнику, с помощью устных команд, управлять устройствами домашней автоматизации и воспроизведением мультимедиа с помощью голоса, а также управлять другими основными задачами, такими как электронная почта, списки дел, открывать или закрывать любое приложение и т.д.
Позвольте мне привести вам пример Braina (Brain Artificial), которая является интеллектуальным личным помощником, интерфейсом на человеческом языке, программным обеспечением для автоматизации и распознавания голоса для ПК с Windows. Braina — это многофункциональное программное обеспечение для искусственного интеллекта, которое позволяет вам взаимодействовать с вашим компьютером с помощью голосовых команд на большинстве языков мира. Braina, помимо этого, точно преобразовывает речь в текст на более чем 100 разных языках мира.
История Голосовых Помощников
В последнее время голосовые помощники получили основную платформу после того, как Apple интегрировала самый удивительный Virtual Assistant — Siri, который официально является частью Apple Inc. Но график наибольшего развития начался с события 1962 года на выставке в Сиэтле, где IBM представила уникальный аппарат под названием Shoebox. Это был аппарат размером с обувную коробку, он мог выполнять научные функции и мог воспринимать 16 слов, а также произносить их человеческим узнаваемым голосом, и цифры от 0 до 9.
В течение 1970-х годов исследователи из Университета Карнеги-Меллона в Питтсбурге, штат Пенсильвания, при существенной помощи Министерства обороны США и его Агентства перспективных исследований в области обороны (DARPA), создали Harpy. Она могла понимать почти 1000 слов, что примерно соответствует словарному запасу трехлетнего ребенка.
Крупные организации, такие как Apple и IBM, рано, в 90-х годах, начали создавать вещи, использующие голосовое подтверждение. В 1993 году Macintosh начал создавать системы распознавания речи на своих компьютерах Macintosh с PlainTalk.
В апреле 1997 года Dragon NaturallySpeaking был первым продуктом с постоянной диктовкой, который мог охватить около 100 слов и преобразовать его в читаемый контент.
После всего вышесказанного, как здорово было бы создать простой голосовой помощник на рабочем столе/ноутбуке, который мог бы:
- Открыть subreddit в браузере;
- Открыть любой веб-сайт в браузере;
- Отправить электронное письмо своим контактам;
- Запустить любое системное приложение;
- Сообщить текущую погоду и температуру любого города;
- Сообщить текущее время;
- Поприветствовать / завершить работу;
- Воспроизвести песню на медиаплеере VLC (конечно, на вашем ноутбуке / настольном компьютере должен быть установлен медиаплеер VLC);
- Изменить обои для рабочего стола;
- Сообщить вам последние новости из новостной ленты;
- Рассказать практически обо всем, что вы просите.
Итак, здесь, в этой статье, мы собираемся создать голосовое приложение, способное выполнять все вышеупомянутые задачи. Но сначала, посмотрите это видео, которое я сделал, когда общался со своим настольным голосовым помощником. И я зову ее София.
Надеюсь, вам, ребята, понравилось вышеупомянутое видео, в котором я общался с Софией. Теперь давайте начнем строить эту классную штуку.
Перед началом изучения рекомендую подробнее почитать о голосовых помощниках, а также следить за новостями в моём телеграм-канале Нейрон (@dataisopen), чтобы не пропустить интересные статьи.Необходимые системные требования: Python 2.7, Spyder IDE, MacOS Mojave (версия 10.14)
Установите все эти библиотеки Python:
pip install SpeechRecognition
pip install beautifulsoup4
pip install vlc
pip install youtube-dl
pip install pyowm
pip install wikipedia
Давайте начнем создавать наш настольный голосовой помощник с Python
Начните с импорта всех необходимых библиотек:
import speech_recognition as sr
import os
import sys
import re
import webbrowser
import smtplib
import requests
import subprocess
from pyowm import OWM
import youtube_dl
import vlc
import urllib
import urllib2
import json
from bs4 import BeautifulSoup as soup
from urllib2 import urlopen
import wikipedia
import random
from time import strftime
Чтобы наш голосовой помощник выполнил все рассмотренные выше функции, мы должны закодировать логику каждой из них одним способом.
Итак, наш первый шаг — создать метод, который будет интерпретировать голосовой ответ пользователя:
def myCommand():
r = sr.Recognizer()
with sr.Microphone() as source:
print('Say something...')
r.pause_threshold = 1
r.adjust_for_ambient_noise(source, duration=1)
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('....')
command = myCommand();
return command
Затем создайте метод, который будет преобразовывать текст в речь:
def sofiaResponse(audio):
print(audio)
for line in audio.splitlines():
os.system("say " + audio)
Теперь создадим цикл, чтобы продолжить выполнение нескольких команд. Внутри метода assistant () передается пользовательская команда (myCommand ()) в качестве параметра:
while True:
assistant(myCommand())
Наш следующий шаг — создать несколько операторов if, соответствующих каждой функции. Итак, давайте посмотрим, как создать эти небольшие модули внутри оператора if для каждой команды.
1. Открыть subreddit Reddit в браузере
Пользователь даст любую команду, чтобы открыть любой subreddit из Reddit, и команда должна быть «Эй, София! Можешь ли ты open Reddit subreddit_name».То, что выделено жирным курсивом следует использовать как есть. Вы можете использовать любой вид префикса, просто позаботьтесь о том, что выделено жирным.
if 'open reddit' in command:
reg_ex = re.search('open reddit (.*)', command)
url = 'https://www.reddit.com/'
if reg_ex:
subreddit = reg_ex.group(1)
url = url + 'r/' + subreddit
webbrowser.open(url)
sofiaResponse('The Reddit content has been opened for you Sir.')
Таким образом, приведенный выше код откроет нужный вам Reddit в браузере по умолчанию.
2. Открыть любой веб-сайт в браузере
Вы можете открыть любой веб-сайт, просто сказав «open website.com» или «open website.org».
Например: «Пожалуйста, открой facebook» или «Эй, вы можете открыть linkedin», так вы можете попросить Софию открыть любой веб-сайт.
elif 'open' in command:
reg_ex = re.search('open (.+)', command)
if reg_ex:
domain = reg_ex.group(1)
print(domain)
url = 'https://www.' + domain
webbrowser.open(url)
sofiaResponse('The website you have requested has been opened for you Sir.')
else:
pass
3. Отправить e-mail
Вы также можете попросить вашего настольного помощника отправить электронное письмо.
elif 'email' in command:
sofiaResponse('Who is the recipient?')
recipient = myCommand()
if 'rajat' in recipient:
sofiaResponse('What should I say to him?')
content = myCommand()
mail = smtplib.SMTP('smtp.gmail.com', 587)
mail.ehlo()
mail.starttls()
mail.login('your_email_address', 'your_password')
mail.sendmail('sender_email', 'receiver_email', content)
mail.close()
sofiaResponse('Email has been sent successfuly. You can check your inbox.')
else:
sofiaResponse('I don\'t know what you mean!')
4. Запустить любое системное приложение
Скажите «Открой календарь» или «Можешь, пожалуйста, запустить Skype» или «София, открой Finder» и т.д. И София запустит для вас это системное приложение.
elif 'launch' in command:
reg_ex = re.search('launch (.*)', command)
if reg_ex:
appname = reg_ex.group(1)
appname1 = appname+".app"
subprocess.Popen(["open", "-n", "/Applications/" + appname1], stdout=subprocess.PIPE)
sofiaResponse('I have launched the desired application')
5. Сообщить текущую погоду и температуру любого города
София также может сказать вам погоду, максимальную и минимальную температуру любого города мира. Пользователь просто должен сказать что-то вроде «какая сейчас погода в Лондоне» или «скажи мне текущую погоду в Дели».
elif 'current weather' in command:
reg_ex = re.search('current weather in (.*)', command)
if reg_ex:
city = reg_ex.group(1)
owm = OWM(API_key='ab0d5e80e8dafb2cb81fa9e82431c1fa')
obs = owm.weather_at_place(city)
w = obs.get_weather()
k = w.get_status()
x = w.get_temperature(unit='celsius')
sofiaResponse('Current weather in %s is %s. The maximum temperature is %0.2f and the minimum temperature is %0.2f degree celcius' % (city, k, x['temp_max'], x['temp_min']))
6. Сообщить текущее время
«София, ты можешь сказать мне текущее время?» Или «Который сейчас час?», и София скажет вам текущее время вашего часового пояса.
elif 'time' in command:
import datetime
now = datetime.datetime.now()
sofiaResponse('Current time is %d hours %d minutes' % (now.hour, now.minute))
7. Приветствие / Завершение
Скажите «Здравствуй, София», чтобы поприветствовать своего голосового помощника, или, когда хотите, чтобы программа завершилась, произнесите что-то вроде «Заверши работу, София» или «София, пожалуйста, заверши работу» и т.д.
#Greet Sofia
elif 'hello' in command:
day_time = int(strftime('%H'))
if day_time < 12:
sofiaResponse('Hello Sir. Good morning')
elif 12 <= day_time < 18:
sofiaResponse('Hello Sir. Good afternoon')
else:
sofiaResponse('Hello Sir. Good evening')
#to terminate the program
elif 'shutdown' in command:
sofiaResponse('Bye bye Sir. Have a nice day')
sys.exit()
8. Воспроизведение песни на медиаплеере VLC
Эта функция позволяет вашему голосовому боту воспроизводить желаемую песню в медиаплеере VLC. Пользователь скажет «София, сыграй мне песню», бот спросит: «Какую песню мне сыграть?». Просто скажите название песни, и София загрузит песню с youtube на ваш локальный диск, воспроизведите эту песню на медиаплеере VLC, и если вы снова воспроизведете песню, ранее загруженная песня будет автоматически удалена.
Теперь, если в следующий раз вы запросите любую другую песню, локальный каталог будет сброшен, и в этот каталог будет загружена новая песня.
elif 'play me a song' in command:
path = '/Users/nageshsinghchauhan/Documents/videos/'
folder = path
for the_file in os.listdir(folder):
file_path = os.path.join(folder, the_file)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
except Exception as e:
print(e)
sofiaResponse('What song shall I play Sir?')
mysong = myCommand()
if mysong:
flag = 0
url = "https://www.youtube.com/results?search_query=" + mysong.replace(' ', '+')
response = urllib2.urlopen(url)
html = response.read()
soup1 = soup(html,"lxml")
url_list = []
for vid in soup1.findAll(attrs={'class':'yt-uix-tile-link'}):
if ('https://www.youtube.com' + vid['href']).startswith("https://www.youtube.com/watch?v="):
flag = 1
final_url = 'https://www.youtube.com' + vid['href']
url_list.append(final_url)
url = url_list[0]
ydl_opts = {}
os.chdir(path)
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
vlc.play(path)
if flag == 0:
sofiaResponse('I have not found anything in Youtube ')
9. Изменить обои для рабочего стола
Вы, также можете изменить обои для рабочего стола, используя эту функцию. Когда вы говорите что-то вроде «Поменять обои» или «София, пожалуйста, поменяй обои», бот загрузит случайные обои с unsplash.com и установит их в качестве фона рабочего стола.
Теперь, если в следующий раз вы попросите изменить обои снова, ваш локальный каталог будет сброшен, и новые обои будут загружены в этот каталог.
elif 'change wallpaper' in command:
folder = '/Users/nageshsinghchauhan/Documents/wallpaper/'
for the_file in os.listdir(folder):
file_path = os.path.join(folder, the_file)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
except Exception as e:
print(e)
api_key = 'fd66364c0ad9e0f8aabe54ec3cfbed0a947f3f4014ce3b841bf2ff6e20948795'
url = 'https://api.unsplash.com/photos/random?client_id=' + api_key #pic from unspalsh.com
f = urllib2.urlopen(url)
json_string = f.read()
f.close()
parsed_json = json.loads(json_string)
photo = parsed_json['urls']['full']
urllib.urlretrieve(photo, "/Users/nageshsinghchauhan/Documents/wallpaper/a") # Location where we download the image to.
subprocess.call(["killall Dock"], shell=True)
sofiaResponse('wallpaper changed successfully')
10. Сообщить последние новости из новостной ленты
София также может рассказать вам последние новости. Пользователь просто должен сказать «София, какие новости сегодня самые популярные?» Или «Скажите мне новости на сегодня».
elif 'news for today' in command:
try:
news_url="https://news.google.com/news/rss"
Client=urlopen(news_url)
xml_page=Client.read()
Client.close()
soup_page=soup(xml_page,"xml")
news_list=soup_page.findAll("item")
for news in news_list[:15]:
sofiaResponse(news.title.text.encode('utf-8'))
except Exception as e:
print(e)
11. Рассказать практически обо всем, что вы спрашиваете
Ваш бот может получить подробную информацию практически обо всем, что вы у нее спросите. Например, «София расскажи мне о Google» или «Пожалуйста, расскажи мне о суперкомпьютерах» или «Пожалуйста, расскажи мне об Интернете». Итак, как вы можете видеть, вы можете спросить о чем угодно.
elif 'tell me about' in command:
reg_ex = re.search('tell me about (.*)', command)
try:
if reg_ex:
topic = reg_ex.group(1)
ny = wikipedia.page(topic)
sofiaResponse(ny.content[:500].encode('utf-8'))
except Exception as e:
sofiaResponse(e)
Давайте сложим все вместе:
import speech_recognition as sr
import os
import sys
import re
import webbrowser
import smtplib
import requests
import subprocess
from pyowm import OWM
import youtube_dl
import vlc
import urllib
import urllib2
import json
from bs4 import BeautifulSoup as soup
from urllib2 import urlopen
import wikipedia
import random
from time import strftime
def sofiaResponse(audio):
"speaks audio passed as argument"
print(audio)
for line in audio.splitlines():
os.system("say " + audio)
def myCommand():
"listens for commands"
r = sr.Recognizer()
with sr.Microphone() as source:
print('Say something...')
r.pause_threshold = 1
r.adjust_for_ambient_noise(source, duration=1)
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('....')
command = myCommand();
return command
def assistant(command):
"if statements for executing commands"
#open subreddit Reddit
if 'open reddit' in command:
reg_ex = re.search('open reddit (.*)', command)
url = 'https://www.reddit.com/'
if reg_ex:
subreddit = reg_ex.group(1)
url = url + 'r/' + subreddit
webbrowser.open(url)
sofiaResponse('The Reddit content has been opened for you Sir.')
elif 'shutdown' in command:
sofiaResponse('Bye bye Sir. Have a nice day')
sys.exit()
#open website
elif 'open' in command:
reg_ex = re.search('open (.+)', command)
if reg_ex:
domain = reg_ex.group(1)
print(domain)
url = 'https://www.' + domain
webbrowser.open(url)
sofiaResponse('The website you have requested has been opened for you Sir.')
else:
pass
#greetings
elif 'hello' in command:
day_time = int(strftime('%H'))
if day_time < 12:
sofiaResponse('Hello Sir. Good morning')
elif 12 <= day_time < 18:
sofiaResponse('Hello Sir. Good afternoon')
else:
sofiaResponse('Hello Sir. Good evening')
elif 'help me' in command:
sofiaResponse("""
You can use these commands and I'll help you out:
1. Open reddit subreddit : Opens the subreddit in default browser.
2. Open xyz.com : replace xyz with any website name
3. Send email/email : Follow up questions such as recipient name, content will be asked in order.
4. Current weather in {cityname} : Tells you the current condition and temperture
5. Hello
6. play me a video : Plays song in your VLC media player
7. change wallpaper : Change desktop wallpaper
8. news for today : reads top news of today
9. time : Current system time
10. top stories from google news (RSS feeds)
11. tell me about xyz : tells you about xyz
""")
#joke
elif 'joke' in command:
res = requests.get(
'https://icanhazdadjoke.com/',
headers={"Accept":"application/json"})
if res.status_code == requests.codes.ok:
sofiaResponse(str(res.json()['joke']))
else:
sofiaResponse('oops!I ran out of jokes')
#top stories from google news
elif 'news for today' in command:
try:
news_url="https://news.google.com/news/rss"
Client=urlopen(news_url)
xml_page=Client.read()
Client.close()
soup_page=soup(xml_page,"xml")
news_list=soup_page.findAll("item")
for news in news_list[:15]:
sofiaResponse(news.title.text.encode('utf-8'))
except Exception as e:
print(e)
#current weather
elif 'current weather' in command:
reg_ex = re.search('current weather in (.*)', command)
if reg_ex:
city = reg_ex.group(1)
owm = OWM(API_key='ab0d5e80e8dafb2cb81fa9e82431c1fa')
obs = owm.weather_at_place(city)
w = obs.get_weather()
k = w.get_status()
x = w.get_temperature(unit='celsius')
sofiaResponse('Current weather in %s is %s. The maximum temperature is %0.2f and the minimum temperature is %0.2f degree celcius' % (city, k, x['temp_max'], x['temp_min']))
#time
elif 'time' in command:
import datetime
now = datetime.datetime.now()
sofiaResponse('Current time is %d hours %d minutes' % (now.hour, now.minute))
elif 'email' in command:
sofiaResponse('Who is the recipient?')
recipient = myCommand()
if 'rajat' in recipient:
sofiaResponse('What should I say to him?')
content = myCommand()
mail = smtplib.SMTP('smtp.gmail.com', 587)
mail.ehlo()
mail.starttls()
mail.login('your_email_address', 'your_password')
mail.sendmail('sender_email', 'receiver_email', content)
mail.close()
sofiaResponse('Email has been sent successfuly. You can check your inbox.')
else:
sofiaResponse('I don\'t know what you mean!')
#launch any application
elif 'launch' in command:
reg_ex = re.search('launch (.*)', command)
if reg_ex:
appname = reg_ex.group(1)
appname1 = appname+".app"
subprocess.Popen(["open", "-n", "/Applications/" + appname1], stdout=subprocess.PIPE)
sofiaResponse('I have launched the desired application')
#play youtube song
elif 'play me a song' in command:
path = '/Users/nageshsinghchauhan/Documents/videos/'
folder = path
for the_file in os.listdir(folder):
file_path = os.path.join(folder, the_file)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
except Exception as e:
print(e)
sofiaResponse('What song shall I play Sir?')
mysong = myCommand()
if mysong:
flag = 0
url = "https://www.youtube.com/results?search_query=" + mysong.replace(' ', '+')
response = urllib2.urlopen(url)
html = response.read()
soup1 = soup(html,"lxml")
url_list = []
for vid in soup1.findAll(attrs={'class':'yt-uix-tile-link'}):
if ('https://www.youtube.com' + vid['href']).startswith("https://www.youtube.com/watch?v="):
flag = 1
final_url = 'https://www.youtube.com' + vid['href']
url_list.append(final_url)
url = url_list[0]
ydl_opts = {}
os.chdir(path)
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
vlc.play(path)
if flag == 0:
sofiaResponse('I have not found anything in Youtube ')
#change wallpaper
elif 'change wallpaper' in command:
folder = '/Users/nageshsinghchauhan/Documents/wallpaper/'
for the_file in os.listdir(folder):
file_path = os.path.join(folder, the_file)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
except Exception as e:
print(e)
api_key = 'fd66364c0ad9e0f8aabe54ec3cfbed0a947f3f4014ce3b841bf2ff6e20948795'
url = 'https://api.unsplash.com/photos/random?client_id=' + api_key #pic from unspalsh.com
f = urllib2.urlopen(url)
json_string = f.read()
f.close()
parsed_json = json.loads(json_string)
photo = parsed_json['urls']['full']
urllib.urlretrieve(photo, "/Users/nageshsinghchauhan/Documents/wallpaper/a") # Location where we download the image to.
subprocess.call(["killall Dock"], shell=True)
sofiaResponse('wallpaper changed successfully')
#askme anything
elif 'tell me about' in command:
reg_ex = re.search('tell me about (.*)', command)
try:
if reg_ex:
topic = reg_ex.group(1)
ny = wikipedia.page(topic)
sofiaResponse(ny.content[:500].encode('utf-8'))
except Exception as e:
print(e)
sofiaResponse(e)
sofiaResponse('Hi User, I am Sofia and I am your personal voice assistant, Please give a command or say "help me" and I will tell you what all I can do for you.')
#loop to continue executing multiple commands
while True:
assistant(myCommand())
Итак, вы видели, как, просто написав простые строки кода на Python, мы можем создать очень классного голосового помощника для компьютера. Помимо этих функций, вы также можете включить множество различных функций в свой голосовой помощник.
Вывод
Что ждет нас в будущем, на протяжении всей истории вычислений пользовательские интерфейсы стали все более естественными в использовании. Экран и клавиатура были одним шагом в этом направлении. Мышь и графический интерфейс пользователя были другими. Сенсорные экраны являются самой последней разработкой. Следующий шаг, скорее всего, будет состоять из смеси дополненной реальности, жестов и голосовых команд. В конце концов, часто легче задать вопрос или поговорить, чем набрать что-то или ввести несколько деталей в онлайн-форме.
Чем больше человек взаимодействует с устройствами, активируемыми голосом, тем больше трендов и паттернов, которые система идентифицирует на основе получаемой информации. Затем эти данные можно использовать для определения пользовательских предпочтений и вкусов, что является долгосрочным преимуществом для того, чтобы сделать дом умнее. Google и Amazon стремятся интегрировать голосовой искусственный интеллект, способный анализировать человеческие эмоции и реагировать на них.
Надеюсь, вам понравилось читать эту статью. Поделитесь своими мыслями/комментариями/сомнениями в разделе комментариев.
Всем знаний!
Комментарии (12)
vassabi
01.05.2019 13:26+2Необходимые системные требования: Python 2.7, Spyder IDE, MacOS Mojave (версия 10.14)
МакОС в требованиях? мда… это было бы смешно, если бы не было так грустно.iroln
01.05.2019 20:51-1А Python 2.7 не грустно?
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
mkovalevskyi
01.05.2019 19:35Это концептуально. В статье с романтичным названием
[В закладки] Пошаговое руководство по созданию голосового помощника с Python
первый вменяемый текст:
Перед началом изучения рекомендую подробнее почитать о голосовых помощниках
trapwalker
02.05.2019 00:42такой спагетти-код нам в закладках ни к чему. Разве что пару либ можно выписать на посмотреть. А так я бы лучше сосредоточился на написании скилла к алисе или гугловому помщнику
Gryphon88
03.05.2019 02:27А мне стало грустно при упоминании recognize_google. Что, никак не распознать локально речь, надо обязательно на сервера гугла постучаться?
mkovalevskyi
03.05.2019 16:36Gryphon88
03.05.2019 20:52Ну вот совсем другое дело! А то гуглосервисы в туториале — это не есть хорошо.
DollaR84
04.05.2019 20:11Да я тоже делал помощника с использованием Pocketsphinx.
На грамматических правилах JSGF отлично работает и распознает довольно хорошо и автономно.
С распознаванием произвольной речи гораздо хуже, по крайней мере у меня не получилось добиться нормального распознавания.
Но для таких вещей как управление умным домом или еще чем, где достаточно определенного набора команд правила и нужны.
Yastreb1332
пожалуйста уберите эту мелтешащую хрень. спасибо.