PingMonitor2 - Extended ping monitoring using LedBorg
We recommend using the new driver free based scripts for LedBorg.
The new driver free examples can be found here, the installation can be found here.
So you have tried the PingMonitor script, but there are not enough colour levels to help you judge quality, maybe we should try dithering...

PingMonitor2.py drives the LedBorg using a dithering algorithm to generate partial levels between the main levels:
to 22% |
to 44% |
to 67% |
to 89% |
to 110% target :) |
to 132% |
to 155% |
to 177% |
or more |
or failed |
So if we have say 133%, it will toggle between lime green and yellow so they are both on roughly half of the time, since it is roughly half-way between the two levels.
The downside to this is you can see the light flickering.
There are some settings you may wish to change:
delayInterval, line 21
The time to wait between pings, in secondscolourTimeout, line 18
The colour to use if a ping times out or has an errorcolourGrade, line 17
The colour gradient to use, from 0% to 200% oftargetPingditherCount, line 19
The number of cycles used to represent a single levelditherDelay, line 20
The time to wait between dither cycles
Save the text file on your pi as PingMonitor2.py
Make the script executable using
chmod +x PingMonitor2.pyand run using
./PingMonitor2.py targetPing address_or_ip
#!/usr/bin/env python
# coding: Latin-1
# Load the libraries we need
import time
import sys
import os
import threading
# Make a function to set the LedBorg colour
def SetColour(colour):
LedBorg=open('/dev/ledborg','w')
LedBorg.write(colour)
LedBorg.close()
# User settings
colourGrade = ['002', '012', '022', '021', '020', '120', '220', '210', '200']
colourTimeout = '202' # Colour to use for ping failures
ditherCount = 4 # Number of colours to cycle for dithered output
ditherDelay = 0.02 # Number of seconds between dithered output levels
delayInterval = 1.0 # Time to wait between pings, in seconds
# Global variables
global running
running = True
global level
level = -11.0
# Class for the LedBorg dithering thread
class LedBorgDitherer(threading.Thread):
# The code which will be run when the thread is started
def run(self):
global running
global level
# Run until the program is terminated
while running:
# Make a local copy of the level
localLevel = level
if level < -10.0:
# Not ready, set to off
colourLow = '000'
colourHigh = '000'
ditherLevel = 0.0
elif level < 0.0:
# Timeout or problem, use colourTimeout
colourLow = colourTimeout
colourHigh = colourTimeout
ditherLevel = 0.0
else:
# Get the nearest colour levels
localLevel *= len(colourGrade)
if localLevel < (len(colourGrade) - 1):
# Get the colours below and above the value
colourLow = colourGrade[int(localLevel)]
colourHigh = colourGrade[int(localLevel) + 1]
else:
# Too high, use the highest value as both settings
colourLow = colourGrade[len(colourGrade) - 1]
colourHigh = colourGrade[len(colourGrade) - 1]
# Set the dithering level between them
ditherLevel = localLevel - int(localLevel)
# Setup the dithering cycle
lowCount = 0
highCount = 0
# Run the dither cycle
for i in range(ditherCount):
if i == 0:
# First loop, use the low level
SetColour(colourLow)
lowCount += 1
else:
# Work out the current level so far
currentLevel = highCount / float(i)
if currentLevel < ditherLevel:
# We are too low, add some high level
SetColour(colourHigh)
highCount += 1
else:
# We are either too high or correct, add some low level
SetColour(colourLow)
lowCount +=1
# Wait for the dither interval
time.sleep(ditherDelay)
# Get user input
if len(sys.argv) > 2:
try:
targetPing = float(sys.argv[1])
pingAddress = sys.argv[2]
printUsage = False
except ValueError:
# Not a valid number
print '"%s" is not a number!' % (sys.argv[1])
printUsage = True
else:
printUsage = True
# Main code
if printUsage:
print 'Usage: %s target_ping_ms address_or_ip' % (sys.argv[0])
else:
# Start the LedBorg sequence handler loop
ledBorgDitherer = LedBorgDitherer()
ledBorgDitherer.start()
# Loop until the user presses CTRL+C
try:
while running:
# Perform the ping using the system ping command
rawPingFile = os.popen('ping -c 1 %s' % (pingAddress))
rawPingData = rawPingFile.readlines()
rawPingFile.close()
# Extract the ping time
if len(rawPingData) < 2:
# Failed to find a DNS resolution or route
failed = True
latency = 0
else:
index = rawPingData[1].find('time=')
if index == -1:
# Ping failed or timed-out
failed = True
latency = 0
else:
# We have a ping time, isolate it and convert to a number
failed = False
latency = rawPingData[1][index + 5:]
latency = latency[:latency.find(' ')]
latency = float(latency)
# Set the level to run
if failed:
level = -1.0
else:
level = latency / (targetPing * 2.0)
# Wait for the delay interval
time.sleep(delayInterval)
except KeyboardInterrupt:
# CTRL+C exit
running = False
# Wait for the LedBorg dithering loop to terminate
ledBorgDitherer.join()
SetColour('000')

