Installing Munin on Linux

I read several articles on how to install the Munin monitoring tool for Linux, and they all seem to over-complicate the install, or end up with an install that doesn’t work.

This article will walk you through installing Munin for a local monitor/node setup on Debian 8 64-bit. Tweak it to your liking. This also assumes that you are running as root. Prefix commands with sudo where appropriate.

Start by making sure your system is up to date:

apt-get update
apt-get upgrade

Next, install apache, munin, munin-node, munin-plugins-extra and dependencies.

apt-get install apache2 apache2-utils libcgi-fast-perl libapache2-mod-fcgid munin munin-node munin-plugins-extra

Now, edit the munin config file /etc/munin/apache24.conf

nano /etc/munin/apache24.conf

Change the section as follows:

Require all granted
Options FollowSymLinks SymLinksIfOwnerMatch

Do the same with the section, adding the Options line if it’s not preset.

Now restart both apache and munin-node.

/etc/init.d/apache2 restart
/etc/init.d/munin-node restart

You can now view munin data at http:///munin

Sound not working in Java apps in Ubuntu Linux

I tested Ubuntu 14.04 LTS in VMware. I started with a clean install. I made sure sound was working in the VM, then updated everything using this command:

sudo apt-get update && sudo apt-get upgrade

I then checked Software Updater and found a few more packages that didn’t get updated, and updated them.

I then made a backup of the VM to have a good baseline. I then installed OpenJDK 7 and the icedtea-7-plugin, using the following command:

sudo apt-get install openjdk-7-jre icedtea-7-plugin

I did not have openjdk-6, icedtea 6, or Oracle Java installed. If you do have any of those installed, try removing them to prevent any conflicts.

You can test your Java sound output any trying any Java applet that produces sound, such as this SoundApplet demo. If you don’t hear sound from it, you have an issue. If you have more than 1 sound device, check the other sound device for the sound output. In my case I only had 1 device (through virtualization), but it worked fine.

I also tried AllStar and was able to hear audio from the node announcements just fine, albeit with occasional crackle, perhaps due to the limited resources of the VM. I tried transmitting but did not get a reply from the few nodes I tried.

1 2 3 4 56

If you have something to add, please feel free to comment below.

Weather Underground forecast data in text display

One of the uses I found for my Raspberry Pi was using it to display weather data. I retrieved the weather data from Weather Underground using their API, parsed it, and displayed it on my RPi’s small LCD. This gave me an always-on view of the weather, which was nifty, and it was done all in bash scripting with a few external programs to parse the data.

This script is very customizable and extensible. You could use it to do any number of weather-related tasks.

I reduced the font size on the LCD to Terminus 6×12 using the following command:

sudo dpkg-reconfigure console-setup

This helped make room for all the forecast data on the tiny LCD. If you are running this on a PC, it’s not necessary.

For the smoothest updates, I have found it ideal to run the script under ‘watch’, as so:

watch ./

I tired doing a ‘while true; do… clear… done’ loop, but the refresh rate was too low and the updates were not smooth.

Here is the script:

# requires fold, wget, xmlstarlet, find, tr, awk
# RPi 320x240 LCD is 53x20 at 6x12 font

zip="12345" # Set to your zipcode
apikey=123123123123 # Set to your wunderground API key. See
apiurl= # Do not change
refetch=10 # API data refetch time, in minutes (15 recommended, <4 will exceed free API limit)
refresh=30 # time (in seconds) to wait between screen refreshes # not yet implemented

# main loop # not yet finished

# check age of cache files. If allowable, delete it to refetch data
# 1 second pauses to allow for disk writes to settle and help prevent errors
find ./ -mmin +$refetch -name wx_forecast.xml -delete
if [ ! -f wx_forecast.xml ]; then
sleep 1
wget $apiurl/$apikey/forecast/q/$zip.xml -qO wx_forecast.xml
sleep 1

find ./ -mmin +$refetch -name wx_conditions.xml -delete
if [ ! -f wx_conditions.xml ]; then
sleep 1
wget $apiurl/$apikey/conditions/q/$zip.xml -qO wx_conditions.xml
sleep 1

#Reference the wunderground API documentation and the downloaded xml format for data
#use 'xmlstarlet el filename.xml' to see the xml tree elements
#xmlstarlet command and xml tree reference variables
xmlcmd="xmlstarlet sel -t -v"
XMLSF="$xmlcmd //response/forecast/simpleforecast/forecastdays"
XMLTF="$xmlcmd //response/forecast/txt_forecast/forecastdays"
XMLCC="$xmlcmd //response/current_observation"
# set variables from xml
# there's probably a better way to do this, but this is plenty fast
display_location=`$XMLCC/display_location/full wx_conditions.xml`
temp=`$XMLCC/temp_f wx_conditions.xml`
temperature_string=`$XMLCC/temperature_string wx_conditions.xml`
feelslike=`$XMLCC/feelslike_f wx_conditions.xml`
heat_index=`$XMLCC/heat_index_f wx_conditions.xml`
windchill=`$XMLCC/windchill_f wx_conditions.xml`
relative_humidity=`$XMLCC/relative_humidity wx_conditions.xml`
weather=`$XMLCC/weather wx_conditions.xml`
pressure=`$XMLCC/pressure_in wx_conditions.xml`
pressure_trend=`$XMLCC/pressure_trend wx_conditions.xml`
if [[ "$pressure_trend" == "0" ]]; then pressure_trend="="; fi
UV=`$XMLCC/UV wx_conditions.xml` # | awk -F. '{print $1}'`
precip_1hr=`$XMLCC/precip_1hr_in wx_conditions.xml`
precip_today=`$XMLCC/precip_today_in wx_conditions.xml`

high=`$XMLSF/forecastday[1]/high/fahrenheit wx_forecast.xml`
low=`$XMLSF/forecastday[1]/low/fahrenheit wx_forecast.xml`
DAY=`$XMLSF/forecastday[1]/date/weekday wx_forecast.xml`
DATE=`$XMLSF/forecastday[1]/date/pretty_short wx_forecast.xml`
maxwind=`$XMLSF/forecastday[1]/maxwind/mph wx_forecast.xml`
maxwind_dir=`$XMLSF/forecastday[1]/maxwind/dir wx_forecast.xml`
avewind=`$XMLSF/forecastday[1]/avewind/mph wx_forecast.xml`
avewind_dir=`$XMLSF/forecastday[1]/avewind/dir wx_forecast.xml`
snow_day=`$XMLSF/forecastday[1]/snow_day/in wx_forecast.xml`
snow_night=`$XMLSF/forecastday[1]/snow_night/in wx_forecast.xml`
snow_allday=`$XMLSF/forecastday[1]/snow_allday/in wx_forecast.xml`
qpf_day=`$XMLSF/forecastday[1]/qpf_day/in wx_forecast.xml`
qpf_night=`$XMLSF/forecastday[1]/qpf_night/in wx_forecast.xml`
qpf_allday=`$XMLSF/forecastday[1]/qpf_allday/in wx_forecast.xml`

title_1=`$XMLTF/forecastday[1]/title wx_forecast.xml | tr '[:lower:]' '[:upper:]'`
fcttext_1=`$XMLTF/forecastday[1]/fcttext wx_forecast.xml`
pop_1=`$XMLTF/forecastday[1]/pop wx_forecast.xml`
title_2=`$XMLTF/forecastday[2]/title wx_forecast.xml | tr '[:lower:]' '[:upper:]'`
fcttext_2=`$XMLTF/forecastday[2]/fcttext wx_forecast.xml`
pop_2=`$XMLTF/forecastday[2]/pop wx_forecast.xml`
title_3=`$XMLTF/forecastday[3]/title wx_forecast.xml | tr '[:lower:]' '[:upper:]'`
fcttext_3=`$XMLTF/forecastday[3]/fcttext wx_forecast.xml`

#display report
#sometimes wunderground omits data from the xml forecast or sends back a malformed
#xml document. You could rotate the xml cache files and use the old ones as a
#fallback if you so desired, but I find the 15 minute update period to be
#just fine, and I don't mind waiting for an update.

echo "Currently at ${display_location}, $zip:"
echo -n "${weather}, ${temperature_string}"
if [[ "$windchill" != "NA" ]]
then echo ", (Wind Chill ${windchill} F)"
else if [[ "$heat_index" != "NA" ]]
then echo ", (Heat Index ${heat_index} F)"
else if [[ "${feelslike}" != "$temp" ]]
then echo ", (Feels like ${feelslike} F)"
else echo "."
echo "Humidity ${relative_humidity}, Pressure ${pressure}"(${pressure_trend}), UV index $UV/10"
echo "Today: ${low}/${high} F, wind ${avewind_dir:-"--"} @ ${avewind:-"--"} mph (Gust ${maxwind_dir:-"--"} @ ${maxwind:-"--"} mph)"
if [[ "$qpf_allday" != "0.00" ]]; then echo "RAIN: AM ${qpf_day:-"--"}in (${pop_1}%), PM ${qpf_night:-"--"}in (${pop_2}%), Total: ${qpf_allday:-"--"}in"; fi
if [[ "$snow_allday" != "0.0" ]]; then echo "SNOW: AM ${snow_day:-"--"}in, PM ${snow_night:-"--"}in, Tot: ${snow_allday:-"--"}in"; fi
if [[ "$precip_today" != "0.00" ]]; then echo "Total Precip: ${precip_1hr}in last hour, ${precip_today}in today"; fi
echo "${title_1}: $fcttext_1" | fold -sw $COLUMNS
echo "${title_2}: $fcttext_2" | fold -sw $COLUMNS
echo "${title_3}: $fcttext_3" | fold -sw $COLUMNS
echo "( --=N/A / Data from, every ${refetch} min)"
#sleep $refresh

Last updated: 11-21-2015

Installing and configuring Samba on Raspberry Pi

If you want your Raspberry Pi to share its files and folders over the network, you want to install and configure Samba.

Start off by installing the basic Samba requirements:

sudo apt-get install samba samba-common-bin

Edit the samba config file

sudo nano /etc/samba/smb.conf

edit the workgroup= line to match your network. workgroup=WORKGROUP is the default and usually fine. It needs to match what your Windows PCs are set to.

only guest=no
create mask=0777
directory mask=0777

Add the pi user to samba. Use the same password for the pi user:

sudo smbpasswd -a pi

It takes about 2 minutes for the changes to take effect, but after this you should have no problem exploring files over the network. Note that some may be owned by root and you may have an issue writing to them.

If you have trouble logging in under Windows (password errors), try using “raspberrypipi” (raspberrypi-backslash-pi) as your username (without the quotes)

Setting up the SainSmart WaveShare SpotPear 3.2 inch Raspberry Pi LCD (V3)

I picked this inexpensive LCD up at MicroCenter for my Raspberry Pi, but getting it to work was a bit of a chore.

I wanted to install it onto a Raspberry Pi 2 which is already set up and running some software of mine. Therefore, I wanted to install it in as few steps as possible. Fortunately, WaveShare provides some drivers (but they don’t clearly document the setup process).

Here’s now to set it up:

Do the normal update/upgrade procedure:

sudo apt-get update && sudo apt-get upgrade

Download “LCD-show-151020.tar.gz for 2015-09-24-raspbian-jessie” from the Resources section of the product page on WaveShare, and transfer it to your Pi, or use the following command from your Pi to download it directly:

tar xvzf LCD-show-151020.tar.gz
cd LCD-show/

and run this command to set up the 3.2″ screen. :


Important note: The LCD32-show and LCD-hdmi scripts will overwrite several system files. If you have customized them, or have concerns, you are strongly advised to read through the scripts before running, and consider merging the changes in manually. Here is the list of touched files:

  • /boot/overlays/waveshare*-overlay.dtb
  • /etc/X11/xorg.conf.d/99-calibration.conf
  • /usr/share/X11/xorg.conf.d/99-fbturbo.conf
  • /boot/cmdline.txt
  • /etc/inittab
  • /boot/config.txt

After a few seconds, you Pi will reboot, and the screen should be active. You can refer back to the WaveShare page to see documentation on how to switch to HDMI and back to the LCD.

Follow these steps to download and install xinput_calibrator to calibrate the touchscreen. I noticed that on my panel, the touchscreen does not respond well to input; I suspect I have a defective panel.

sudo apt-get install libx11-dev libxext-dev libxi-dev x11proto-input-dev
sudo make install

Now, following the directions from WaveShare, you can run this command to calibrate the touchscreen:

DISPLAY=:0.0 xinput_calibrator

Refer to WaveShare’s page on how to edit 99-calibration.conf to save the calibration data so it persists over reboots.

Comments are welcome.

Raspberry Pi heartbeat LED

The Raspberry Pi has two LEDs on the front: One hardwired as a power indicator, and the other is (by default) an SD card activity indicator. This second LED can be changed via software to anything (even a GPIO), but for this, I’m going to show you how to set it as a heartbeat indicator.

sudo su
modprobe ledtrig_heartbeat
echo heartbeat > /sys/class/leds/led0/trigger

The Pi’s led should now start blinking as a heartbeat indicator. If you want to restore the default behavior, you can do so:

echo mmc0 > /sys/class/leds/led0/trigger

That’s all there is to it.

First steps with the Raspberry Pi or Pi 2

After getting a Raspberry Pi (or Pi 2), here are the first steps you should take:

login with username pi, password raspberry.

Configure the Pi:

sudo raspi-config
  • Advanced options
    • A0 Update this tool
  • Expand filesystem
  • Change user password
  • Internationalization options:
    • Change locale: Add your locale (Removing the default en_GB.UTF-8 caused display issues on mine, so just add your locale.)
    • Change Timezone

Next, update the Pi:

sudo apt-get update
sudo apt-get upgrade

Last, update the firmware:

sudo rpi-update

How much data does a Voice-over-LTE call use, and does it bill against your data plan?

Yesterday a friend of mine sent me this text message:

So, I spoke to two separate AT&T representatives, one on Tuesday and the other yesterday, and they both said that VoLTE calls when available will subtract from monthly cellular data.
So, I spoke to two separate AT&T representatives, one on Tuesday and the other yesterday, and they both said that VoLTE calls when available will subtract from monthly cellular data.

Well, I can’t well ignore that. I reached out to AT&T via Twitter for comment:

@ATT @ATTCares Can you comment on VoLTE data usage?
@ATT @ATTCares Can you comment on VoLTE data usage?

Not receiving a response, I decided to do some ballparking on my own. I wanted a rough estimate of the peak usage that VoLTE could use under any circumstances, because, what if it’s true?

So, first thing to note is that under AT&Ts roll-out of VoLTE, they’re introducing HD Voice. HD Voice is also being rolled out on other carriers, some possibly independent of a VoLTE roll-out, but since I’m focusing on bandwidth utilization, that difference is not applicable to this.

Now, for the purposes of VoLTE, there are two codecs in play here. AMR-NB (for narrowband, normal calls), and AMR-WB (for wideband, HD Voice calls) [source]. AMR-WB will naturally have the higher bandwidth utilization of the two.

The AMR-WB codec uses, at peak, a 23.85kbps (kilobits) codec [source]. That’s one-way, making it 47.7kbps peak for both ways. I’ll say 48kbps to add a little overhead. This number is in line with an article at NetworkWorld, which states that VoLTE calls come out to about 30-40kbps at peak. That comes out to 6kBps (kilobytes), both ways, at peak. Roughly speaking. It’s possible for the codec to shift to a lower bandwidth during silences and lower frequency-range conversations, or during network congestion, and that’s important to understand.

So, doing the math on a 15-minute phone call will give you a peak usage of 6kB/sec, 360kB/min, and 5.4MB/15min (1MB=1000kB). That’s absolute peak. All other usage not withstanding, that’s [very] roughly at least 92.5 hours or 5,550 minutes of talking on your 2GB plan.

And that’s if VoLTE calls bill against your data plan.

Thoughts on this? Corrections on my math? Please feel free to comment below. 

Synology Antivirus Essential detects PHP.Exploit.CVE_2015_2331-3

Today my DiskStation emailed me about detecting malware in the system files. When I looked at the log, I saw this:

Antivirus Essential detects Php.Exploit.CVE_2015_2331-3 in zip
Antivirus Essential detects Php.Exploit.CVE_2015_2331-3 in zip

It appears this is a false positive in the ClamAV database.

Further reading:

If your Synology reports the same, simply restore the quarantined file, update virus definitions, and re-scan. It should come up clean. If you had configured Antivirus Essential to automatically delete files, you may have to restore the DSM OS to get the file back.