Armand Halbert
Customer Success Engineer

Resume - pdf
Resume - text

Published on:
Wednesday, October 30, 2013

Adding the Weather to the tmux status bar

I decided to add a weather feature in my tmux status bar. I saw this could be done via powerline, and I initially tried to add it through there. I gave up after a few hours of trying to patch my fonts, although I must say powerline looks nice done right.

I then set out to work on rolling my own script to display the weather. It consisted of 3 parts: * A python script that fetched weather from the internet. * A launchd job to run it periodically. * A tmux command to read the file.

The python script was relatively simple. I got some api keys for the relevant services, and then found what data I wanted from my requests, and wrote it. I picked my default location as umass, in case geoIP lookup fails.

import urllib3
import re
import us
import string
import json

http = urllib3.PoolManager()
req = http.request('get', "")
ip =[:-1]
#Defalit location
state = "MA"
town = "Amherst"
#where are we?
req = http.request('GET', '' + ip)
if req.status == 200:
    data = re.split(';',
    state = (us.states.lookup(data[5]).abbr).upper()
    town = data[6].replace(' ', '_')
#get weather conditions
weatherAddress = string.Template("$@state/$@town.json").substitute({'state':state,'town':town})
req = http.request('GET', weatherAddress)
conditions =  json.loads('[' + + ']')[0]
forecastAddress = string.Template("$@state/$@town.json").substitute({'state':state,'town':town})
req = http.request('GET', forecastAddress)
forecast =  json.loads('[' + + ']')[0]
#output weather to file
output = "$@weather, $@future $@{temperature}, $@hi/$@low F, $@wind mph"
weatherdic ={'weather': conditions['current_observation']['weather'], 'future':forecast['forecast']['simpleforecast']['forecastday'][1]['conditions'], 'temperature':conditions['current_observation']['temperature_string'], 'hi': forecast['forecast']['simpleforecast']['forecastday'][0]['high']['fahrenheit'], \
    'low':forecast['forecast']['simpleforecast']['forecastday'][0]['low']['fahrenheit'], 'wind': forecast['forecast']['simpleforecast']['forecastday'][0]['avewind']['mph']}
with open('/Users/ahalbert/.weather', 'w') as weatherfile:

I then tried to set up a cron job. This, however ended in failure when I realized launchctl had replaced cron. So after reading through the launchctl documentation, I added the following to ~/Library/LaunchAgents/

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Of course, even after this, launchctl load ~/Library/LaunchAgents/ gave me a permission denied error, which is due to running the command in iterm and/or tmux, when it must be done in

I also had to be reminded that /bin/sh does not execute as me, and requires extra permissions to read/execute my file. However, now information is gathered every 30 minutes, and put into my .weather file.

The last part involved setting up my tmux configuration. I added:

set status-interval 30 #update every 30 seconds
set -g status-right-length 150 #Weather string is longer than the default so I had to extend it
set -g status-right '#(cat ~/.weather) #h #(~/dotfiles/ %y-%m-%d %H:%M'


You may have noticed in my configuration, I also wrote a battery script, which consists of

ioreg -l | grep -i capacity | tr '\n' ' | ' | awk '{printf("%.2f%%", $@10/$@5 * 100)}' |  grep -v '^$@'

The results:


I am quite happy with it. I no longer need to switch to the dashboard if I want to see a weather forecast.

<< Previous Next >>