Tuesday, April 13, 2010

Review: Traffic Shaper for Windows (Freeware for limiting bandwidth usage)

 

I was recently at the office blitzing a download for Visual Basic 2008 express on the High speed DSL line. Suddenly the folks around me started grimacing and cursing their computers in unison. I realized that my download was putting a lot of work on hold, and so I was forced to close it and wait for a more opportune time.

Whenever I’m in a situation like this, I start thinking about code. That makes me wonder if there was a way to control the traffic on every workstation in the network. I was quite sure that there would be many applications available to professional network administrators to aid in the task at hand. Making one from scratch would be a worthwhile waste of time :D But I had way too much work to sit and break my head over this right now. So a ready made solution it had to be…!

A few Google searches later I stumbled upon “Traffic Shaper XP” (click here to download). This is what it looks like:

image

image

 

To start checking your bandwidth, simply go to View> Options > Internet. Here choose a bandwidth limit for uploads and downloads from this computer. That’s all there is to it. Just be careful, as the settings you choose are in kiloBITS per second. So divide the number by 8 to get the limit value in kiloBYTES per second. I set my download limit to 512 kbits/sec allowing me upto 64 kBytes/sec. This download limit is now shared between all the active downloads on my computer.

So all you downloaders out there, download with ethics. “Surf and let surf”. Cheers!

Appellation - Smart rename utility for your music (Core Python)

Haven’t you always wished that your music was well organized but were too lazy to do it yourself. Here is an app that addresses the first step towards organizing your music collection viz. “Nomenclature”. Personally, I have always preferred my music files to be saved on disk in “<artist name>-<song title>” format.

Recently I had written a post on extracting ID3 tags from music files (read it here). I decided to extend that module and create an application which could be used to rename all my music files in the format mentioned above. The application would simply accept the path of destination directory and recursively search it for music files. If the ID3 tags present in the file are the latest version, the renaming process would occur without much difficulty. However, if the version of ID3 tags is very old, the process might not occur, leaving the filename unaltered. Another case of failure is when the artist information is not present in the file (No frame id TPE1 found… the app won’t look for anything else as the performer name!)

I was too lazy to create a GUI… so you are most likely to see a console when you run this app. But fear not, there is little you have to do. Simply copy and paste the path of the destination directory into the console and press enter. The progress of the entire operation is displayed on the console itself.

You can download the application from my projects page (click here). Look for a file “appellation.rar”. Simply extract the files into a folder and run the launcher script “run.py” using python.

The app is open source, so feel free to browse through the meagre amount of code. Perhaps if you feel like extending the app, you can drop me a line. Someone please make a UI if possible. I’m too bummed out with GUI for the moment to make this any better than its current (and ugly) form :)

I ran this on my collection and got pretty decent results. The summary towards the end of the program displayed a sum total of 20 files (out of 16 GiB of music) that had failed. Hopefully you have similar or better results.

Sunday, April 4, 2010

How To: PyQt4 - Temperature Monitor with Google Charts support for Ubuntu 9.10

I was recently using various system monitors on my Ubuntu 9.10, the most popular being "System Monitor" (the default gnome application for this purpose), and I realised that neither of these utilities presented any information about the CPU core temperature.

Perhaps its not such a big requirement, but I'd really like to know how hot my CPU core gets under different load conditions. For instance, when I run a massive search on my filesystem, I find my laptop getting a little warmer (a little too warm sometimes!!). The CPU core will always be at a higher temperature than the body/ambient environment since it's always at work. The operating range of most CPUs is between 55 to 85 degree centigrade. So if the ambient temperature (temperature of the body) seems to have risen by a small margin, there is a good chance that the increase is considerable inside your core.

So I decide to compliment the existing utilities by making an application of my own - TempMon. I decided to use PyQt4 for my application as its easy to use and fits perfectly with Python, my language of choice. Before I began, I penned down the goals for this application. Here they are:

  • The application must display the core temperature of the CPU at all times
  • The application must also display the average CPU load (a.k.a CPU Usage). This is usually represented as a percentage by many system monitors. Since I have a dual core 64 bit AMD at the heart of my motherboard, I will compute the "AVERAGE" cpu load. Gnome's system monitor provides individual load percentages for each core
  • The application must allow me to trigger an alert/alarm if the core temperature exceeds a particular threshold value that can be user defined
  • The application must be dockable to the taskbar or system tray
  • Finally, all the data assimilated (temperature and usage info) over a certain period of time must be displayed using a plotter or a graph
Firstly, its important to understand your data source for this application. Where does the application get the temperature and CPU usage data from? On Linux, this information is available on the local filesystem on the following files:

  • '/proc/acpi/thermal_zone/TZ01/temperature' contains a string that contains the immediate value of the temperature. In fact, this file has only one line that says "temperature: 64 C". Makes my life a lot easier :)
  • '/proc/stat' contains the information about CPU usage. There is a lot of information available on this file and not all of it is relevant to our need. The first line is all we need. It looks something like 'cpu 936808 309 246585 14286660 39745 3447 13778 0 0'. Only the values in bold digits are important to us.
  • So how do we calculate the CPU usage? Its rather simple. In the above example, consider the four numbers (in bold). Let them be u1, s1, t1 and i1. At another time (usually on a successive read of this file), let the values for the same numbers be u2, s2, t2 and i2. Now we will calculate two quantities (since we need a ratio for a percentage): usage(U) and total usage(T). The ration of these two values multiplied by 100 will be the percentage of CPU usage
  • U = (u2-u1)+(s2-s1)+(t2-t1); T = U + (i2 - i1); CPU Usage = (U/T) x 100 %
I quickly opened up Qt Designer, and a few clicks later, the GUI was ready. Small and compact but very informative. Here's what the UI looked like:


Two labels that displayed the temperature and usage percentage, one spin box to set the threshold value for temperature, a checkbox and a push button. Thats pretty much it. Once I was done, I saved the file as "fontend.ui" and subsequently converted the GUI into a python source file using pyuic4:

shell$pyuic4 frontend.ui > frontend.py

A file "frontend.py" is generated and contains a class for this dialog. That class has a method called setupUi that draws the form shown above. Now, I'm ready to start coding the core of the app. I create another file called "tempmonitor.py". You can download the entire source code from here (Look for a file labelled "Temperature Monitor").

In the init routine of the main class of "tempmonitor.py", I created a system tray icon object:
self.trayIcon = QtGui.QSystemTrayIcon(QtGui.QIcon("trayicon.png"),self)

Following which I connected this tray icon to a slot where in I toggled the form's visibility:

self.connect(self.trayIcon,SIGNAL("activated(QSystemTrayIcon::ActivationReason)"),self.toggleVisibility)

This creates a system tray icon, which allows me to show/hide the form by simply clicking it. The self.toggleVisibility routine simply changes the visibility status of the form to the opposite of its current state.

Next up, its time to write the actual tasks of polling the temperature and usage values from the respective files. That is done using self.getTemp and self.getCpuUsage methods. Both these methods read the respective files (mentioned above), and process the data within to create two strings, one for temperature and another for CPU usage. Once all the hard work is done, each of these methods, emits a custom signal viz. "tempUpdate" and "cpuUpdate" respectively.

These signals are very important. Since these routines do the "heavy work", its only natural to run them as a thread in the background (in order to prevent the GUI event loop from being interrupted). Now if they're going to run as concurrent children threads, directly providing them with access to the widgets on the form is risky business. Signals help us solve this problem. The background threads emit signals which the parent thread (GUI event loop) comes to know about. Each of these signals is tied to a slot (a method basically, that allows us the parent thread to "do" something when it discovers the signal). The following statements help redirect these signals to their respective slots.

self.connect(self,SIGNAL("tempUpdate"),self.tempUpdate) self.connect(self,SIGNAL("cpuUpdate"),self.cpuUpdate)

Now these slots are tied up to the self.tempUpdate and self.cpuUdate slots respectively. These slots are simple methods of the class, which can now be used to update the text in the labels for temperature and CPU Usage.

So the heavy work is done. Its time to actually spawn a thread that will run do all the heavy work. This thread must run until the parent thread dies (application is closed). I put up all the methods which I want to run, into a single routine called self.idleTime, which is now run in the background using the following statement:

thread.start_new_thread(self.idleTime,())

The empty parentheses indicate that no arguments are being passed to this routine. This routine periodically runs all the other methods which will read the temperature and usage data from the files, process this information and emit signals to indicate that their work is done. After every iteration of these methods, I put the thread to sleep for a couple of seconds (this allows for context switching, and since the data we read isn't changing drastically every moment, this resolution is pretty good).

We're almost done, except for the last criterion that demands a graphical display of the assimilated data. If you notice, in the source for self.tempUpdate and self.cpuUpdate (slots for the signals we spoke about earlier), the values that are read are stored as tuples of (temperature, cpu percentage) in a list called data. This list is going to serve as our source of information when we plot the temperature and usage values graphically using Google Charts.

The Google Charts API is really easy to use and the best part is that it works easily using simple GET requests. So all you really have to do is take all the data you want to plot and formulate a URL. That URL can be opened in a web browser and your chart is ready. As a hack I used the QWebView widget to dynamically generate the URL for the chart every few seconds, thereby giving the appearance of a real time graph/plot (just like system monitor does). Anyway, that is not part of this tutorial, so let's stay on point.

The self.getChartLink method generates the URL based on the values present in the list ''data". This routine is also added to the idle task routine. So now, the worker thread that runs in the background will read the temperature, the CPU usage and generate the URL for a graph based on the values stored in data. Since Google Charts API has a limit to how many points can be plotted in a single chart, I've restricted the plot to the last 200 values that were sampled. Currently I'm sampling the values at an interval of 2 seconds (sleep time for the worker thread), thereby giving myself a plot of the temperature and CPU usage over the last 400 seconds or roughly 6 minutes. Here is what the chart looks like:


The green trace represents the CPU temperature (in centigrade) and the blue trace represents the CPU usage (in percentage).

Download the source from my projects page (look for Temperature Monitor). In order to run this project you will need to have PyQt4 installed along with Python (>=v2.5.0).

And that is how its done!