SDS Player, Digital Signage com Adobe Air, Parte II

Entrando num papo mais técnico hoje vou falar do módulo previsão do tempo. Com isso vou mostrar:

  • Como buscar informações de previsão do tempo na Web.
  • Como garantir que o player terá sempre dados locais para exibir.
  • Como fazer acesso a dados remotos com Adobe Air.
  • Como exibir a previsão do tempo no player.

Como buscar informações de previsão do tempo na Web?

Existem vários serviços abertos na Web que fornecem dados de previsão do tempo. Testei muito e fiz minha escolha pelo Google Weather. Você pode testar o serviço simplesmente utilizando essa url: http://www.google.com/ig/api?weather=Vila%20Velha,ES. Verá que o retorno é um XML semelhante a este:

XML of Forecast

XML retornado pelo WS Google Weather


Como garantir que o player terá sempre dados locais para exibir?

Imagine se criarmos um player que acessa diretamente esse Web service para obter os dados da previsão do tempo toda vez que necessário. E se o PC onde roda o player estiver off-line por um motivo qualquer ou se o serviço do Google estiver fora do ar. Teríamos somente duas opções: mostrar uma tela azul com erro ou pular para o próximo programa. Você há de concordar que nenhuma das duas opções interessa. Como então podemos solucionar os dois problemas (falta de conexão e queda do serviço do Google)?

  1. Mantendo dados da previsão do tempo em memória para o caso de falta de conexão.
    O player faz chamadas (como mostrarei adiante) esporádicas ao nosso servidor para se atualizar. Caso essas chamadas sejam mal sucessedidas não há problema, ele continuará usando os dados obtidos na última chamada.
  2. Mantendo os dados da previsão do tempo em nosso servidor.
    Desse modo, criamos um script que é executado via Crontab e que se encarrega de obter os dados do Web service e grava-los em banco de dados. Segue o exemplo de um script que faz essa função:

    // Atualizando dados da previsão do tempo
    $cidades[0][0] = "Vila Velha, ES";
    $cidades[0][1] = "Vila%20Velha-ES";
    $cidades[1][0] = "Guarapari, ES";
    $cidades[1][1] = "Guarapari-ES";
    
    for ($i = 0; $i < count($cidades); $i++) {
        $contents = file_get_contents('http://www.google.com/ig/api?hl=pt-Br&weather=' . $cidades[$i][1]);
        $query = "UPDATE ext_forecast SET forecast_date = NOW(), xml = '" . addslashes($contents) . "' WHERE city = '" . utf8_decode($cidades[$i][0]) . "'";
        mysql_query($query, $connection) or die (mail('seu@email.com', 'Erro Cron', 'O Cron não conseguiu atualizar a previsão do tempo.'));
    }
    

    Observe que estou salvando todo o XML para dentro de um campo do tipo text no banco de dados. Nesse passo, é importante perceber que se deve utilizar a função addslashes de forma a facilitar a utilização desses dados mais tarde. O script ainda envia e-mail para o administrador caso algo de errado ocorra – falha de conexão com o servidor do banco de dados, por exemplo.


Como fazer acesso a dados remotos com Adobe Air?

Bom, agora já temos os dados da previsão do tempo em nosso próprio banco de dados. Nosso player irá se conectar somente em nosso servidor, evitando ponto de falha por ter que se conectar em vários servidores / servidores de terceiros.

  1. No lado do servidor, inclua um método como esse em seu serviço:
    public function getForecast() {
        $this->connect();
    
        $forecastDAO = new ForecastDAO($this->connection);
        $resultObj = $forecastDAO->getAll();
    
        if($resultObj != null) {
            $this->logger->log('Get Forecast Ok.', Zend_Log::DEBUG);
        } else {
            $this->logger->log('Error getting Forecast', Zend_Log::WARN);
            $resultObj = "error";
        }
        return $resultObj;
    }

    Nesse código fazemos acesso ao mesmo banco utilizado para gravar os dados da previsão no tópico anterior, buscamos a linha correspondente à cidade solicitada e retornamos, garantindo que quaisquer erros serão logados.

  2. No cliente (player)
    Criamos um método para ser executado em períodos determidados, fazendo a chamada ao método remoto. Dessa forma:

    protected function getForecast():void {
    	serv.getForecast.send();
    	setTimeout(getForecast, 6 * 60 * 60 * 1000); // six hours
    }
    
    protected function getForecast_resultHandler(event:ResultEvent):void {
    	var result:Array = event.result as Array;
    	var arrayXmls:Array = new Array();
    	if (result != null) {
    		for (var i:int = 0; i < result.length; i++) {
    			var xml:XML = new XML(result[i].xml);
    			var xmlDoc:XMLDocument = new XMLDocument(xml);
    			var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(true);
    			var resultObj:Object = decoder.decodeXML(xmlDoc);
    
    			arrayXmls[result[i].city] = resultObj.xml_api_reply.weather.forecast_conditions;
    		}
    
    		this.forecast_data = arrayXmls;
    	}
    }

    Essa parte é a que pode assustar mais em função dos passos que temos que seguir para deixar o XML de forma mais amigável, entretanto como já estou colocando tudo prontinho, você não terá muitos problemas.

Como exibir a previsão do tempo no player?

De posse dos dados, chega a hora de criar a tela para exibir a previsão do tempo. Nessa hora vale a pena investir no design. Assim é a privisão do tempo no SDS Player:

A parte mais complicada nesse ponto está relacionada com as imagens (sol, nuvem, etc), mas tenho um post que trata especificamente desse assunto. No mais, você só precisa usar e abusar de um layout criativo e inovador! A foto de fundo cai muito bem!

Um box para exibir uma dia de previsão fica dessa forma:

				<s:BorderContainer borderAlpha="0.2" styleName="boxPrevisao" width="33.33333%" height="100%">
					<mx:HBox verticalAlign="top" paddingBottom="18" paddingLeft="18" paddingRight="18" paddingTop="18">
						<s:VGroup width="260" height="350">
							<s:Label text="{nomeAmanha}" width="100%" height="55" styleName="tituloDia" id="labelNomeDia0" color="#FEFCFC" fontSize="54" filters="{[dropShaText]}"/>
							<mx:HRule width="100%" alpha="0.4"/>
							<mx:Spacer height="5"/>
							<s:Label text="{descAmanha}" width="250" height="100" styleName="descPrevisao"/>
							<s:HGroup width="100%" height="48" verticalAlign="top">
								<mx:Image source="icones/temp_max.png"/>
								<s:Label text="{maxAmanha}˚C" height="100%" width="100%" styleName="temperature" filters="{[dropShaTemp]}"/>
							</s:HGroup>
							<mx:Spacer height="10"/>
							<s:HGroup width="100%" height="48" verticalAlign="middle">
								<mx:Image source="icones/temp_min.png"/>
								<s:Label text="{minAmanha}˚C" height="100%" width="100%" styleName="temperatureMin" filters="{[dropShaTemp]}"/>
							</s:HGroup>

						</s:VGroup>
						<s:VGroup width="150" height="100%" verticalAlign="top">
							<mx:SWFLoader source="icones/tempo/{WeatherResolver.getImageName(imgAmanha)}" width="200" height="100%"/>
						</s:VGroup>
					</mx:HBox>
				</s:BorderContainer>

Por enquanto é isso. Espero ter ajudado caso construir um player para digital signage seja o seu desafio no momento!

No próximo post pretendo falar de exibição de clipes no player.

Até agora:

  • Já contei como tudo começou (nesse post).
  • Já fiz uma introdução sobre o SDS Player e mostrei nossas vinhetas (nesse post).

Leave a Reply