PingMonitor2 - Extended ping monitoring using LedBorg

This is an old driver based LedBorg script
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:

0%
to
22%
23%
to
44%
45%
to
67%
68%
to
89%
90%
to
110%
target :)
111%
to
132%
133%
to
155%
156%
to
177%
178%
or
more
Timeout
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 seconds
  • colourTimeout, line 18
    The colour to use if a ping times out or has an error
  • colourGrade, line 17
    The colour gradient to use, from 0% to 200% of targetPing
  • ditherCount, line 19
    The number of cycles used to represent a single level
  • ditherDelay, line 20
    The time to wait between dither cycles
Here's the code, you can download the PingMonitor2 script file as text here
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')
Subscribe to Comments for &quot;PingMonitor2 - Extended ping monitoring using LedBorg&quot;