Don't like ads? PRO users don't see any ads ;-)
Guest

Conky UPnP Router Monitor

By: a guest on Jun 1st, 2012  |  syntax: Python  |  size: 13.00 KB  |  hits: 42  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. #http://www.ip-phone-forum.de/showthread.php?t=246673
  5.  
  6. import sys
  7. import os
  8. import socket
  9.  
  10. ######################################################
  11. #        Konfiguration und Optionen
  12. ######################################################
  13.  
  14. # IP des Routers
  15. routerIP = 'fritz.box'
  16. port = 49000
  17.  
  18. #### Asgabe-Methode 1, 2 oder 3 waehlen
  19. style = 3
  20.  
  21. ## Methode 1: komplette Ausgabe der Werte mit Balken in Textform - schnell, simpel und retro :)
  22. """Die folgende Zeile gehoert in die Conky-Konfigurationsdatei
  23. ${exec ~/.conky/upnp_traffic.py}
  24. """
  25. ## Methode 2: direkte Auswertung des Python-Skripts in Conky - relativ langsam, Skript muss jeweils fuer jede Variable durchlaufen
  26. """Die folgenden vier Zeilen gehoeren in die Conky-Konfigurationsdatei
  27. Down: ${exec ~/.conky/upnp_traffic.py | sed -n 1p}
  28. ${execbar ~/.conky/upnp_traffic.py | sed -n 3p}
  29. Up: ${exec ~/.conky/upnp_traffic.py | sed -n 2p}
  30. ${execbar ~/.conky/upnp_traffic.py | sed -n 4p}
  31. """
  32. ## Methode 3: schnelle, stabile Auswertung - Umweg ueber eine "Vermittlungs-Datei", Python-Skript schreibt die Werte in eine Textdatei, Conky liest die Werte aus
  33. """Die folgenden fuenf Zeilen gehoeren in die Conky-Konfigurationsdatei
  34. ${exec ~/.conky/upnp_traffic.py}
  35. Down: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 1p}
  36. ${execbar cat ~/.conky/upnp_traffic_tmp | sed -n 3p}
  37. Up: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 2p}
  38. ${execbar cat ~/.conky/upnp_traffic_tmp | sed -n 4p}
  39. """
  40.  
  41. #### IP-Adresse ausgeben (True oder False)
  42. showIP = True
  43. """Die Zeile gehoert in die Conky-Konfigurationsdatei
  44. ## bei Methode 1:
  45. WAN IP: ${exec ~/.conky/upnp_traffic.py | sed -n 5p}
  46. ## bei Methode 2:
  47. WAN IP: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 5p}
  48. """
  49.  
  50. #### Uptime ausgeben (True oder False) Zeigt die abgelaufene Zeit, seit der der Router online ist
  51. show_uptime = True
  52. """Die Zeile gehoert in die Conky-Konfigurationsdatei
  53. ## bei Methode 1:
  54. Uptime: ${exec ~/.conky/upnp_traffic.py | sed -n 6p}
  55. ## bei Methode 2:
  56. Uptime: ${exec cat ~/.conky/upnp_traffic_tmp | sed -n 6p}
  57. """
  58.  
  59. #### *optional:  Progress-Balken-Optionen - Dies sind die Balken aus Methode Nr. 1
  60. # mehr Infos unter http://code.activestate.com/recipes/577871/
  61. custom_options = {
  62.     'end': 100,         # Max. Prozentwert
  63.     'width': 37,        # Breite
  64.     'fill': '-',        # Fuellungs-Zeichen
  65.     'blank': '.',       # Leer-Stellen-Zeichen
  66.     'format': '[%(fill)s|%(blank)s]' # Augabemuster
  67.     }
  68.  
  69. #### *optional: Pfad zum home-Verzeichnis des Benutzers. Nur fuer die Asgabe-Methode Nr. 3
  70. homefolder = os.path.expanduser('~') # Standart ist os.path.expanduser('~')
  71. conky_path = '.conky' # Conky Verzeichnis im Benutzerordner
  72. temp_file_name = 'upnp_traffic_tmp' # Name der "Vermittlungs-Textdatei"
  73.  
  74.  
  75. #### Textbausteine fuer moegliche Uebersetzung
  76. text_download = "Down:\t"
  77. text_upload = "Up:\t"
  78. text_WAN_IP = "WAN IP:"
  79. text_uptime = "Uptime:"
  80. text_kibs = "KiBs"
  81. text_mibs = "MiBs"
  82. text_day = "Tag"
  83. text_days = "Tage"
  84. text_max_dl = "Max"
  85. text_max_ul = "Max"
  86. text_debug1 = "OK"
  87. text_debug2 = "Error: Your Computer is connected with the router.\nBut can't connect to the web.\nMaybe some problems with your bad ISP or with hardware/cable?"
  88. text_debug3 = "Error: Oh noo! No connection to the router... Check the IP settings!"
  89. ######################################################
  90. #        Ende der Konfiguration und Optionen
  91. ######################################################
  92.  
  93.  
  94.  
  95. # Werte automatisch in Kibibyte/Sek oder Mebibyte/Sek mit Suffix
  96. def kbmb(x):
  97.     x = int(x)
  98.     if x < 900*1024: # ab 900 Kibibyte wird in Mebibyte angezeigt
  99.       value = x/1024 # Umrechnung Bytes in Kibibyte
  100.       value_suffix = text_kibs
  101.     else:
  102.       value = (float(x))/1048576 # Umrechnung Bytes in Mebibyte
  103.       value_suffix = text_mibs
  104.       value=round(value, 2) # Runden auf zwei Nachkomma-Stellen
  105.     return value, value_suffix
  106.     #kbmb()[0] entspricht dem Augabewert
  107.     #kbmb()[1] ist der Suffix KiBs / MiBs
  108.  
  109. # Sekunden in Tage, Stunden, Minuten, Sekunden umrechnen und formatiert zurueck geben
  110. def dhms(seconds):
  111.     if seconds is None: return (0,0,0,0)
  112.  
  113.     minutes = seconds / 60
  114.     seconds %= 60
  115.     hours = minutes / 60
  116.     minutes %= 60
  117.     days = hours / 24
  118.     hours %= 24
  119.  
  120.     if days == 1:
  121.         return str(days) +' '+ text_day +' '+ "%02d:%02d:%02d" % (hours, minutes, seconds)  
  122.     elif days > 1:
  123.         return str(days) +' '+ text_days +' '+ "%02d:%02d:%02d" % (hours, minutes, seconds)
  124.     elif days == 0:
  125.         return "%02d:%02d:%02d" % (hours, minutes, seconds)
  126.     elif days == 0 and hours == 0:
  127.         return "%02d:%02d" % (minutes, seconds)
  128.     elif days == 0 and hours == 0 and minutes == 0:
  129.         return "%02d" % (seconds)
  130.  
  131.  
  132. # ###########################################################
  133. # Informationen des Routers auslesen.
  134. class upnp():
  135.   def __init__(self, host=routerIP, port=port):
  136.  
  137.     self.host=host
  138.     self.port=port
  139.  
  140.   # Sendet eine Anfrage an den Router und liefert den Antwortstring zurueck
  141.   def send_req_resp(self,controlURL,serviceType, action):
  142.     body='<?xml version="1.0"?>\n' \
  143.          '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"\n' \
  144.          ' s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">\n' \
  145.          '  <s:Body>\n' \
  146.          '    <u:'+action+' xmlns:u="urn:schemas-upnp-org:service:'+serviceType+'"/>\n' \
  147.          '  </s:Body>\n' \
  148.          '</s:Envelope>\n'
  149.     pream='POST /upnp/control/'+controlURL+' HTTP/1.0\r\n' \
  150.           'HOST: '+self.host+':'+str(self.port)+'\r\n' \
  151.           'CONTENT-LENGTH: '+str(len(body))+'\r\n' \
  152.           'CONTENT-TYPE: text/xml; charset="utf-8"\r\n' \
  153.           'SOAPACTION: "urn:schemas-upnp-org:service:'+serviceType+'#'+action+'"\r\n\r\n'
  154.     sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  155.     sock.connect((self.host, self.port))
  156.     sock.send(pream + body)
  157.  
  158.     resp = ""
  159.     while True:
  160.       data=sock.recv(1024)
  161.       if len(data)==0:
  162.         break
  163.       resp+=data
  164.     sock.close()
  165.     return(resp)
  166.  
  167.   # liefert aus "xml_str" den Teilstring, der zwischen <"arg"> und </"arg"> steht.
  168.   def get_argument(self, xml_str, arg):
  169.     v="<"+arg+">"
  170.     p1=xml_str.find(v)
  171.     if p1>=0:
  172.       p2=xml_str.find("</"+arg+">", p1)
  173.       if p2>=0:
  174.         return(xml_str[p1+len(v):p2])
  175.     return(None)
  176.  
  177.   # Liefert die Maximal-Werte der Verbindung.
  178.   def MaxBandwidth(self, div=1):
  179.     s=self.send_req_resp("WANCommonIFC1","WANCommonInterfaceConfig:1","GetCommonLinkProperties")
  180.     # /9 fuer "Bit/Sek" zu "Byte/Sek"
  181.     maxSnd=int(self.get_argument(s, "NewLayer1UpstreamMaxBitRate"))/9
  182.     maxRec=int(self.get_argument(s, "NewLayer1DownstreamMaxBitRate"))/9
  183.     return((maxRec/div, maxSnd/div))
  184.  
  185.   # Liefert die aktuellen Uebertragungsraten.
  186.   def Traffic(self, div=1):
  187.     s=self.send_req_resp("WANCommonIFC1","WANCommonInterfaceConfig:1","GetAddonInfos")
  188.     snd=int(self.get_argument(s, "NewByteSendRate"))
  189.     rec=int(self.get_argument(s, "NewByteReceiveRate"))
  190.     return((rec/div, snd/div))
  191.  
  192.   # Liefert die externe IP.
  193.   def ExternalIP(self, div=1):
  194.     s=self.send_req_resp("WANCommonIFC1","WANIPConnection:1","GetExternalIPAddress")
  195.     ip=str(self.get_argument(s, "NewExternalIPAddress"))
  196.     return ip
  197.  
  198.   # Liefert die "Uptime".
  199.   def Uptime(self, div=1):
  200.     s=self.send_req_resp("WANCommonIFC1","WANIPConnection:1","GetStatusInfo")
  201.     uptime=int(self.get_argument(s, "NewUptime"))
  202.     try:
  203.         uptime = int(uptime)
  204.     except (ValueError,TypeError):
  205.         uptime = None
  206.     if uptime is None: uptime = 0
  207.     return dhms(uptime)
  208.  
  209.   # Liefert den Verbindungs-Status.
  210.   def Status(self):
  211.     s=self.send_req_resp("WANDSLLinkC1","WANDSLLinkConfig:1","GetDSLLinkInfo")
  212.     status=str(self.get_argument(s, "NewLinkStatus"))
  213.     return status
  214.  
  215.  
  216. # Verbindungs-Status pruefen
  217. def checkConnection():
  218.     get=upnp()
  219.     try:    
  220.         if get.Status() == 'Up' or 'Down' or 'Initializing':
  221.             status = 1
  222.             debug = text_debug1 # 'OK'
  223.         elif get.Status() == 'Unavailable':
  224.             status = 2
  225.             debug = text_debug2 # 'maybe some router/hardware problems?'
  226.         elif get.Status() !=  'Up' or 'Down' or 'Initializing' or 'Unavailable':
  227.             status = 3
  228.             debug = text_debug3 # 'check IP settings!'
  229.         return status, debug
  230.     except socket.error, msg:
  231.             status = 4
  232.             debug = 'Socket error:' + str(msg)
  233.             return status, debug  
  234.  
  235.    
  236. ## {{{ http://code.activestate.com/recipes/577871/ (r1)
  237. class ProgressBar(object):
  238.     """ProgressBar class holds the options of the progress bar.
  239.    The options are:
  240.        start   State from which start the progress. For example, if start is
  241.                5 and the end is 10, the progress of this state is 50%
  242.        end     State in which the progress has terminated.
  243.        width   --
  244.        fill    String to use for "filled" used to represent the progress
  245.        blank   String to use for "filled" used to represent remaining space.
  246.        format  Format
  247.        incremental
  248.    """
  249.     def __init__(self, start=0, end=10, width=12, fill='=', blank='.', format='[%(fill)s>%(blank)s] %(progress)s%%', incremental=True):
  250.         super(ProgressBar, self).__init__()
  251.  
  252.         self.start = start
  253.         self.end = end
  254.         self.width = width
  255.         self.fill = fill
  256.         self.blank = blank
  257.         self.format = format
  258.         self.incremental = incremental
  259.         self.step = 100 / float(width) #fix
  260.         self.reset()
  261.  
  262.     def __add__(self, increment):
  263.         increment = self._get_progress(increment)
  264.         if 100 > self.progress + increment:
  265.             self.progress += increment
  266.         else:
  267.             self.progress = 100
  268.         return self
  269.  
  270.     def __str__(self):
  271.         progressed = int(self.progress / self.step) #fix
  272.         fill = progressed * self.fill
  273.         blank = (self.width - progressed) * self.blank
  274.         return self.format % {'fill': fill, 'blank': blank, 'progress': int(self.progress)}
  275.  
  276.     __repr__ = __str__
  277.  
  278.     def _get_progress(self, increment):
  279.         return float(increment * 100) / self.end
  280.  
  281.     def reset(self):
  282.         """Resets the current progress to the start point"""
  283.         self.progress = self._get_progress(self.start)
  284.         return self
  285.  
  286.  
  287. # Asgabe-Methode 1
  288. def retroOutput():
  289.     get=upnp()
  290.     traffic = get.Traffic()  # traffic[0] ist Download,  traffic[1] ist Upload
  291.    
  292.     # Prozentwert des Traffics
  293.     dwn_percent=int((float(traffic[0])/get.MaxBandwidth()[0])*100)
  294.     up_percent=int((float(traffic[1])/get.MaxBandwidth()[1])*100)
  295.  
  296.     if (dwn_percent or up_percent) > 100: # pruefen ob Wert ueber 100%
  297.         return retroOutput()        
  298.     else:
  299.         dwn_bar = ProgressBar(**custom_options) + dwn_percent # Download-Progress-Balken
  300.         up_bar = ProgressBar(**custom_options) + up_percent # Upload-Progress-Balken
  301.  
  302.         print text_download, kbmb(traffic[0])[0], kbmb(traffic[0])[1]    # Augabewert KiBs/MiBs mit Suffix
  303.         print dwn_bar, int(dwn_percent),"\b%" # Download-Progress-Balken und Prozentwert
  304.         print text_upload, kbmb(traffic[1])[0], kbmb(traffic[1])[1] # Augabewert KiBs/MiBs mit Suffix
  305.         print up_bar, int(up_percent),"\b%" # Upload-Progress-Balken und Prozentwert
  306.         if showIP == True: print text_WAN_IP, get.ExternalIP()
  307.         if show_uptime == True: print text_uptime, get.Uptime()
  308.  
  309.  
  310. # Asgabe-Methode 2
  311. def compactOutput():
  312.     get=upnp()
  313.     traffic = get.Traffic()  # traffic[0] ist Download,  traffic[1] ist Upload
  314.    
  315.     # Prozentwert des Traffics
  316.     dwn_percent=int((float(traffic[0])/get.MaxBandwidth()[0])*100)
  317.     up_percent=int((float(traffic[1])/get.MaxBandwidth()[1])*100)
  318.  
  319.     if (dwn_percent or up_percent) > 100: # pruefen ob Wert ueber 100%
  320.         return compactOutput()        
  321.     else:
  322.         print kbmb(traffic[0])[0], kbmb(traffic[0])[1] # Download-Traffic
  323.         print kbmb(traffic[1])[0], kbmb(traffic[1])[1] # Upload-Traffic
  324.         print dwn_percent # Download-Prozent
  325.         print up_percent # Upload-Prozent
  326.         if showIP == True: print get.ExternalIP()
  327.         if show_uptime == True: print text_uptime, get.Uptime()
  328.  
  329.  
  330. # Asgabe-Methode 3
  331. def fileOutput():
  332.     tr_temp_file_path = homefolder + '/' + conky_path + '/' + temp_file_name # Pfad zur der Textdatei wird gebildet
  333.    
  334.     get=upnp()
  335.     traffic = get.Traffic()  # traffic[0] ist Download,  traffic[1] ist Upload
  336.    
  337.     # Prozentwert des Traffics
  338.     dwn_percent=int((float(traffic[0])/get.MaxBandwidth()[0])*100)
  339.     up_percent=int((float(traffic[1])/get.MaxBandwidth()[1])*100)
  340.  
  341.     if (dwn_percent or up_percent) > 100: # pruefen ob Wert ueber 100%
  342.         return fileOutput()        
  343.     else:
  344.         fobj = open(tr_temp_file_path, "w")
  345.         print >> fobj, kbmb(traffic[0])[0], kbmb(traffic[0])[1]
  346.         print >> fobj, kbmb(traffic[1])[0], kbmb(traffic[1])[1]
  347.         print >> fobj, dwn_percent
  348.         print >> fobj, up_percent
  349.         if showIP == True: print >> fobj,  get.ExternalIP()
  350.         if show_uptime == True: print  >> fobj, get.Uptime()
  351.         fobj.close()
  352.  
  353.  
  354. # Ausgabewahl
  355. def Output(method):
  356.     if method == 1: retroOutput()
  357.     elif method == 2: compactOutput()
  358.     elif method == 3: fileOutput()
  359.  
  360.  
  361. # Ausgabe-Start
  362. if checkConnection()[0] == 1: Output(style)
  363. else: print checkConnection()[1]