Introduction: Espelho Mágico

Neste Instructables mostramos como criar um protótipo de um espelho inteligente que projeta informações de clima e notícias, utilizando comandos de voz.

Embora seja o projeto de um espelho, não houve como utilizar um devido a contratempos.

Step 1: Hardware

Dragonboard 410c

Audio Mezzanine Board

Step 2:

Para a programação foi utilizado o Visual Studio Community 2017, e a linguagem c#. A interface gráfica foi feita utilizando o editor XAML do Visual Studio.

Step 3: Programação - Detecção De Voz

O primeiro passo, foi trabalhar com a detecção de voz. A placa Audio Mezzanine Board já possui dois microfones integrados, que foram utilizados para a detecção. No Visual Studio, utilizamos a biblioteca Windows.Media.SpeechRecognition para decodificar a voz.

Foi utilizado o método encontrado aqui para a inicialização da detecção de voz, que é mostrado também abaixo.

private async void InicializaVoz()
{ var idioma = new Windows.Globalization.Language("en-US"); SpeechRecognizer recognizer = new SpeechRecognizer(idioma); recognizer.StateChanged += RecognizerStateChanged; recognizer.ContinuousRecognitionSession.ResultGenerated += RecognizerResultGenerated; string fileName = String.Format(SRGS_FILE); StorageFile grammarContentFile = await Package.Current.InstalledLocation.GetFileAsync(fileName); SpeechRecognitionGrammarFileConstraint grammarConstraint = new SpeechRecognitionGrammarFileConstraint(grammarContentFile); recognizer.Constraints.Add(grammarConstraint); SpeechRecognitionCompilationResult compilationResult = await recognizer.CompileConstraintsAsync(); if (compilationResult.Status == SpeechRecognitionResultStatus.Success) { Debug.WriteLine("Result: " + compilationResult.ToString()); await recognizer.ContinuousRecognitionSession.StartAsync(); } else { Debug.WriteLine("Status: " + compilationResult.Status); } }

Após iniciar o reconhecimento, o método RecognizerResultGenerated recebe os comandos que foram interpretados e compara com os comandos com os que estão configurados em um arquivo xml que foi criado e inserido na solução.

Como não foi possível inserir o idioma português, os comandos utilizados foram show (mostrar) e hide (esconder)e o que deve ser mostrado forecast (previsão) e news (notícias).

private async void RecognizerResultGenerated(SpeechContinuousRecognitionSession session, SpeechContinuousRecognitionResultGeneratedEventArgs args)
{

int count = args.Result.SemanticInterpretation.Properties.Count;

// Check for different tags and initialize the variables String target = args.Result.SemanticInterpretation.Properties.ContainsKey("target") ? args.Result.SemanticInterpretation.Properties["target"][0].ToString() : "";

String cmd = args.Result.SemanticInterpretation.Properties.ContainsKey("cmd") ? args.Result.SemanticInterpretation.Properties["cmd"][0].ToString() : "";

String device = args.Result.SemanticInterpretation.Properties.ContainsKey("device") ? args.Result.SemanticInterpretation.Properties["device"][0].ToString() : "";

// First check which device the user refers to if (cmd.Equals("show"))

{ if (device.Equals("forecast")) { Consulta_previsao(); } else if (device.Equals("news")) { Consulta_noticias(); } else { //Debug.WriteLine("Unknown Device"); }

} else if (cmd.Equals("hide"))

{ if (device.Equals("forecast")) { //Tempo.Text = ""; await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => { // This now works, because it's running on the UI thread: this.Max_tit.Text = ""; this.Min_tit.Text = ""; this.Min.Text = ""; this.Max.Text = ""; this.Img_Tempo.Source = new BitmapImage(new Uri("ms-appx:///Images/blank.png"));

});

} else if (device.Equals("news")) { await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => { // This now works, because it's running on the UI thread: this.News1.Text = ""; this.News2.Text = ""; this.News3.Text = ""; this.News4.Text = ""; this.News5.Text = ""; }); } else { // Debug.WriteLine("Unknown Device"); } } else { //Debug.WriteLine("Unknown Command"); }

}

Step 4: Programação - Exibir Previsão Do Tempo

Se o comando de voz detectado for show forecast, o método Consulta_previsao envia uma requisição HTTP ao site CPTEC do INPE, que retorna a previsão do tempo em um arquivo xml. Após a leitura do xml, uma imagem é mostrada na tela de acordo com a previsão e também são mostradas as temperaturas máxima e mínima .

private async void Consulta_previsao()
{

HttpClient httpcliente = new HttpClient(); //HttpResponseMessage resp = httpcliente.GetAsync("http://servicos.cptec.inpe.br/XML/cidade/222/previsao.xml").Result; var resp = httpcliente.GetAsync("http://servicos.cptec.inpe.br/XML/cidade/222/previsao.xml").Result; resp.EnsureSuccessStatusCode(); var respbody = resp.Content.ReadAsStringAsync(); XmlDocument previsao = new XmlDocument();

previsao.LoadXml(respbody.Result);

XmlElement root = previsao.DocumentElement; XmlNodeList nodes = root.GetElementsByTagName("tempo");

string prevtempo = (nodes.Item(0).InnerText); string prevtempo1 = (nodes.Item(1).InnerText); string prevtempo2 = (nodes.Item(2).InnerText); string prevtempo3 = (nodes.Item(3).InnerText); nodes = root.GetElementsByTagName("minima"); string tempmin = (nodes.Item(0).InnerText); nodes = root.GetElementsByTagName("maxima"); string tempmax = (nodes.Item(0).InnerText);

string rsultado_previsao = "";

switch (prevtempo) { case "ec": rsultado_previsao = "Chuvas_Isoladas.png"; break; case "ci": rsultado_previsao = "Chuvas_Isoladas.png"; break; case "c": rsultado_previsao = "Chuva.png"; break; case "in": rsultado_previsao = "Instavel.png"; break; case "pp": rsultado_previsao = "Chuva.png"; break; case "cm": rsultado_previsao = "Chuva.png"; break; case "cn": rsultado_previsao = "Chuvas_Isoladas_Noite.png"; break; case "pt": rsultado_previsao = "Chuva.png"; break; case "pm": rsultado_previsao = "Chuvas_Isoladas.png"; break; case "np": rsultado_previsao = "Chuva.png"; break; case "pc": rsultado_previsao = "Chuva.png"; break; case "pn": rsultado_previsao = "Nublado.png"; break; case "cv": rsultado_previsao = "Chuva.png"; break; case "ch": rsultado_previsao = "Chuva.png"; break; case "t": rsultado_previsao = "Tempestade.png"; break; case "ps": rsultado_previsao = "Sol.png"; break; case "e": rsultado_previsao = "Sol_Encoberto.png"; break; case "n": rsultado_previsao = "Nublado.png"; break; case "cl": rsultado_previsao = "Sol.png"; break; case "nv": rsultado_previsao = "Nevoeiro.png"; break; case "g": rsultado_previsao = "Neve.png"; break; case "ne": rsultado_previsao = "Neve.png"; break; case "nd": rsultado_previsao = "na.png"; break; case "pnt": rsultado_previsao = "Chuvas_Isoladas_Noite.png"; break; case "psc": rsultado_previsao = "Chuva.png"; break; case "pcm": rsultado_previsao = "Chuva.png"; break; case "pct": rsultado_previsao = "Chuva.png"; break; case "pcn": rsultado_previsao = "Chuva.png"; break; case "npt": rsultado_previsao = "Chuva.png"; break; case "npn": rsultado_previsao = "Chuva.png"; break; case "ncn": rsultado_previsao = "Chuva.png"; break; case "nct": rsultado_previsao = "Chuva.png"; break; case "ncm": rsultado_previsao = "Chuva.png"; break; case "npm": rsultado_previsao = "Chuva.png"; break; case "npp": rsultado_previsao = "Chuva.png"; break; case "vn": rsultado_previsao = "Instavel.png"; break; case "ct": rsultado_previsao = "Chuva.png"; break; case "ppn": rsultado_previsao = "Chuvas_Isoladas_Noite.png"; break; case "ppt": rsultado_previsao = "Chuva.png"; break; case "ppm": rsultado_previsao = "Chuva.png"; break;

}

await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => { // This now works, because it's running on the UI thread: this.Max_tit.Text = "Máxima"; this.Min_tit.Text = "Mínima"; this.Min.Text = tempmin + "°"; this.Max.Text = tempmax + "°"; this.Img_Tempo.Source = new BitmapImage(new Uri("ms-appx:///Images/" + rsultado_previsao)); });

}

Step 5: Programação - Exibir Notícias

Se o comando detectado for show news, o método Consulta_noticias envia uma requisição HTTP ao feed de notícias da BBC, que também retorna um XML. As cinco primeiras notícias são exibidas na tela em textblocks.

private async void Consulta_noticias()
{

HttpClient httpcliente2 = new HttpClient();

var resp2 = httpcliente2.GetAsync("http://feeds.bbci.co.uk/portuguese/rss.xml").Result; resp2.EnsureSuccessStatusCode(); var respbody2 = resp2.Content.ReadAsStringAsync(); XmlDocument noticia = new XmlDocument();

noticia.LoadXml(respbody2.Result);

XmlElement root2 = noticia.DocumentElement;

XmlNodeList nodes2 = root2.GetElementsByTagName(@"title");

await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => { this.News1.Text = (nodes2.Item(2).InnerText); this.News2.Text = (nodes2.Item(3).InnerText); this.News3.Text = (nodes2.Item(4).InnerText); this.News4.Text = (nodes2.Item(5).InnerText); this.News5.Text = (nodes2.Item(6).InnerText);

});

}

Step 6: Conclusão

Ao reproduzir esse instructables, será possível realizar detecção de comandos de voz utilizando alguma placa com o Windos IoT Core instalado. Basta criar o arquivo de gramática com os comandos desejados .

Autores:
Egon Patrick Marques Silva

Frederico Clark