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% oftargetPing
ditherCount
, 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.py
and 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')