This is the final installment of a 3-part series on building a visual status screen, or dashboard, for your company. If you missed the previous parts you can find them at:
In the first installment I showed how to physically mount LCDs on a wall, and in the second I showed how I go about collecting data from various systems (both internal and external) in a central location.
The final step is taking that data and displaying it on the status screens, and then updating the display whenever the data changes. There are a huge number of ways this could be done depending on what sort of system you are accustomed to working with, but since I normally do web application development I decided to take the simple way out and make the status screens using dynamic web pages. Yes, when I'm swinging this PHP hammer every problem looks like it could be solved with a web page!
I'll start by showing you the simplest, most brute-force approach that should be easy to get going. It's a bit crude but it'll get the job done, and later I'll mention some enhancements that can make it more elegant.
In the last installment we ended up with all the relevant data being stored in simple text files on a central machine. With all the data in one place it's easy to create a dynamic web page that is served by that machine and displays the data neatly formatted to suit your LCDs, and by displaying it in a browser like Google Chrome that can run in full-screen mode it can look really pretty.
You'll need some kind of scripting system running on your server to generate dynamic web pages, and there are many alternatives so I won't go into detail here. I'm using PHP but you could do the same thing with Perl, Python, ASP.net, or many others. It's really up to you.
Let's start with just about the simplest case possible, which is a page that loads a single value (the current temperature, in this case) from a text file on disk, displays it, and reloads itself periodically.
<html><head><title></title> <meta http-equiv="refresh" content="10" /> </head> <?php $temperature = file_get_contents( "/home/statusscreen/data/data-weather-temp" ); echo "The temperature is " . $temperature . "°"; ?> </body></html>
That's it! Not so hard, right? If you put that code into a file called something like "screen.php" inside the web tree on your server and load it up in a browser, you'll see a mostly blank page with the current temperature displayed on it - assuming your data collector script is updating the "data-weather-temp" file as described in Part 2.
The "meta" tag at the top is a special tag that tells the browser to reload the page periodically, and in this case it'll reload every 10 seconds. If you leave the page open in your browser and alter the value in the "data-weather-temp" file you'll see the change reflected in the web page after a few seconds.
Of course this is a very minimal example, and if you've done any programming it'll be obvious that there are many ways to improve the code above: for example, before attempting to retrieve the contents of the file there should be a check to make sure the file actually exists. Then once the value has been extracted it should probably be cast to a numeric value just in case something nasty ends up in the file. The page itself will also be totally unstyled, simply displaying default black text in the top left corner of the page on a default white background. You'll also notice that the entire page is reloading every single time, when really it's only the temperature value that should need to be fetched from the server.
It's a start though, and with some further development it can end up as quite a decent system. To test it you can open the Google Chrome browser on the computer connected to your wall-mounted status screen, press F11 to go to full-screen mode, and leave it open. The page will continue to reload every 10 seconds so by editing the script on the server you'll be able to see the effect of your changes almost immediately. You can also preview the page directly on your laptop or desktop, of course, but having it open on the machine and screen combination that you'll ultimately leave running can be handy because it may have a different resolution to your own computer. Normally when developing web pages it's a good principle to structure it in such a way that it looks good in different browsers at different resolutions, but in this case you're creating a web page that will only ever be loaded up by one computer running that specific browser at a known resolution, so you can tune it to look exactly the way you want without caring about how well it works on other computers.
The next step is to expand the script to include other bits of data that you want to display on the same screen. In my case I wanted a simple 4x3 grid layout for one of the screens so it made sense to put the different parameters into a table. The result could be something like this:
<?php $datapath = "/home/statusscreen/data"; $temperature = file_get_contents( $datapath . "/data-weather-temp" ); $brillianz = file_get_contents( $datapath . "/data-ops-br" ); $sb4 = file_get_contents( $datapath . "/data-ops-sb4" ); $projnum = file_get_contents( $datapath . "/data-projects-projnum" ); //(etc) ?> <html><head><title></title> <meta http-equiv="refresh" content="10" /> </head> <table> <tr> <td><?=$temperature?></td> <td><?=$brillianz?></td> <td><?=$sb4?></td> <td><?=$projnum?></td> </tr> </table> </body></html>
That's functional, but still ugly. We're still dealing with default text on a white page in an unstyled table.
But now you can apply some styling to make it look pretty. By putting class names and IDs on the various elements and loaded an external CSS file you can now make your plain page look as classy as you like. In my version I applied styles to just about everything using CSS: the font size, font colour, text shadow, page background, borders and margins, and cell backgrounds you see in photos of the screens are all just styled with CSS.
At this point you have a system that is not only perfectly functional, but is actually starting to look pretty sweet as well. You could leave the system running exactly like this and be happy.
Because I have three screens on the wall I actually have three pages defined. One uses the simple grid layout described here, while one loads a web-based energy monitoring system created at IVT to display real-time power consumption in different parts of the building, and another displays bar graphs using data collected from various internal systems such as our bug tracker and package autobuilders. What you want to display is totally up to you.
The energy monitoring system is actually based on slightly different technology to what I've described here. It's still a web page, but it uses Adobe Flex to display real-time data that updates dynamically without having to reload the whole page.
I've deliberately become more vague towards the end because this is where you really have to decide what data you want to display and how you want it to appear. I built a system that suits my requirements, but it may not suit yours.
If you've built a status screen for your company I'd love to hear about it, so please drop me an email!
This is part 2 of a 3-part series on building a visual status screen, or dashboard, for your company. If you missed part 1 you can find it at Building a Status Screen, part 1: Hardware.
Now that you have the monitors neatly mounted in place it's time to start collecting some data to display on them, so the first thing to decide is exactly *what* you want to display. Write a list of items first, then we'll work through the list and figure out how to retrieve that particular piece of data. In my case the initial list looked a bit like this:
- Recent Twitter updates that mention us or our products.
- Number of open bugs in our bug tracker.
- Number of feature requests pending.
- Number of packages that are in the QA queue awaiting testing.
- Number of open support requests categorised by customer.
- Number of customers categorised by product and project type.
- Monthly revenue categorised by product and project type.
- Number of running physical servers in each data centre.
- Number of running virtual machines in each data centre and on EC2.
- Current weather conditions in Melbourne, Australia.
- Graphs of office power consumption broken down by desk area and power circuit.
Other things that I'd like to display but don't currently have room to include on the current screens:
- Graph of phone lines in use.
- Nagios report on service status and failures.
- Visualisation of network traffic.
- Video feed from front door of office.
If you glance down that list you'll notice that the data itself has to come from quite a few different places: some is stored in internal systems, some is external. Additionally, some is quite volatile and can change by the second while some may vary quite slowly.
To get around the problem of different data sources and types I used an architecture based on a centralised datastore, and wrote a number of independent data collectors that each deal with their own specific type of data and update the datastore at the appropriate rate.
At any one point in time the datastore can then be relied on to contain a snapshot of the last set of data that has been collected, without concern for the status of any of the individual collectors.
In my case the datastore and all the collectors run on the same machine, the intranet server at Internet Vision Technologies. The datastore itself could be created using something like a MySQL database but as a quick, low-effort starting point I just used a bunch of text files stored in a directory on the server. Ultimately I'll probably switch the database to MySQL but having everything sitting around in text files appeals to my sense of minimalism and makes debugging very easy during development.
The IVT intranet server is running Linux (Ubuntu, in this case) so there are plenty of options for scripting environments, but I chose to use PHP since that's what most of our other projects use and it's a language I'm very familiar with. The same thing could be done in Perl, Python, C, or even in a collection of BASH scripts and command line tools if you prefer. It really doesn't matter: just use whatever you're most comfortable with.
Each collector is just a self-contained PHP script that can be invoked directly on the command line or automatically run by CRON at a predetermined interval. Start by writing and running each script manually, then when you're happy that everything is working properly they can be added to a crontab file. We'll get to that in just a moment.
The first collector I wrote was a trivial Twitter collector. Twitter offers a simple API, and the TwitterSearch class by Ryan Faerman makes it incredibly simple to access using PHP. I downloaded the TwitterSearch class from http://ryanfaerman.com/twittersearch/ and put it in the directory with the collector.
The code for the collector itself is stored in a file called "collector-twitter.php" located in "/home/statusscreen" and looks like this:
$datapath = "/home/statusscreen/data/";
include_once( "/home/statusscreen/includes/TwitterSearch.php" );
$search = new TwitterSearch( '#brillianz' );
$search-%gt;user_agent = 'phptwittersearch:firstname.lastname@example.org';
$results = $search->results();
$fp = fopen( $datapath . 'data-twitter', 'w' );
foreach( $results as $result )
$text = $result->text;
$avatar = $result->profile_image_url;
$user = $result->from_user;
fwrite( $fp, $user . "|" . $avatar . "|" . $text . "n" );
fclose( $fp );
Even if you haven't used PHP before the script should hardly need any commentary. It starts by specifying the location in which to store the data, includes Ryan's TwitterSearch class, then sets up a search for the "#brillianz" hashtag and executes it. Of course you'll probably want to use a different search.
The collector then opens a text file called "data-twitter" in "write" mode and loops over the search results. For each result it extracts the text of the tweet, the URL of the user's avatar, and the username that created the tweet. These are then inserted into the text file with a pipe separator before looping back to the next result and doing it again. Finally the file is closed.
The result is a text file that contains data about a set of tweets, and in part 3 of this series we'll be looking at how to process that data and display it on the status screens.
Oh yes, and something to keep in mind here is potential attacks. If we were taking this data and inserting it into a MySQL database we'd need to be careful to validate the data, otherwise you'd be opening yourself up to SQL injection attacks from any random Twitter user!
Once you've created the script you can make it executible using:
chmod +x collector-twitter.php
Then run it manually using:
The result should be a set of entries in the "data-twitter" file.
The weather collector is even simpler, and uses PHP's built in XML parsing support to access the Google Weather API.
$datapath = "/home/statusscreen/data/";
$weather_feed = file_get_contents("http://www.google.com/ig/api?weather=melbourne,Australia");
$weather = simplexml_load_string($weather_feed);
if(!$weather) die('weather failed');
$temp_c = $weather->weather->current_conditions->temp_c['data'];
$fp = fopen( $datapath . 'data-weather-temp', 'w' ); fwrite( $fp, $temp_c ); fclose( $fp );
You'll notice a commented-out call to "print_r". If you want to explore the other data available within the API you can just uncomment that line and execute the script manually. This example only collects the temperature in degrees C, but it could trivially be extended to collect other data and store it in other text files alongside the "data-weather-temp" file.
Custom Data Services The two data collectors shown so far access external services with established APIs, but in many cases the data you need to fetch comes from internal systems with no existing API. The solution is to write your own data services to make that information available in a similar way to the external APIs.
The systems I needed to access were all running the Apache web server so once again I just used PHP to create simple scripts that would report specific values. For example, our server provisioning system runs on another Ubuntu Linux server and uses its own MySQL database to manage information about all the servers we run.
You need to think very carefully about security at this point because you're potentially exposing highly confidential information to anyone with a web browser. Make sure the system is behind a firewall, password protected, or otherwise restricted.
In the web tree on the provisioning server I created a script that connects to the MySQL database on the server, runs a couple of queries to get some relevant data, and then reports those values when accessed using a web browser. The result is a simple web page that looks something like this:
That page can then be loaded by a data collector and parsed to extract the values.
If you really wanted to you could implement a full web-services API using XML or something, but I couldn't be bothered. This is lightweight and works perfectly well.
Internal Data Collector The final collector I'll show you is one example of the many collectors I've written to acquire data from our own internal systems such as the one described above. As we've just seen the data service exposes values in a very simple format so all we need to do is call the appropriate URL, parse the response, and stick the values into text files just like before. This should do the trick:
Obviously you'll need to substitute your own URLs and variables into these examples to suit your own requirements, and your scripts may have many more variables in them. Most of my collectors acquire about 4 to 8 data points.
Automatic Scheduling On Linux systems it's really easy to schedule scripts for regular execution. In my case I have a file called "/etc/cron.d/statusscreen" that looks a bit like this:
* * * * * root /home/statusscreen/collector-stats.php
* * * * * root /home/statusscreen/collector-bugs.php
*/15 * * * * root /home/statusscreen/collector-weather.php
* * * * * root /home/statusscreen/collector-twitter.php
In this case the weather collector is executed every 15 minutes, while the other collectors are executed every minute. My real file has many more lines (and therefore collectors) than that, but it gives you the idea. If you set up your collectors to be executed automatically you can periodically "cat" each data file to see the current values, and you should see them change within a minute or so of the original data source changing.
So at this point you should have infrastructure in place to periodically collect data from a variety of sources and store it all in a central place. In the final installment I'll show you how I take that data and display it on the status screens up on the office wall.
A couple of weekends ago I mounted some LCD screens on the wall at Internet Vision Technologies and set them up to display a dashboard of assorted data from within the company. I wrote a blog post about it that received a lot of attention so if you want to know the "why" behind the project it would be a good idea to read that first:
To refresh your memory this is what we're going to end up with:
What I'm going to do now is show you some of the details of how I did it so you can have a go at building something similar yourself. This will be a series of three posts covering the hardware, setting up data sources, and creating the interface.
So, on to the hardware!
The first thing to consider is where to put it. Keep in mind that a company status screen isn't an advertising board for visitors, it's an internal tool that you want your staff to be able to see throughout the day and that will probably display confidential information. The IVT office is an awkward shape and it took a bit of pondering to work out the best place, but in the end I mounted the screens on a reasonably central wall where they can be seen by most staff while sitting at their desks.
Try to find a location that's fairly high. The screens at IVT are mounted so that the bottom of the screen area is at about head height, with the tops nearly 2.5m above the floor. That was partly because they needed to be mounted above desks, but it gives the additional benefit that they're easy to see over partitions and people walking around.
Other considerations are glare from the Sun or other light sources, availability of power nearby, and a location fairly close to the screens where you can place a computer to run them. The computer will also need network access but that could be either wired Ethernet or WiFi, so in most offices that shouldn't be a problem.
In my case I bought a set of three identical screens second-hand from a friend so I didn't get to select what model they were, but it worked out fairly well in the end. They're 22" LCDs with a native resolution of 1680x1050, they're fairly thin as LCDs go so they sit back close to the wall, and as a bonus they remember the last power state so if their power is turned off at the wall and then turned back on again they come back in an "on" state. That's fairly unusual for LCDs: most models need the power button pressed to turn them back on again after power has been removed.
Restoring state after power-off isn't really critical but it does make things easier if you want to turn the screen off outside business hours and have it come back on again automatically. A simple appliance timer can be used to turn the screens off at the end of the day and back on again first thing in the morning, and if the screen is smart enough to turn on when power is restored it saves you having to hit the power button every morning.
If money was no object and I could simply go out and buy the most impressive screen possible I'd probably pick the one used for the Panic Software status board: a Samsung 460UXN-2. They're huge, have high resolution, and the plastic bezel around the screen is very thin.
If you have a single huge screen your job is simple: measure it, check that it fits the space you have in mind, and you're set. In my case I wanted to mount three screens side by side so things were just a little more tricky.
Obviously vertical space wasn't a problem but I didn't have much leeway horizontally. I measured the width of a screen, multiplied by 3, and discovered that it came to just less than the space available on that section of wall. Perfect.
Then I took the width of a screen, added 10mm to allow for a slight gap between the screens and give me some wiggle-room, and used that as the center-to-center spacing of the screens. That distance is shown as the "spacing" measurement in the diagram below. I then took half that value, added about 20mm to put a slight border to the edge of the wall, and measured in that distance from the edge of the wall as shown by the "offset" measurement below. That gave me the center position of the first screen, so I used a pencil to draw a small vertical line on the wall at that point.
Then I took the screen-width-plus-10mm value that I calculated earlier, measured across to the right, and drew another vertical line for the center of the second screen. Repeat the process again and I had the center of the third screen.
I then drew a short horizontal line through one of the center marks to show vertically where I wanted the center of the screens to be, and used a builders spirit level to draw horizontal lines through the center of the other two screens at the exact same height.
Stepping back and looking at the wall you'll now have three crosses: one for the center position of each screen. Make sure the spacing makes sense, maybe by getting a friend to help you hold up a couple of the screens in the correct positions so you can see if they fit as you expected.
Almost all LCD computer monitors and TVs are designed to use a standard mounting system generally referred to as a "VESA mount." VESA mounts use four screws arranged in a square to attach a bracket to the back of the screen, and they come in different sizes. There are two size factors you need to get right.
The first is the carrying capacity. The 22" LCDs I used are fairly light but if you've ever tried to move a big LCD TV you'll know they can be amazingly heavy. VESA mounting brackets are rated by weight, so make sure you get one that is strong enough to hold your display.
The second is the screw spacing. VESA mounts use four screws in a square and the most common configuration is for them to be 100mm apart. Some small monitors have them on 75mm spacing, and with TVs getting ever bigger there are now also VESA mounts with 200mm, 400mm, and even bigger spacing.
Most mounting brackets have holes for multiple spacings but it's worth checking to be sure. Measure the spacing on the holes in the back of your monitor, then when you're buying a bracket you can check that it supports that same spacing. You'll often see packaging marked as "VESA-100", or "VESA-75", as a shorthand way to indicate the spacings they support.
Display mounting brackets add a little bit of space between the monitor and the wall, particularly brackets that provide pan and tilt adjustment. In my case I wanted the monitors to sit as flat against the wall as possible and didn't care about pan/tilt, so my choice of bracket was based on getting something as thin and simple as possible.
In the end I grabbed three brackets like these from Bunnings for about $20 each:
It's really just two pieces of folded metal, but they work very well and add minimal space behind the screen. The bottom piece in that picture attaches to the wall (more about that in a moment) while the top piece screws onto the back of your monitor. Because the sides are not quite parallel you can then slide the monitor down onto the bracket on the wall and it'll sit firmly in place.
If you're working with a big screen you'll probably need something a bit stronger, and it's likely you'll end up with a bracket that looks more like this:
Fitting the Bracket
Carefully place the screen face-down on a flat surface, preferably with something soft like a towel or blanket underneath so the screen surface won't be scratched. Remove the desk mounting stand since it'll just get in the way. That can be harder than it sounds, with the mounting stand often fitted using screws that are concealed behind plastic covers. In my case I had to pop a plastic moulding off the back of the monitor before I could even see the screws.
Next, attach the appropriate section of the mounting bracket to the back of the screen using the screws that should have come with the bracket. Some monitors have unfortunate plastic mouldings that protrude behind the back face of the case and in that case you may have to use spacers (typically supplied with the bracket) between the bracket and the back of the monitor. Avoid using the spacers if possible though because they make the gap to the wall bigger and increase the torsional force applied to the wall mount.
Mounting the bracket to the wall is the bit that you absolutely must get right. If you get it wrong your monitor may well end up on the floor in broken pieces, and we don't want that!
Most interior walls are faced with plasterboard (called "drywall" in the US) which gives a nice surface but has little structural strength. If you have a heavy monitor you'll need to locate the framework within the wall and make sure that at least some of the screws you use penetrate through to the timber or metal "studs" (verticals) or "noggins" (horizontals) inside the wall. Most mounting brackets come with a large number of holes in them so that you can place the bracket in your desired position and then put screws through whichever holes correspond to the location of the frame inside the wall.
Whatever you do, don't just put regular metal screws straight into bare plasterboard and expect them to hold strongly!
If you're using light monitors like mine you can get by with regular metal screws combined with "plaster screws". A plaster screw is a special screw with a very large thread so it can bite strongly into plaster and spread the load across a large area. They have a small hole through the center so you start by driving the plaster screw into the plasterboard using a screwdriver (they're self-tapping, so there's no need for a pilot hole although it can help sometimes) all the way in until they're flush with the face of the wall. You can then screw a regular metal screw into the center of it with the result that it'll bite firmly into the plaster screw and you'll have a fairly strong mount.
If the monitor is mounted fairly close to the wall with a thin bracket the majority of the force exerted will be vertical. There will also be a small horizontal force applied to the screws at the top of the bracket because the monitor will try to tilt forward and down, resulting in torsion (twisting) applied to the bracket.
Whew, just about there! With the brackets in place it's time to lift your monitor(s) onto the wall, step back, and admire your work. Hopefully you won't watch in horror as they crash to the floor.
If you want your status screens to look really slick it's important to conceal the cabling as much as possible. You can cut a hole through the wall directly behind the screen and feed the cable through it, but in my case I was lucky enough to have a pole next to the screen so I just ran the cabling behind and then used velcro cable ties to attach it to the pole. It's not as neat as having the cable run through the wall but it's good enough for this situation, and it looks acceptably neat.
One thing to keep in mind is the length of cable you'll require. Whatever length you estimate it probably won't be enough: you need to allow extra for the end of the cable to loop around a bit behind the monitor, to follow curves, and to reach to the location of the computer that will drive the whole contraption. Do some measuring, figure out how long you need, and add another metre or two for safety. I used 5m DVI and VGA cables for the video, and fitted IEC extension cables (like the ones that are sometimes used to connect a monitor to a computer power outlet) to the power cables so the bulky plugs wouldn't be visible.
Because I used three monitors I ran the power cables for all the monitors to the same location and plugged them into a power strip. That makes it easy to use a single appliance timer to control the power strip and turn on all the monitors at 8am and turn them all off again at 6pm automatically.
The computer used to drive the screens doesn't need to be anything special, but one important consideration is that it should be quiet and preferably not a power-guzzler. It'll be running 24x7 so try to pick something low-power. At IVT we often upgrade machines and there's always a slush-pile of about the last 4 or 6 most recently replaced machines sitting around as spares and for use in testing, so we just grabbed two of those. At the moment we have one computer with a dual-head video card driving two of the screens, and the other computer driving the remaining screen. The plan is to condense it all into just one computer running all three screens but we had problems with video card compatibility and haven't got that far yet.
At this point you should have your screen(s) mounted on the wall, cabling in place, and a computer connected to drive them.
Stay tuned for the next installment, which will cover setting up the data sources to grab the information you want to display on the screens.
One of the things we focus on at Internet Vision Technologies is giving our customers insight into how well their business processes are operating. Seeing what is happening within a business in real-time, or close to it, can be tremendously powerful in terms of closing the feedback loop and giving people a sense of control over where things are going. Not just a "sense" of control, either: real control based on facts, not hunches. Sometimes it's like the difference between driving a car with a blindfold on versus being able to see!
We do this through online systems of course (we're a web app company, after all) but last week I saw a blog post about Panic Software's status board and thought it would be good to do something similar internally. There are all sorts of reports available through our intranet (KPI reporting, ops statistics, project management reports, financial reports, etc) but the problem is that you have to actively go looking for them. Putting some basic facts and figures up on the wall gives it far more immediacy and keeps drawing people's attention to it.
Since a friend of mine is clearing out a bunch of hardware prior to travelling overseas I bought three 22" LCDs from him, and last night I stuck them up on the wall in the central area of the IVT office. A few simple web pages running off the intranet displayed using Google Chrome in full-screen mode, and this is the result:
The left screen is showing the current task queue in our bug / feature request tracking system, broken down by category. The objective of the game is to push all these down toward 0.
The center screen shows Twitter updates that mention IVT or our products, followed by a few odds and ends of data including the number of physical hosts currently running; the number of Xen VMs running; the number of EC2 VMs running; current temperature in Melbourne; number of Brillianz customers (yes, it's a low number - that's because it's not publicly released yet); revenue generated by Brillianz; number of live SB4 sites; and revenue generated by SB4.
The right screen shows a live view of the Arduino-based energy monitoring system running in the office. There are lines for power consumption in each of the workstation pods; building lighting; aircon; server rack power consumption; and general power consumption.
I briefly had a Nagios tactical overview screen on the right monitor but the power monitoring system looks cooler and is of more general interest to non-sysadmins. If I had room for a 4th screen it would be up there though!
The cabling still needs a little cleanup but on the whole it's turned out pretty well.
Update: I've started a series of posts explaining how I set up the screens, including details of the hardware and software. Part 1 is up now at Building a Status Screen, part 1: Hardware.
We need another 3 staff in our Melbourne office right away. We're writing up full job descriptions at the moment and they'll be posted at www.ivt.com.au/jobs in a little while, but in the meantime if you're interested in working at www.ivt.com.au on web applications based on a FOSS platform, let me know if any of these sound interesting: * Helpdesk Support Analyst: Assist existing customers with using the administration functions of their websites, intranets, extranets, and custom web applications. * Web Application Integrator: Take approved interface design concepts and convert them to HTML/CSS, then deploy them on either SiteBuilder (our existing web application platform) or Brilliance (our new development platform) systems on behalf of customers. * Web Application Developer: Work deep in the internals of Brilliance, our next-generation web application platform, building new features that will be used by millions of users around the world. Based on a combination of Flex, PHP, and MySQL, all running on a big Linux server farm. Sound interesting? Know someone else who might be interested? Contact me!.
>> Office chaos
We're currently part way through a massive office refit at Internet Vision Technologies, partly to improve the general work environment and partly to make better use of space since we moved all our hosting infrastructure offsite. As a result it's a disaster area at the moment. We've shoved *everything* into the back half of the building while the front is refitted, then we'll shift everything forward so the back half can be done. So I'm currently jammed into a corner under a bundle of ethernet and just working off my laptop: Likewise Antoine and Steve have desks that look like they're working in a war zone: And this is Andrew having a chat to Senior, with Luke's temporary desk just to the right: Matt probably has the best setup of all: he claimed the old boardroom table and set himself up on it near Neil and Dianne's desks: This morning a couple of the guys had a meeting with a client so they quickly assembled a temporary "meeting room" in the middle of the area where all the new desks will be assembled: Just behind that the table tennis table has also been set up temporarily, since it's been moved out of the back room to make space for desks and random junk: Looking into the new meeting room (with the larger boardroom beyond it) shows how it's starting to come together. Some time next week there will be a glass wall extending right along here to separate the meeting room and boardroom from the work area: So it's a total mess right now, but in a couple of weeks we'll have a shiny new office with that new-car smell :-)