Saturday, September 6, 2014

Yahoo Weather on Raspberry Pi, with text-to-speech

With java-google-translate-text-to-speech, we can add text-to-speech (tts) to previous Yahoo Weather exercise.


Java code on Raspberry Pi.
package java_jssc_uno;

import com.gtranslate.Audio;
import com.gtranslate.Language;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javazoom.jl.decoder.JavaLayerException;
import jssc.SerialPort;
import jssc.SerialPortException;
import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class Java_jSSC_Uno {

    public static void main(String[] args) {
        SerialPort serialPort = new SerialPort("/dev/ttyACM0");
        try {
            System.out.println("Port opened: " + serialPort.openPort());

            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Java_jSSC_Uno.class.getName()).log(Level.SEVERE, null, ex);
            }

            System.out.println("Params setted: " + serialPort.setParams(9600, 8, 1, 0));
            System.out.println("\"Hello World!!!\" successfully writen to port: " + serialPort.writeBytes("Java_jSSC_Uno".getBytes()));
            //System.out.println("Port closed: " + serialPort.closePort());
        } catch (SerialPortException ex) {
            System.out.println(ex);
        }

        YahooWeather yahooWeather = new YahooWeather();
        yahooWeather.queryWeather();
        
        MyWeather myYahooWeatherResult = yahooWeather.getWeatherResult();
        System.out.println(myYahooWeatherResult.toString());
        
        Reporter reporter = new Reporter(serialPort, myYahooWeatherResult);
        reporter.report();
        
        try {
            System.out.println("Port closed: " + serialPort.closePort());
        } catch (SerialPortException ex) {
            Logger.getLogger(Java_jSSC_Uno.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

class Reporter{
    SerialPort serialPort;
    MyWeather myWeather;
    
    Reporter(SerialPort serialPort, MyWeather myWeather){
        this.serialPort = serialPort;
        this.myWeather = myWeather;
    }
    
    public void report(){
        reportWord(myWeather.description);
        //reportWord(myWeather.city);
        //reportWord(myWeather.region);
        //reportWord(myWeather.country);
        reportWord(myWeather.conditiondate);
        
        reportWord("humidity: " + myWeather.humidity);
        reportWord("visibility: " + myWeather.visibility);
        reportWord("pressure: " + myWeather.pressure);
        reportWord("rising: " + myWeather.rising);
        
        reportWord("Wind chill: " + myWeather.windChill);
        reportWord("direction: " + myWeather.windDirection);
        reportWord("speed: " + myWeather.windSpeed);
        reportWord("Sunrise: " + myWeather.sunrise);
        reportWord("Sunset: " + myWeather.sunset);
        reportWord(myWeather.conditiontext);

    }
    
    private void reportWord(String word){
        try {
            serialPort.writeBytes(word.getBytes());
        } catch (SerialPortException ex) {
            Logger.getLogger(Reporter.class.getName()).log(Level.SEVERE, null, ex);
        }
        speak(word);
        delay2s();
    }
    
    private void speak(String word){
        Audio audio = Audio.getInstance();
        InputStream sound;
        try {
            sound = audio.getAudio(word, Language.ENGLISH);
            audio.play(sound);
        } catch (IOException | JavaLayerException ex) {
            Logger.getLogger(Reporter.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }

    private void delay2s(){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Java_jSSC_Uno.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}

class MyWeather{
    String description;
    String city;
    String region;
    String country;
    
    String windChill;
    String windDirection;
    String windSpeed;
    
    String humidity;
    String visibility;
    String pressure;
    String rising;
    
    String sunrise;
    String sunset;
    
    String conditiontext;
    String conditiondate;
    
    @Override
    public String toString(){
        
        return "\n- " + description + " -\n\n" 
            + "city: " + city + "\n"
            + "region: " + region + "\n"
            + "country: " + country + "\n\n"

            + "Wind\n"
            + "chill: " + windChill + "\n"
            + "direction: " + windDirection + "\n"
            + "speed: " + windSpeed + "\n\n"
            
            + "humidity: " + humidity + "\n"
            + "visibility: " + visibility + "\n"
            + "pressure: " + pressure + "\n"
            + "rising: " + rising + "\n\n"
            
            + "Sunrise: " + sunrise + "\n"
            + "Sunset: " + sunset + "\n\n"
            
            + "Condition: " + conditiontext + "\n"
            + conditiondate +"\n";
    }
}

class YahooWeather {
    
    MyWeather weatherResult;
    
    public void queryWeather(){
        String weatherString = query();
        Document weatherDoc = convertStringToDocument(weatherString);
        
        weatherResult = parseWeather(weatherDoc);
    }

    private String query() {
        String qResult = "";
        //Yahoo Weather Query URL for New York
        String queryString = "http://weather.yahooapis.com/forecastrss?w=2459115";

        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpGet httpGet = new HttpGet(queryString);

        try {
            HttpEntity httpEntity = httpClient.execute(httpGet).getEntity();

            if (httpEntity != null) {
                InputStream inputStream = httpEntity.getContent();
                Reader in = new InputStreamReader(inputStream);
                BufferedReader bufferedreader = new BufferedReader(in);
                StringBuilder stringBuilder = new StringBuilder();

                String stringReadLine;

                while ((stringReadLine = bufferedreader.readLine()) != null) {
                    stringBuilder.append(stringReadLine).append("\n");
                }

                qResult = stringBuilder.toString();

            }

        } catch (IOException ex) {
            Logger.getLogger(YahooWeather.class.getName()).log(Level.SEVERE, null, ex);
        }

        return qResult;
    }

    private Document convertStringToDocument(String src) {
        Document doc = null;

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder parser;

        try {
            parser = dbFactory.newDocumentBuilder();
            doc = parser.parse(new ByteArrayInputStream(src.getBytes()));
        } catch (ParserConfigurationException | SAXException | IOException ex) {
            Logger.getLogger(YahooWeather.class.getName()).log(Level.SEVERE, null, ex);
        }

        return doc;
    }

    private MyWeather parseWeather(Document srcDoc){
        
        MyWeather myWeather = new MyWeather();

        //<description>Yahoo! Weather for New York, NY</description>
        myWeather.description = srcDoc.getElementsByTagName("description")
            .item(0)
            .getTextContent();

        //<yweather:location city="New York" region="NY" country="United States"/>
        Node locationNode = srcDoc.getElementsByTagName("yweather:location").item(0);
        myWeather.city = locationNode.getAttributes()
            .getNamedItem("city")
            .getNodeValue();
        
        myWeather.region = locationNode.getAttributes()
            .getNamedItem("region")
            .getNodeValue();
        
        myWeather.country = locationNode.getAttributes()
            .getNamedItem("country")
            .getNodeValue();

        //<yweather:wind chill="60" direction="0" speed="0"/>
        Node windNode = srcDoc.getElementsByTagName("yweather:wind").item(0);
        myWeather.windChill = windNode.getAttributes()
            .getNamedItem("chill")
            .getNodeValue();
        
        myWeather.windDirection = windNode.getAttributes()
            .getNamedItem("direction")
            .getNodeValue();
        
        myWeather.windSpeed = windNode.getAttributes()
            .getNamedItem("speed")
            .getNodeValue();
        
        //<yweather:atmosphere humidity="82" visibility="6" pressure="30.2" rising="0"/>
        Node atmosphereNode = srcDoc.getElementsByTagName("yweather:atmosphere").item(0);
        myWeather.humidity = atmosphereNode.getAttributes()
            .getNamedItem("humidity")
            .getNodeValue();
        
        myWeather.visibility = atmosphereNode.getAttributes()
            .getNamedItem("visibility")
            .getNodeValue();
        
        myWeather.pressure = atmosphereNode.getAttributes()
            .getNamedItem("pressure")
            .getNodeValue();
        
        myWeather.rising = atmosphereNode.getAttributes()
            .getNamedItem("rising")
            .getNodeValue();

        //<yweather:astronomy sunrise="6:52 am" sunset="7:10 pm"/>
        Node astronomyNode = srcDoc.getElementsByTagName("yweather:astronomy").item(0);
        myWeather.sunrise = astronomyNode.getAttributes()
            .getNamedItem("sunrise")
            .getNodeValue();
        
        myWeather.sunset = astronomyNode.getAttributes()
            .getNamedItem("sunset")
            .getNodeValue();

        //<yweather:condition text="Fair" code="33" temp="60" date="Fri, 23 Mar 2012 8:49 pm EDT"/>
        Node conditionNode = srcDoc.getElementsByTagName("yweather:condition").item(0);
        myWeather.conditiontext = conditionNode.getAttributes()
            .getNamedItem("text")
            .getNodeValue();
        
        myWeather.conditiondate = conditionNode.getAttributes()
            .getNamedItem("date")
            .getNodeValue();

        return myWeather;
    }
    
    public MyWeather getWeatherResult(){
        return weatherResult;
    }
    
    @Override
    public String toString(){
        return weatherResult.toString();
    }
}

Download HERE.

Keep using the sketch in the post "Read from Arduino Serial port, and write to 2x16 LCD" on Arduino Uno.

No comments: