WM: Openbox
GTK: MurrinaGilouche
Not much has changed. Just Wallpaper and Terminal Colors
I wanted to monitor the downstream and upstream power levels on my Scientific-Atlantic modem (provided by my ISP). My intended goal was to keep logs of the power levels and if my modem “froze” then I could go back to the logs and look for any abnormal power levels.
At first, I just logged the power levels to a simple text file. This worked, but the aggressive logging I was doing generated a lot of data. I thought it’d be nice to see how the power levels changed throughout the day.
The following emerged:
Logging Script (python)
#!/usr/bin/env python2
import urllib2
from BeautifulSoup import BeautifulSoup
from lxml import etree
from StringIO import StringIO
import sys
import datetime
URL = 'http://192.168.100.1/system.asp'
def timestamp():
now=datetime.datetime.now()
return now.strftime("%b %d %H:%M:%S")
def error():
print "Error"
return
try:
page = urllib2.urlopen(URL, timeout=10)
except:
print timestamp() + ": # dBmV (rx), # dBmV (tx)"
sys.exit()
soup = BeautifulSoup(page)
# Remove markups, because they break the XML parser.
f = StringIO(str(soup.findAll('tbody')[0]).replace(' ', ''))
dom = etree.parse(f)
nodes = dom.xpath('//font')
# We take every value we can get, but do not use them, yet
modemvalues = []
for i in xrange(0, len(nodes), 2):
modemvalues.append((nodes[i].text, nodes[i+1].text.strip()))
rpl = float(modemvalues[5][1].split(' ')[0]) # dBmV
tpl = float(modemvalues[6][1].split(' ')[0]) # dBmV
print timestamp() + ": " + str(rpl) + " dBmV (rx), " + str(tpl) +" dBmV (tx)"
Usage: ./getModemPl.py >> logFile (cron job)
Output:
Nov 06 22:30:41: 0.7 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:31:41: 0.8 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:32:41: 0.9 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:33:41: 0.5 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:34:41: 0.5 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:35:41: 0.5 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:36:41: 0.6 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:37:41: 0.7 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:38:41: 0.7 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:39:41: 0.7 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:40:41: 0.7 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:41:41: 0.6 dBmV (rx), 35.4 dBmV (tx) Nov 06 22:42:41: 0.7 dBmV (rx), 35.4 dBmV (tx)
Graph Generator (takes every 5th log entry)
#!/bin/bash
if [[ ! $1 ]]; then
echo "No File to Parse"
exit
fi
startRange=$2
endRange=$3
tmpDir="/tmp"
currentDir="$PWD"
logFile="$1"
data="/tmp/modempowerdata"
# Takes every sample from log File
#cat $logFile | sed 's/.dBmV.(rx),//' | sed 's/.dBmV.(tx)//' | sed 's/: / /' | perl -pe 's/(.*?)\s(.*?)\s(.*)/$1-$2-$3/;' > $data
# Takes every 5th sample (we log every minute)
cat $logFile | sed 's/.dBmV.(rx),//' | sed 's/.dBmV.(tx)//' | sed 's/: / /' | sed -n 'p;n;n;n;n;' | perl -pe 's/(.*?)\s(.*?)\s(.*)/$1-$2-$3/;' > $data
date=$(head -1 $logFile | cut -d' ' -f1,2)
date2=$(echo $date | sed 's/ /-/')
png="$currentDir/$date2.png"
svg="$currentDir/$date2.svg"
#rm "$data"
plot=""
cat << EOF | gnuplot
#
# --- gnuplot ---
#
# PNG output
#set terminal png enhanced size 1400,900
set terminal pngcairo size 1200,600 enhanced font 'Verdana,10'
set output "$png"
# SVG Output
#set terminal svg enhanced size 1440,900
# Adds White Background to SVG
set object 1 rect from screen 0, 0, 0 to screen 1, 1, 0 behind
set object 1 rect fc rgb "white" fillstyle solid 1.0
#set output "$svg"
# Line Sytes
set style line 1 lc rgb "#8b1a0e" pt 1 ps 1 lt 1 lw 2
set style line 2 lc rgb "#5e9c36" pt 6 ps 1 lt 1 lw 2
set style line 12 lc rgb '#808080' lt 0 lw 1
set timefmt "%b-%d-%H:%M:%S"
set grid
#set grid back ls 12
set key left box
set title "$date - Power Levels"
# X Label
set xdata time
set format x "%H:%M"
#set xlabel "Time"
# Y Data
set ylabel "dBmV (rx)"
#set yrange [-2:2]
#set ytics 0.2
set yrange [-1.6:4.4]
set ytics 0.2
# Y2 Data
set y2range [31:37]
set y2label "dBmV (tx)"
set y2tics 0.2
plot "$data" u 1:2 ls 1 axis x1y1 ti "rx" with lines, "$data" u 1:3 ls 2 axis x1y2 t "tx" with lines
EOF
Notes:
Graph:
Feel free to use the scripts, they work for me, and hopefully they work for you. As always, use at your own risk.
Since weather.com is ending their free XOAP service conkyForecast will no longer work at the end of this month.
Therefore I wrote a small script to get the temperature and condition from Weather Underground
#!/usr/bin/python
#
# Fetches Weather info from Weather Underground
#
# Usage: ./wundergound.py zipcode
#
# International:
# * Go to http://www.wunderground.com/
# * Find your city
# * Click the RSS icon
# * Station ID is the number that follows /stations/ in the url
#
#
# Values are either True or False
metric=False
international=False
import sys
import feedparser
def usage():
print("Usage:")
if international:
print(" ./wunderground.py StationID")
else:
print(" ./weunderground.py zipcode")
sys.exit(1)
if not len(sys.argv) == 2:
usage()
location=sys.argv[1]
if international:
url="http://rss.wunderground.com/auto/rss_full/global/stations/"
else:
url="http://rss.wunderground.com/auto/rss_full/"
feed=feedparser.parse(url+location)
if not feed.feed:
# Assume Error
print("Error")
sys.exit(1)
current=feed['items'][0].title
if metric:
temp=current.split(",")[0].split(":")[1].split("/")[1].strip()
else:
temp=current.split(",")[0].split(":")[1].split("/")[0].strip()
condition=current.split(",")[1].split("-")[0].strip()
print(temp, "-", condition)
Example:
$ ./wunderground 11201
69.6F - Clear
I’m using this script for my conky config:
${execi 600 /home/pyther/scripts/wunderground 11201}
So for whatever reason you need to install Windows 7 from a flash drive that’s not a problem!
In Linux:
mkfs.vfat -F 32 /dev/sdxmlabel -i /dev/sdd1 ::WIN7x64 (optional)unzip grub4dos-0.4.4.zip./bootlace.com /dev/sdxtitle Install Windows 7 root (hd0,0) chainloader (hd0,0)/bootmgr
TIP: To install any version of Windows 7 (Home Premium, Professional, Ultimate) remove ei.cfg from the sources directory. However, you still need a product key for the appropriate version.
In Windows:
That’s it, boot from the flash drive you are all good.
Note: The windows disk formater writes code to the MBR and VBR. This obvisouly doesn’t happen in Linux therefore we need to use grub4dos as our bootloader.
I was looking for a solution that would allow me to remotely connect to machines on the local network. We often get phone calls form users asking for help. It is way easier to provide help if we can see their screens and we usually end up having to visit their workstation. This can be time consuming, especially when we are in the middle of a project.
In my search, I came across a wonderful gem called Microsoft Remote Assistance which happens to be included in Windows XP/Vista/7.
How does it Work?
Enabling Remote Assistance on the Domain (via Group Policy)
Computer Configuration -> Policies -> Admin Templates -> System -> Remote Assistance
You then have two choices “Allow helpers to control the computer” or “Allow helpers to only view the computer”. In addition to selecting one of these choices, you have to add the users and groups that should be able to provide remote assistance.
Offering Remote Assistance
How can I possibly remember all the host names?
I’ve created a small C# application that you can have your users run. I would put it on a shared drive and push out a shortcut via group policy.
WhoAmI
Source: WhoAmI.zip
Bin: Included in source ./WhoAmI/bin/Release/WhoAmI.exe
Offering Remote Assistance – A nice GUI app
Although the method mentioned above works it is long and convoluted. I put together a small C# app to easily offer Remote Assistance to a user.
The app simply calls msra.exe /offerra <hostname>
Source: RemoteAssistance.zip
Bin: Included in souce ./RemoteAssistance/bin/Release/RemoteAssitance.exe
Ideas for the two Easy GUI apps came from SYNACK over at edugeek. http://www.edugeek.net/forums/coding/49448-easy-gui-remote-assistance-support.html
Why would I want to use Conditional Forwarding?
In my case, my local dns server has entries for local hostnames such as m2n.ion.lan, mongo.ion.lan, and tux.ion.lan. If I am using the vpn dns, then these address lookups would fail. By using Conditional Forwarding I can do all lookups locally, except for ones that match the remote top level domain (example.local). Anything that matches example.local would be forwarded to the remote dns server.
Problem:
Of course the remote ping fails because the local DNS server knows nothing about the remote domain. If I was to configure my machine to use the remote DNS server the opposite would happen. I would be able to ping server.remote.local, but a ping to server.ion.lan would fail.
Solution: Use dnsmasq with conditional forwarding to forward *.work.local requests to the remote dns server.
1. Install dnsmasq using your local package manager
2. Edit /etc/dnsmasq.conf
# Tells dnsmasq to forward anything with the domain of remote.local to dns server 10.25.11.2 server=/remote.local/10.25.11.2 # Listen to requests only coming from the local machine listen-address=127.0.0.1 # Do not cache anything # A decent dns server will already cache for your local network cache-size=0
3. Edit /etc/resolv.conf
# Local LAN Domain domain ion.lan # local dnsmasq server nameserver 127.0.0.1 # Your main dns server (dnsmasq will forward all requests to this server) nameserver 10.20.1.1
4. Start dnsmasq
5. Test – ping a local server and remote server using the FQDN
All dns requests will be forwarded to 10.20.1.1 except any matching *.remote.local. server.remote.local will be forwarded to 10.25.11.2
The OpenVPN server can pass DNS servers and a domain name to the client. This gives the benefit of using the remote dns servers for local hostname lookups.
Finding a good script that worked to do this provide difficult…
In server.conf add:
push "dhcp-option DOMAIN ion.lan" push "dhcp-option DNS 10.25.11.2"
Then save this script on the client in same location as the client config
#!/bin/bash
case "$1" in
up)
mv /etc/resolv.conf /etc/resolv.conf.bak
echo "# Generated by OpenVPN Client UP Script" > /etc/resolv.conf
for opt in ${!foreign_option_*};
do
echo ${!opt} | sed -e 's/dhcp-option DOMAIN/domain/g' -e 's/dhcp-option DNS/nameserver/g' >> /etc/resolv.conf
done
;;
down)
mv /etc/resolv.conf.bak /etc/resolv.conf
;;
*)
echo "Pass either UP or DOWN"
;;
esac
In the client.conf add
script-security 2 up "./vpn_dns_update.sh up" down "./vpn_dns_update.sh down"
Now connect and check /etc/resolv.conf to see if the VPN nameserver and domain is listed.
Syslinux is a simple bootloader for fat, ext2/3/4, and brtfs.
Syslinux works in the following way (in a nutshell):
For a more detailed explanation: https://wiki.archlinux.org/index.php/Syslinux#Syslinux_Boot_Process
Sample configuration:
UI vesamenu.c32 DEFAULT arch PROMPT 0 MENU TITLE Boot Menu MENU BACKGROUND splash.png TIMEOUT 100 MENU WIDTH 78 MENU MARGIN 4 MENU ROWS 5 MENU VSHIFT 10 MENU TIMEOUTROW 13 MENU TABMSGROW 11 MENU CMDLINEROW 11 MENU HELPMSGROW 16 MENU HELPMSGENDROW 29 # Refer to http://syslinux.zytor.com/wiki/index.php/Doc/menu MENU COLOR border 30;44 #40ffffff #a0000000 std MENU COLOR title 1;36;44 #9033ccff #a0000000 std MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all MENU COLOR unsel 37;44 #50ffffff #a0000000 std MENU COLOR help 37;40 #c0ffffff #a0000000 std MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std MENU COLOR msg07 37;40 #90ffffff #a0000000 std MENU COLOR tabmsg 31;40 #30ffffff #00000000 std LABEL arch MENU LABEL Arch Linux LINUX /vmlinuz26 APPEND root=/dev/sda2 ro nomodeset INITRD /kernel26.img LABEL archfallback MENU LABEL Arch Linux Fallback LINUX /vmlinuz26 APPEND root=/dev/sda2 ro nomodeset INITRD /kernel26-fallback.img
As you can see, the majority of the config contains MENU statements declaring colors and positing for the menu. If you removed all the MENU statements, the config would be less than 20 lines.
Screenshot:
I was lazy and took a screenshot of the Arch Linux installer menu. The configuration above generates the same menu, except there are only two boot choices, Arch Linux and Arch Linux Fallback.
The arch wiki has a whole lot of good information on configuring Syslinux. https://wiki.archlinux.org/index.php/Syslinux
Well after some experimentation and playing around I have found some new information out regarding listening to iheartradio from the command line in Linux.
Newer versions of mplayer have support to play the rtmp:// protocol eliminating the need for rtmpdump.
Quick Recap on how to grab the rtmp:// url from an iheartradio stream
http://p2.STATION_ID.ccomrcdn.com/player/player_dispatcher.html?section=radio&action=listen_live; where station id is the call letters (ex: wtfx-fm)NOTE: The RTMP URL changes every 5-10 minutes! You must fetch the new url everytime.
To play the stream with mplayer:
mplayer "rtmp://cp21366.live.edgefcs.net/live/Lou_KY_WTFX-FM_OR..." -novideo
The -novideo option is very improtant otherwise mplayer will take 5+ minutes trying to find video for the stream (there is none).
This is all great, but this is a lot of work everytime you want to listen to a iheartradio stream. Therefore I have coded up a script.
The Script:
#!/usr/bin/env python
import subprocess
import time
import urllib2
import xml.etree.ElementTree as ET
import os
import datetime
#Location of Stream to be SAVED
DefaultStation="wtfx-fm"
def getXML():
data=urllib2.urlopen('http://p2.'+station+'.ccomrcdn.com/player/player_dispatcher.html?section=radio&action=listen_live').read()
xml=ET.fromstring(data)
return xml
def getSongInfo():
xml=getXML()
artist=xml.find('ListenLiveInitialize/JustPlayed/song/artist').attrib['name']
title=xml.find('ListenLiveInitialize/JustPlayed/song/track').attrib['track_title']
return artist,title
while True:
station=raw_input("Enter Station ID [" + DefaultStation + "]: ")
if not station:
station=DefaultStation
try:
xml=getXML()
except urllib2.URLError:
print "Error - Invalid Station ID or Web Server Problem - Try Again"
else:
break
while True:
try:
TIME=int(raw_input("Time Stream will Play (in minutes): "))
except ValueError:
print "Error - Invalid Time - Try Again"
else:
break
rtmpurl=xml.find("ListenLiveInitialize/StreamInfo/stream").attrib['primary_location']
mp=subprocess.Popen(['/usr/bin/mplayer', rtmpurl, '-novideo', '-ao', 'alsa', '-quiet'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
mpPID=mp.pid
endTime = datetime.datetime.now() + datetime.timedelta(minutes=TIME)
OldSongInfo=[]
while datetime.datetime.now() < endTime:
SongInfo=getSongInfo()
if not SongInfo == OldSongInfo:
OldSongInfo = SongInfo
print SongInfo[0] + " - " + SongInfo[1]
time.sleep(5)
print("Stopping MPlayer...")
os.kill(mpPID, 2)
print "Done"
N900
I got this script working on the N900 by downloading the Maemo 5 SDK and compiling the mplayer binary from a recent svn snapshot. Luckily, I didn't run into any problems. Although mplayer works with the N900, without any patches, it is not flawless. For example, video gets jittery and skips when the backlight switches off. I would recommend leaving mplayer form extra installed and storing the mplayer you compiled in /opt. With audio playback I do not have any issues, especially with the iheartradio rtmp stream!
UPDATE: http://pyther.net/blog/index.php/2010/08/iheartradio-command-line-mplayer/
If you have ever listened to any Clear Channel FM radio station then I am sure you have heard the ads to listen to the station online through iheartradio. The only problem is that iheartradio is a bulky and slow flash application. On a powerful desktop that isn’t a huge issue, but with my N900 (600mhz cpu, 256MB Ram) it takes over 5 minutes to start streaming the radio station. Of course, iheartradio has an application for the iPod and Blackberry, but no app for the N900.
I went on a quest to figure out how to listen to iheartradio without the bulky flash application and this is what I found.
Step 1:
The url of the a stations stream is can be found in a XML file, at URL “http://p2.STATION_NAME.ccomrcdn.com/player/player_dispatcher.html?section=radio&action=listen_live”
If I want to listen to The Fox (call letters: WTFX-FM), the URL of the XML would be “http://p2.wtfx-fm.ccomrcdn.com/player/player_dispatcher.html?section=radio&action=listen_live”
Open up the url in a web browser and grab the rtmp url which is between the <stream> tags. rtmp://cp21366.live.edgefcs.net/live/Lou_KY_WTFX-FM_OR@s7696?auth=daEcEbgdNb4a3bdcKdYcrcgcGara0c1c3cZ-bmC7wi-4q-LM3Y9_7nqEDps4CCulBtyp&aifp=1234&CHANNELID=981&CPROG=_&MARKET=LOUISVILLE-KY&REQUESTOR=WTFX-FM&SERVER_NAME=p2.wtfx-fm.ccomrcdn.com&SITE_ID=2038&STATION_ID=WTFX-FM&MNM=2&TYPEOFPLAY=0
Step 2:
Download and Install rtmpdump and mplayer
Step 3:
Lastly open up the terminal and enter the following command: rtmpdump -r $RTMPURL -v | mplayer -
-r tells rtmpdump the url of the stream
-v tells rtmpdump that the stream is a live stream
The | (pipe) directs stdin to mplayer and the – after mplayer tells mplayer to read data from stdin
Example: rtmpdump -r "rtmp://cp21366.live.edgefcs.net/live/Lou_KY_WTFX-FM_OR@s7696?auth=daEcEbgdNb4a3bdcKdYcrcgcGara0c1c3cZ-bmC7wi-4q-LM3Y9_7nqEDps4CCulBtyp&aifp=1234&CHANNELID=981&CPROG=_&MARKET=LOUISVILLE-KY&REQUESTOR=WTFX-FM&SERVER_NAME=p2.wtfx-fm.ccomrcdn.com&SITE_ID=2038&STATION_ID=WTFX-FM&MNM=2&TYPEOFPLAY=0" -v | mplayer -
Things to watch out for:
Sources:
Maybe when I get some more time and become more ambitious I will write a small python wrapper that will extract the url from the xml file and start the stream.