Friday 31 May 2013

The code!!!

Ok, this is probably the moment you've all been waiting for!  This is a tidied up version of the code for the pi-jarvis program.

Please bear in mind that while some customisation is possible (i.e. you can change what it says) there are some severe limitations.  Notably, the weather.  It has been tailored to work with data taken from the Met Office's 5 day UK forecast, and I'm afraid that if you are from another region it won't work.
That said, the basic concepts are in place, so there is nothing to stop you editing it to get and parse data from another source.

Before you start compiling the code though, there are two more things to do.  You need to create a shell script to download the xml file containing the weather information and another shell script to run the program.

You should put this in the same directory as the speech.sh script and the program itself.  I've got all mine in /home/pi (terrible practice I know, but I haven't got round to changing it yet).

The first script you need is here.  There are two things you might want to change.

First, the section of the URL that says "xml/310011?". The number, 310011, is the weather station I am getting the data from.  You will almost certainly want to change this, unless you happen to live in Leicester.

The full list of weather stations can be found here, scroll down to the section that says XML and search through it for your nearest station.

The other thing you might want to change is the location you are saving the xml document.  To do this, just alter the final section (--output-document=/home/pi/weather.xml). Note that the file name must be 'weather.xml' else the program will not be able to open it.

The second script is even simpler and I'll just write it here rather than post to git for ease.

#! /bin/bash
/home/pi/pijarvis


Change the directory /home/pi to the directory you will be using and save it as "runspeech.sh", again, in the same directory.

Ok, so now for the code itself.

It can be found here.  There might be a few of my test 'printf' statements floating around, if you spot any, feel free to delete them, they aren't important.

Copy it all into a file called pijarvis.c and save it to the same directory as the two shell scripts from earlier.

Now, customisation.  The variable 'args[]' stores the text that will be converted into speech.  You can change this into anything you like.  Just remember that args[0] has to remain as "speech.sh" else it won't work.

You will probably want to change args[1] from "Good morning Tom" to something else that you feel is appropriate.

For those not familiar with programming, in basic terms, the number in the [] following 'args' is the order in which the text will be spoken.

Whatever you do with that array, remember that the final element, in my case, 'args[12]' has to be set to '\0' to terminate the array.

To compile the program, run the command "gcc pijarvis.c -o pijarvis"
Hopefully, it will compile without any errors.  If, for some reason, you get an error, leave a comment and I'll see if I can spot the problem.


Test it to make sure it works with the command "./pijarvis".  If all has gone well, you should hear speech from your speakers.

Finally, to make it run at a certain time, you need to setup some cronjobs.

Run the command "crontab -e" and add the following to the end of the file:

05 6 * * * /home/pi/weather.sh
20 06 * * * /home/pi/runspeech.sh

What this does is sets the two scripts to run at 6:05 and 6:20 respectively.  The first script will download the weather data and the second will run the program.

Obviously, you probably don't want the program running at 6:20am every morning!  The first number is the minutes and the second the hour.  Change them to whatever you want, then press 'ctrl+x' and then 'y' to save and exit.

Just check the cronjobs have been saved by running the command "crontab -l", with will output a copy of the file you've just edited to the terminal.

Chances are there are simpler ways or methods that don;t involve so many shell scripts, but that is how I have it set up at the minute on my Pi and I know it works.

Good luck!

Oh, one more thing. At the minute, it won't run at the weekend.  This is because I wanted it to do something slightly different.  In the next few days, I will add this.

5 comments:

  1. Project is looking awesome, been looking at getting in to coding so sorry if this is a stupid question but how do you send the statement to audio and not printed in an output window?

    ReplyDelete
    Replies
    1. I'm using a shell script, which I linked in the previous post.

      If you execute the script with "./speech hello world", it will send "hello world" to Google Translate, which returns an mp3 file, then it plays that mp3.

      In the code, there is a function called "exec".

      In this function, the program forks (creates a child process) then executes the shell script. The line "execvp(args[0], args);" is the one that does it.

      You have to give the execvp function the program name, which is stored in args[0] and the arguments you want to give the program.
      So for instance, if args[1] was set to "hello world", the line "execvp(args[0], args); is essentially saying "run the command ./speech.sh with the arguments 'hello world'". This is the same as typing "./speech.sh hello world" into the terminal yourself.

      Delete
    2. Thanks been looking at this again and it makes a load more sense and I'm happy to say I understood most of it. Definitely going to be looking at doing something with this and I've got some inspiration for some other projects too so thanks

      Delete
  2. Could I use a American source for the weather? instead of Met Office, could I use, say weather.com? Sorry if this is painfully simple and I'm just over complicating things.

    ReplyDelete
    Replies
    1. Sorry for the late reply, I haven't looked at this page for months.

      You could do, it would require quite a bit of rewriting though. If you wanted to use your source in the same way I used the Met Office source, you would need to change the wget script to point to the xml file from your source.

      Then, the functions 'int reading()' and 'int weather()' would need to be rewritten as it is almost certain that the xml file you used will be completely different to the Met Office file.

      The gist of it would be the same, in that you would start by looking for the date and then go through looking for other things such as temperature, conditions and so on. But the way they would be stored would be different, so as I said, you'd need to rewrite the 'weather()' function and, most likely, the 'reading()' function.

      Delete