Munin Plugin for USB Thermometers

I recently bought a cheap USB thermometer on eBay, to measure the room temperature in the garage where my home server lives. When it finally arrived from Hong Kong, the parcel contained the thermometer, an extension cable and a CD for the Windows drivers and utilities.

HID TEMPer USB thermometer box contents

My server runs Ubuntu 10.10, so the CD went in the bin, and I grabbed the Device::USB::PCSensor::HidTEMPer module from CPAN so I could take temperature readings with a simple Perl script.

As I already run Munin on my server, I set about writing a plugin to graph the temperature from the USB thermometer. Following the Munin plugin-writing guide I came up with this:

Download: Munin plugin for HID TEMPer USB thermometer

To get it working, first install the CPAN module and its dependencies by running the following as root:

aptitude install libusb-dev
cpan Inline::MakeMaker
cpan Device::USB::PCSensor::HidTEMPer

then copy my plugin script to the plugins directory (/etc/munin/plugins on Ubuntu) and make it executable. Next, configure Munin so that this plugin is run as root (required for access to the USB device) by adding the following to the existing config file at /etc/munin/plugin-conf.d/munin-node:

[temperature]
user root

then finally

service munin-node restart

This should work with multiple thermometers if you have more than one, and record values from both the internal and external sensor of each unit. I only have one unit, which only has an internal sensor, as you can see from this screenshot of the Munin output.

Screenshot of temperature graph from Munin plugin for USB thermometers

Hopefully it will continue to get warmer over the coming weeks

CSS Resets and Grids

As promised in my last post introducing the website redesign, I'd like to expand on the various projects that I've used to put this together. Today I'll start with the CSS framework.

Firstly, I use Eric Meyer's CSS Reset as a starting point. Reset stylesheets supply rules to get rid of the inconsistencies that different browsers apply to elements by default, when you don't supply any explicit styles to tell them otherwise. Without a reset stylesheet, these inconsistencies are generally stumbled across when doing cross browser testing and are worked around by adding styles that are specific to each specific piece of markup which renders oddly. With a reset, the inconsistencies have been removed at a higher level so your styles for specific elements of the page can concentrate on the actual style and not making sure that the bottom margin of that level three header in your sidebar is the same height in IE as it is in Firefox.

Despite being a deceptively small stylesheet, an awful lot of time and careful thought has gone into each and every rule - Eric does a great job of explaining his approach in this article which is well worth the read if you're not familiar with CSS resets.

Next, to massively simplify the problem of page layout I use the 960 Grid System. Using a grid system feels a little bit icky - having to put classes in the markup to indicate a box that is 8 columns wide is not very “semantic”. If I really wanted to be semantic and purge myself of the heinous crime against semanticism that is …

<div class="container_12">
    <div id="header" class="grid_12">
        ...
    </div>
    <div id="content" class="grid_8">
        ...
    </div>
    <div id="sidebar" class="grid_3 prefix_1">
        ...
    </div>
</div>

… I could attempt to make use of a tool like Sass to apply the Grid Systems rules to the semantic ids and classes etc. Sass and other similar tools such as HSS, CleverCSS, or LESS are higher level meta languages that are compiled down into CSS. This allows such things as mixins, where you can embed whole sets of rules inside selectors with a single line, so my semantic classes and ids could have all the rules of 960s container_12s and grid_8s applied to them without having to use the unsemantic class names in the markup.

In fact, while writing this, I've discovered that of course, others have done exactly this already.

Making Semantic Grids

  • Use the +grid-container mixin to declare your container element.
  • Use the +grid mixin to declare a grid element.
  • Use the +alpha and +omega mixins to declare the first and last grid elements for a row.
  • User the +grid-prefix and +grid-suffix mixins to add grid columns before or after a grid element.

Example:

#wrap
  +grid-container
  #left-nav
    +alpha
    +grid(5,16)
  #main-content
    +grid-prefix(1,16)
    +grid(10, 16)
    +omega

Awesome. Something to pursue another day I think. For now using 960 GS certainly got the job done quickly and let me move onto the parts that interested me more.

Please note that if you “view source” to look for the reset or 960.gs stylesheet you won't find them very easy to read. My styles have been minified and concatenated together for performance reasons by django-compress - which I'll get to in a future post.

Redesign

I've rewritten the website from scratch. Again.

This time the excuse was to learn Django.

Using a web framework like Django instead of a CMS like my previous Drupal installation gives me a lot more control over the fine details, which suits my pedantic programmer brain. Unfortunately that programmer brain is not so good when it comes to the design side of things, so I opted to keep things simple. This simplicity has resulted in a minimalistic, uncluttered look that I'm actually quite pleased with.

Here is a screenshot of my new design (on the right) alongside the Garland theme from my old Drupal 5 setup.

2007 design2010 design

Sources of inspiration for the design include semicolon and Furry Brains: two clean looking blogs I stumbled across during my Django research.

In terms of the code, when putting this site together I made use of:

I hope to blog about each of these in turn over the coming weeks, so subscribe if you want to catch that.

In the meantime, please contact me if you find any problems with the new site, broken links etc.