{"id":92,"date":"2014-07-03T20:28:27","date_gmt":"2014-07-03T18:28:27","guid":{"rendered":"http:\/\/chriskrz.selfhost.bz\/wordpress\/?p=92"},"modified":"2020-03-22T15:10:19","modified_gmt":"2020-03-22T14:10:19","slug":"haengenden-router-automatisch-rebooten","status":"publish","type":"post","link":"https:\/\/www.rustimation.eu\/index.php\/haengenden-router-automatisch-rebooten\/","title":{"rendered":"H\u00e4ngenden Router automatisch rebooten"},"content":{"rendered":"<p>Manchmal hat man da, wo der Pi seinen Dienst als Webcam oder als Home Automation Server versieht, keinen Festnetzanschlu\u00df. Die L\u00f6sung ist ein Router, an den man einen UMTS Internetstick anschlie\u00dft oder ein fertiger UMTS (LTE ist nat\u00fcrlich noch besser) Router.<\/p>\n<p>Leider verh\u00e4lt es sich so, dass diese Konfiguration immer mal wieder menschlicher Interaktion bedarf:\u00a0 Unter Umst\u00e4nden ist das Mobilfunknetz so stark \u00fcberlastet, dass der Router, bzw. der Internet Stick daran sich einfach nicht verbinden will. Nach zu vielen Fehlversuchen streikt der Router dann \u2013 zumindest der von mir verwendete TP-Link Mobilfunk Router TL-MR3420. Dann hilft nur ein physikalischer Reset des Routers. Bl\u00f6d, wenn man dann nicht vor Ort ist, sondern hunderte Kilometer entfernt.<\/p>\n<p>Man k\u00f6nnte den Router ganz einfach mit einer Zeitschaltuhr irgendwann (nachts) aus- und wieder einschalten. Im schlimmsten Fall w\u00e4re der Pi dann 24 Stunden offline.<\/p>\n<p>Viel eleganter ist die L\u00f6sung mittels Fernschalt-Steckdosen und einem 433MHz Sender am Pi.<\/p>\n<p><!--more--><\/p>\n<p>Wie man 433MHz Schaltsteckdosen mit dem Pi ansteuert, ist <a title=\"433MHz Schalt-Steckdosen fernsteuern\" href=\"http:\/\/www.rustimation.eu\/index.php\/433mhz-schalt-steckdosen-fernsteuern\/\">hier<\/a> <a title=\"433MHz Schalt-Steckdosen fernsteuern\" href=\"http:\/\/www.rustimation.eu\/index.php\/433mhz-schalt-steckdosen-fernsteuern\/\">beschrieben<\/a>.<\/p>\n<p>Dann kommt der von mir \"entwickelte\" Python Code zum \u00dcberwachen und Steuern des Routers. Ich bin leider kein Python Experte, weshalb der Code f\u00fcr Experten wahrscheinlich etwas schlampig aussieht. F\u00fcr Anregungen w\u00e4re ich sehr dankbar!<\/p>\n<pre class=\"expand:true lang:python decode:true\" title=\"checkinet.py - Router Check and Reboot\">#!\/usr\/bin\/python\r\n#coding=UTF-8\r\n#-----------------\r\n# This program tries to establish a connection to a given Internet site.\r\n# In case, a connection cannot established after several retries,\r\n# a command is sent to a 433MHz switch, to turn off the router and start it after \r\n# a minute or so. This program should be called at regular intervals (ca. 15 minutes)\r\n# by use of a crontab statement\r\n#-----------------\r\n\r\nimport urllib2\r\nimport time\r\nfrom elropi import RemoteSwitch\r\nimport logging\r\n\r\n\r\ndef internet_on():\r\n    try:\r\n        response=urllib2.urlopen('http:\/\/www.google.it',timeout=urltimeout)\r\n        return True\r\n    except urllib2.URLError as err: pass\r\n    return False\r\n\r\n\r\n# setting constants\r\n# change device number according to your requirements\r\ndeviceno=1\r\n# Change the key[] variable below according to the dipswitches on your Elro receivers.\r\ndefault_key = [1,1,0,1,1]\r\n# change the GPIO pin according to your wiring\r\ndefault_pin =7\r\n# set parameters for class elropi.py\r\ndevice = RemoteSwitch(device=deviceno,key=default_key,pin=default_pin)\r\n# set timeout for URL check [s]\r\nurltimeout=15\r\n# set wait inbetween retries [s]\r\nretrywait=15\r\n# set wait after shutdown [s]\r\nshutdownwait=60\r\n# set number of retries\r\nretries=3\r\n\r\n# Logging\r\nlogging.basicConfig(filename='\/var\/log\/checkinet.log',level=logging.WARNING,format='%(asctime)s %(message)s')\r\n\r\n# Check whether Internet is available\r\ninetstatus=internet_on()\r\nattempt=0\r\nwhile not inetstatus:\r\n      attempt=attempt + 1\r\n      errmsg=\"Attempt number \" + str(attempt) + \": connect failed, retrying\"\r\n      logging.warning(errmsg)\r\n\r\n      if attempt &gt;= retries:\r\n         device.switchOff()\r\n         logging.warning(\"router seems offline, going through power cycle\")\r\n         time.sleep(shutdownwait)\r\n         device.switchOn()\r\n         logging.warning(\"router is booting\")\r\n         break\r\n      #wait for some seconds before next try and return to top of while loop\r\n      time.sleep(retrywait)\r\n      inetstatus=internet_on()\r\n\r\nif inetstatus:\r\n       logging.debug(\"router online\")\r\n\r\n#End of Connectivity check\r\n<\/pre>\n<p>Den oben abgebildeten Code in den Editor pasten und als <code>checkinet.py<\/code> im Verzeichnis <code>\/home\/pi\/433mhz<\/code> abspeichern.<\/p>\n<h5>Was passiert da?<\/h5>\n<p>Zuerst einmal werden die ben\u00f6tigten Libraries inklusive der Klasse \"RemoteSwitch\" aus dem in <a title=\"433MHz Schalt-Steckdosen fernsteuern\" href=\"http:\/\/www.rustimation.eu\/index.php\/433mhz-schalt-steckdosen-fernsteuern\/\">diesem Beitrag<\/a> besorgten Programm <code>elropi.py<\/code> geladen.<\/p>\n<p>Die Funktion<code> internet_on<\/code> funkt eine frei w\u00e4hlbare Internet Adresse an. Sinnvollerweise eine, welche eine schnelle Response zeigt. Den Timeoutwert in Sekunden kann man frei w\u00e4hlen. Ist er zu kurz, wird der Router bei schlechten Empfangsbedingungen entsprechend \u00f6fter zur\u00fcckgesetzt.<\/p>\n<p>Dann werden alle Konstanten gesetzt, inklusive der Konstanten f\u00fcr <code>RemoteSwitch<\/code>. Die im <a title=\"433MHz Schalt-Steckdosen fernsteuern\" href=\"http:\/\/www.rustimation.eu\/index.php\/433mhz-schalt-steckdosen-fernsteuern\/\">433MHz Beitrag<\/a> vorgenommene Einstellung des GPIO Pins und der Systemadresse der Funkschaltdose in <code>elropi.py<\/code> keinen Einfluss auf die Einstellungen, die du hier in <code>checkinet.py<\/code> vornimmst. Deshalb m\u00fcssen diese Parameter hier noch einmal eingegeben werden.<\/p>\n<p>Zus\u00e4tzlich wird noch die Python Logging Komponente angesprochen, die es dir erlaubt, die Funktionsweise und ggf. stattgefundene Resets zu \u00fcberpr\u00fcfen. <code>Print <\/code>Statements kannst du nat\u00fcrlich auch einbauen, aber die sind nur sichtbar, wenn man das Programm direkt aufruft. Wir werden das Programm ja automatisch und im Hintergrund laufen lassen. Wer mag, kann anstatt <code>level=logging.WARNING<\/code> auch <code>level=logging.DEBUG<\/code><br \/>\nschreiben; dann wird jedesmal, wenn das Programm l\u00e4uft eine Zeile \"router online\" ins Protokoll geschrieben.<\/p>\n<p>Die angegebene Internet Adresse wird angefunkt. Ist alles okay, wird das Programm beendet. Falls nicht, wird die\u00a0 <code>While <\/code>Schleife x-mal bis zu einem einstellbaren Maximalwert durchlaufen, zwischen den Versuchen wird immer ein bisschen gewartet. Nach dem x-ten Fehlversuch wird der Schaltdose ein Abschalt-Kommando geschickt. Nach einer einstellbaren Wartezeit wird die Dose wieder eingeschaltet und der Router bootet &#8211; nat\u00fcrlich nur, wenn er auch tats\u00e4chlich an der Schaltdose h\u00e4ngt \ud83d\ude42 . Wenn alles klappt, hat sich der Router nach ein paar Minuten mit dem Internet verbunden. Falls nicht, geht beim n\u00e4chsten Start das Spiel wieder von vorne los.<\/p>\n<h3>Regelm\u00e4\u00dfiger Check? In die Crontab damit!<\/h3>\n<p>So, das wars fast schon. Damit die Internetverbindung regelm\u00e4\u00dfig getestet wird gehen wir wie folgt vor:<\/p>\n<pre class=\"lang:python decode:true \">sudo crontab -e<\/pre>\n<p>Die Crontab wird geladen. Ans untere Ende sollten wir folgenden Befehl schreiben:<\/p>\n<pre class=\"lang:default decode:1 inline:1 \" >2,12,22,32,42,52 * * * * python \/home\/pi\/433mhz\/checkinet.py <\/pre>\n<p>Das bewirkt, dass das Programm alle 10 Minuten zur 2., 12., 22., 32., 42 und 52. Minute ausgef\u00fchrt wird. Das mache ich deshalb, weil meine Webcam zu jeder vollen und halben Stunde ein Foto macht und dann etwas Zeit braucht, die Bilder in meinen Webspace hochzuladen. W\u00e4hrend dieser Zeit ist der Kanal dicht und es k\u00f6nnte zu einem ungewollten Timeout und Reset kommen &#8211; meine Bandbreite ist manchmal echt j\u00e4mmerlich.<br \/>\nEs ginge nat\u00fcrlich auch<\/p>\n<pre class=\"lang:python decode:1 inline:1 \" >*\/10 * * * * python \/home\/pi\/433mhz\/checkinet.py<\/pre>\n<p>dann w\u00fcrde der Check alle 10 Minuten zur vollen zehnten Minute stattfinden.<br \/>\nWie oft ihr das Programm laufen lasst, bleibt euch \u00fcberlassen. Allerdings sollte zwischen den Aufrufen gen\u00fcgend Zeit bleiben, dass sich der Router bzw. Internet Stick wieder mit dem Internet verbindet. Sonst gibt's eine Endlosschleife.<br \/>\nStellt man die Crontab mit <code>sudo crontab<\/code> ein, wird sie immer als Superuser ausgef\u00fchrt, ihr braucht deshalb den Prefix <code>sudo<\/code> nicht. <code>python<\/code> br\u00e4uchte man eigentlich auch nicht, wenn man das in <a title=\"Shebang! Oder wie man Python wegl\u00e4sst\" href=\"http:\/\/www.rustimation.eu\/index.php\/shebang-oder-wie-man-python-weglaesst\/\">diesem Beitrag<\/a> Beschriebene beachtet. Der Einfachheit halber und wohl eher aus Gewohnheit lasse ich das trotzdem meist drin, da ich anf\u00e4nglich Schwierigkeiten mit dem impliziten Aufruf des Pythoninterpreters hatte.<\/p>\n<h3>Zus\u00e4tzliche Absicherung und Mail Benachrichtigung<\/h3>\n<p>Warum auch immer, manchmal will sich das Edimax USB Dongle (ansonsten wirklich hervorragend) nicht mehr mit dem frisch gestarteten Router verbinden. Das f\u00fchrt dann auch zu einer Endlosschleife, da checkinet.py nix checkt bzw. keine Verbindung zum Router zustande kommt.\u00a0 Was tun? Ganz einfach: den Raspberry Pi nach erfolgten Reset und ein paar Gedenkminuten durchstarten.<\/p>\n<p>Dazu braucht es noch die <code>os<\/code> Library und den Befehl <code>os.system(\"sudo reboot\")<\/code> an geeigneter Stelle.<\/p>\n<p>Hier mein ganzes Programm, was als zus\u00e4tzliches Komfortfeature noch ein Email an mich schickt, wenn der Router resetted wurde. Die Mailfunktion habe ich von Trevor Appleton's <a title=\"send email from\" href=\"http:\/\/trevorappleton.blogspot.co.uk\/2014\/11\/sending-email-using-python.html\" target=\"_blank\" rel=\"noopener noreferrer\">Website<\/a>.<\/p>\n<pre class=\"expand:true lang:python decode:true \">#!\/usr\/bin\/python\r\n#coding=UTF-8\r\n#-----------------\r\n# German documentation can be found at www.rustimation.eu\r\n# This program tries to establish a connection to a given Internet site.\r\n# In case, a connection cannot be established after several retries,\r\n# a command is sent to a 433MHz switch to turn off the router and start it after\r\n# a minute or so. This program should be called at regular intervals (ca. 15 minutes)\r\n# by use of a crontab statement.\r\n# For additional security, the Pi reboots after resetting the router (it has happened\r\n# that the WiFi connection between the Pi an the router crashed, resulting in an endless\r\n# loop of resetting and restarting the router without any effect).\r\n# A previous reset is detected and an email is sent.\r\n# Due to GPIO functionality this program must be run as root (sudo)\r\n#-----------------\r\n\r\nimport urllib2\r\nimport time\r\nfrom elropi import RemoteSwitch\r\nimport logging\r\nimport os\r\nimport smtplib\r\n\r\ndef internet_on():\r\n    try:\r\n        response=urllib2.urlopen('http:\/\/www.google.it',timeout=urltimeout)\r\n        return True\r\n    except urllib2.URLError as err: pass\r\n    return False\r\n\r\n\t\t\r\n# Logging - logfile must be present\r\nlogging.basicConfig(filename='\/var\/log\/checkinet.log',level=logging.WARNING,format='%(asctime)s %(message)s')\r\n\r\n#### setting constants\r\nworkdir=\"\/home\/pi\/433mhz\/\"\r\n# change device number according to your requirements\r\ndeviceno=1\r\n# Change the key[] variable below according to the dipswitches on your Elro receivers.\r\ndefault_key = [1,0,1,0,1]\r\n# change the GPIO pin according to your wiring\r\ndefault_pin =7\r\n# set parameters for class elropi.py\r\ndevice = RemoteSwitch(device=deviceno,key=default_key,pin=default_pin)\r\n# set timeout for URL check [s]\r\nurltimeout=15\r\n# set wait inbetween retries [s]\r\nretrywait=30\r\n# set wait after shutdown [s]\r\nshutdownwait=5\r\n# set number of retries\r\nretries=5\r\n# get local time as string\r\nlt = time.localtime()\r\njahr, monat, tag, stunde, minute, sekunde = lt[0:6]\r\nacttime=\"%04i%02i%02i%02i%02i%02i\" % (jahr, monat, tag, stunde, minute, sekunde)\r\n# mail params - \r\n# see also:http:\/\/trevorappleton.blogspot.co.uk\/2014\/11\/sending-email-using-python.html\r\nSMTP_SERVER = 'smtp.gmail.com'\r\nSMTP_PORT = 587\r\nGMAIL_USERNAME = 'yourGmailAddress@gmail.com' #for these purposes, I suggest a special account instead of your regular one.\r\nGMAIL_PASSWORD = 'PaSsWoRD' #CAUTION: This is stored in plain text!\r\nrecipient = 'ReceiversAddress@anywhere.com'\r\nsubject = 'Router Reboot'\r\n\r\nheaders = [\"From: \" + GMAIL_USERNAME,\r\n           \"Subject: \" + subject,\r\n           \"To: \" + recipient,\r\n           \"MIME-Version: 1.0\",\r\n           \"Content-Type: text\/html\"]\r\nheaders = \"rn\".join(headers)\r\n\r\n# check for previous reset - if yes, send mail\r\ninetstatus=internet_on() # necessary since sending mail will only work, if inernet is available\r\nif inetstatus:\r\n\ttry:\r\n\t\tcheckfile=open(workdir+\"reset.txt\", \"r\") # if file (=reset) exists then go on\r\n\t\tresettime=checkfile.read()\r\n\t\tcheckfile.close\r\n\t\tos.remove(workdir+\"reset.txt\")\r\n\t\tlogging.warning(\"previous reset detected\")\r\n\t\temailText = 'A router reset occurred at ' + resettime\r\n\t\temailText = \"\" + emailText + \"\"\r\n\t\tsession = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)\r\n\t\tsession.ehlo()\r\n\t\tsession.starttls()\r\n\t\tsession.ehlo\r\n\t\tsession.login(GMAIL_USERNAME, GMAIL_PASSWORD)\r\n\t\tsession.sendmail(GMAIL_USERNAME, recipient, headers + \"rnrn\" + emailText)\r\n\t\tsession.quit()\r\n\texcept IOError:\r\n\t\tlogging.debug(\"no previous reset\")\r\n\t\r\n# Check whether Internet is available\r\n\r\nattempt=0\r\nwhile not inetstatus:\r\n      attempt=attempt + 1\r\n      errmsg=\"Attempt number \" + str(attempt) + \": connect failed, retrying\"\r\n      logging.warning(errmsg)\r\n\r\n      if attempt &gt;= retries:\r\n\t\t device.switchOff()\r\n\t\t logging.warning(\"router seems offline, rebooting router\")\r\n\t\t time.sleep(shutdownwait)\r\n\t\t device.switchOn()\r\n\t\t logging.warning(\"router is booting\")\r\n\t\t checkfile=open(workdir+\"reset.txt\",\"w\")\r\n\t\t checkfile.write(acttime)\r\n\t\t checkfile.close()\r\n\t\t time.sleep(60) # long enough for router to bring up WiFi\r\n\t\t os.system(\"sudo reboot\") # reboot to add security\r\n\t\t break\r\n      #wait for some seconds before next try and return to top of while loop\r\n      time.sleep(retrywait)\r\n      inetstatus=internet_on()\r\n\r\nif inetstatus:\r\n       logging.debug(\"router online\")\r\n\r\n#End of Connectivity check\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Manchmal hat man da, wo der Pi seinen Dienst als Webcam oder als Home Automation Server versieht, keinen Festnetzanschlu\u00df. Die L\u00f6sung ist ein Router, an den man einen UMTS Internetstick anschlie\u00dft oder ein fertiger UMTS (LTE ist nat\u00fcrlich noch besser) Router. Leider verh\u00e4lt es sich so, dass diese Konfiguration immer mal wieder menschlicher Interaktion bedarf:\u00a0 &hellip; <a href=\"https:\/\/www.rustimation.eu\/index.php\/haengenden-router-automatisch-rebooten\/\" class=\"more-link\"><span class=\"screen-reader-text\">H\u00e4ngenden Router automatisch rebooten<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,7,9,10],"tags":[13,21,29,41,48],"class_list":["post-92","post","type-post","status-publish","format-standard","hentry","category-fernsteuern","category-netzwerk","category-python","category-raspberry-pi","tag-433mhz","tag-failsafe","tag-mobilfunk","tag-router","tag-umts"],"_links":{"self":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts\/92","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/comments?post=92"}],"version-history":[{"count":1,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts\/92\/revisions"}],"predecessor-version":[{"id":1253,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts\/92\/revisions\/1253"}],"wp:attachment":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/media?parent=92"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/categories?post=92"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/tags?post=92"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}