Posts mit dem Label Bash werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Bash werden angezeigt. Alle Posts anzeigen

Mittwoch, 26. Juli 2023

Rund um Linux - Shellbefehle dank "explainshell.com" verstehen

Wie kann man verstehen, was genau ein Shellbefehl macht ohne die jeweiligen Manpages zu lesen? Die Webseite explainshell.com kann hier helfen! Nützliche Befehle bzw. Beispiele findet man in meinem Beitrag Rund um Linux - Einige nützliche Befehle für die Shell II (Download mit wget und seq).

Die Webseite explainshell.com durchsucht Informationen von über 30.000 Manpages.

Dennoch kann es vorkommen, dass Parameter nicht ermittelt werden können. Hier hilft dann nur eine manuelle Recherche in den jeweiligen Manpages.

Donnerstag, 18. Mai 2023

Linux - Terminal ist eingefroren (Strg-S)

Kurzer aber nützlicher Tipp, falls auch euch das Terminal einfriert.

Führt man stty -ixon aus, wird verhindert, dass "Strg-S" das Terminal anhält bzw. pausiert. Diesen Befehl am Besten in der Konfigurationsdatei des Terminals (~/.bashrc) eintragen.

# enable the freeze/unfreeze behavior CTRL-S and CTRL-C
stty -ixon

Hintergrund: ixon und ixoff werden verwendet, um darauf zu bestehen, dass "Strg-S" und "Strg-Q" als Kontrollflusssignale (Bildlaufsperre) interpretiert werden. 

Weitere Infos zu stty finden sich hier https://tldp.org/HOWTO/Serial-HOWTO-11.html#ss11.4.


Montag, 20. Dezember 2021

Linux - Dateien hochladen (file upload) mit curl

In dem Artikel "Linux - Mit curl Dateien herunterladen und Webseiten aufrufen" habe ich bereits sehr viele Möglochkeiten von curl aufgezeigt. In diesem Beitag werde ich die Möglichkeit von einem Datei Upload beschreiben.


Upload
curl -u <user>:<passwort> -T <datei> https://server.de


Upload mit Fortschrittsanzeige
curl -u <user>:<passwort> -T <datei> https://server.de > /dev/null


Sonntag, 27. Juni 2021

Linux - Mit curl Dateien herunterladen und Webseiten aufrufen

Durch curl ist es möglich von Webseiten (mittels Login und Cookies) auf Informationen per Kommandozeile zuzugreifen oder auch Dateien herunterzuladen. In dem Beitrag Linux - Statische Kopie einer Webseite anlegen mit wget bin ich bereits auf die Möglichkeiten von wget eingegangen.

Curl unterstützt neben HTTP eine Vielzahl von weiteren Netzwerkprotokollen wie FTP, FTPS, HTTPS, GOPHER, TELNET, DICT, FILE und LDAP.

In der Regel ist curl vorinstalliert, ansonsten geht dies über den folgenden Befehl:
sudo apt-get install curl 

Folgende Optionen lassen sich Beispielhaft mit curl ausführen

Den Inhalt der heruntergeladenen Datei in den angegebenen DATEINAME schreiben, anstatt in die Standardausgabe:
curl -o DATEINAME "URL"

Wiederaufnahme eines vorangegangenen Downloads (--continue-at OFFSET)
curl -C - "URL"

Den Anforderungs- und Antwortheader anzeigen
curl -v "URL"

HTTP-Header mit eigenen Daten einfügen (z.B. Content-Type oder Accept-Language), hierbei darf -H auch mehrfach verwendet werden.
curl -H 'Content-Type: application/json' "URL"
curl -H 'Accept-Language: de' "URL"


Zum Beispiel lässt sich so das Wetter in ASCII-Grafik auf der Konsole in unterschiedlichen Sprachen anzeigen:
curl -H 'Accept-Language: de' "https://wttr.in/Obergeis"
curl -H 'Accept-Language: en' "https://wttr.in/Obergeis" 

Verbindung SSL oder TLS herstellen
curl --sslv3 "URL"
curl --tlsv1.1 "URL"

Skripte mit python oder bash ausführen
-s, Silent or quiet mode. Don't show progress meter or error messages.
-f, (HTTP)  Fail  silently  (no  output at all) on server errors.
Kleiner Tipp, mit Hilfe von "https://explainshell.com/explain?cmd=curl+-sSL" kann man schnell heausfinden, was der Befhel bedeutet. 

curl -sf "URL" | sudo python3
Achtung: Da hier direkt die Installation eines Skripts mit höheren Rechten erfolgt, macht es ggf. Sinn erst das Skript herunterzuladen um dann mit z.B. less installer.py zu prüfen, was es genau tut.

Siehe z.B. Raspberry Pi-hole - Installation
curl -sSL https://install.pi-hole.net | bash

Verbindung über einem Proxy aufbauen
curl -x yourproxy:port "URL"
-x, <[protocol://][user@password]proxyhost[:port]>

User-Agent verändern und eine URL aufrufen
curl -LA "Mozilla/5.0 (MSIE; Windows 10)" "https://www.google.com/search?q=Obergeis"
Hinweis: Siehe auch List of User Agent strings.

Formulardaten an einen Server senden, ist mit Hilfe von curl -X POST und -F für jedes Feld (field=value), welches man beim POST hinzufügen möchte, möglich.
curl -X POST -F 'username=admin' -F 'password=123456' https://test.de/login.php
Hinweis: Weitere Beispiele finden sich unter https://gist.github.com/subfuzion/08c5d85437d5d4f00e58#file-curl-md .

Cookies erstellen und verwenden (https://curl.se/docs/http-cookies.html)
Erstellen eines Cookies
curl -c "/tmp/cookie" http://localhost:8080/login -d username=admin password=123456
Verwenden eines Cookies
curl -b "/tmp/cookie" http://localhost:8080/getUserData

Curl Befehle mit Hilfe von Firefox kopieren

Dank der Entwicklerwerkzeuge in Firefox, lassen sich curl-Befehle einfach kopieren.



Samstag, 5. Dezember 2020

Raspberry Pi - Temperatursensor DS18B20 - Update I

Kurzes Update für den Artikel Raspberry Pi - Temperatursensor DS18B20. Jetzt gibt es ein Python Script, welches direkt die ID des Sensors herausfindet.

Mit dem Script temperatur.py ist es nicht mehr notwendig die ID (/sys/bus/w1/devices/xx-xxxxxxxxxxxx/w1_slave) des Sensors manuell anzupassen.

Download: wget https://www.shemel.de/download/raspberry/temperatur.py

Dienstag, 3. November 2020

Linux - Die gesamten Handbuchseiten (man pages) durchsuchen

Manchmal muss man bestimmte Wörter in allen Handbuchseiten (manual pages) nachschlagen. Hierbei hilft der Befehl "man -k <beispiel>".

"man" ist der wohl häufigste Weg, um an Informationen über Befehle des jeweiligen Programm zu bekommen.


Eine nützliche Funktion ist "man -k <beispiel>", um alle man-Seiten zu durchsuchen. Das ist sehr praktisch, wenn man den genauen Befhel nicht kennt.


Freitag, 9. Oktober 2020

Linux - Statische Kopie einer Webseite anlegen mit wget

Bereits in anderen Artikeln habe ich auf die Verwendungsmöglichkeiten von wget hingewiesen. Siehe z.B. Rund um Linux - Einige nützliche Befehle für die Shell II (Download mit wget und seq), Webservice Abfrage per Konsole mit wget und Erreichbarkeit von Webseiten oder Servern mit wget überpfüfen inkl. E-Mail Versand. Mit wget lassen sich sehr gut statische Kopien von Websites erstellen.


Ein einfaches wget [url] ist leider nicht ausreichend, da u.a. verschiedene Ressourcen pauschal nicht mitgeladen werden. 

Damit dies vollumfänglich funktioniert, sind die folgenden Parameter notwendig (siehe auch http://www.gnu.org/software/wget/manual/wget.html):

wget -p -nh -H -k -E -w 1 -r -l 1 [URL]

Siehe auch c't 21/2020 S. 154 Praxis Websites kopieren.

‘-p’ => ‘--page-requisites’
This option causes Wget to download all the files that are necessary to properly display a given HTML page. This includes such things as inlined images, sounds, and referenced stylesheets.

‘-nH’ => ‘--no-host-directories’
Disable generation of host-prefixed directories. By default, invoking Wget with ‘-r http://fly.srk.fer.hr/’ will create a structure of directories beginning with fly.srk.fer.hr/. This option disables such behavior.

‘-H’ => ‘--span-hosts’
Enable spanning across hosts when doing recursive retrieving (see Spanning Hosts).

‘-k’ => ‘--convert-links’
After the download is complete, convert the links in the document to make them suitable for local viewing

‘-E’ => ‘--adjust-extension’

If a file of type ‘application/xhtml+xml’ or ‘text/html’ is downloaded and the URL does not end with the regexp ‘\.[Hh][Tt][Mm][Ll]?’, this option will cause the suffix ‘.html’ to be appended to the local filename.

‘-w seconds’ => ‘--wait=seconds’
Wait the specified number of seconds between the retrievals. Use of this option is recommended, as it lightens the server load by making the requests less frequent.

‘-r’ => ‘--recursive’
Turn on recursive retrieving. See Recursive Download, for more details. The default maximum depth is 5.

‘-l depth’ => ‘--level=depth’
Specify recursion maximum depth level depth (see Recursive Download).


Allgemein nützliche Informationen zu wget finden sich auch hier: Frequently Asked Questions About GNU Wget.

Donnerstag, 24. September 2020

Linux - Anzeigen des TIMESTAMP in der history mit Hilfe von HISTTIMEFORMAT

Ruft man die history (Verlauf über die Befehlszeile) auf, werden normalerweise die Befehle mit #ID und der Befehl selber angezeigt. Es kann aber vorteilhaft sein, den Zeitstempel zusammen mit dem Befehl anzuzeigen.


Umgebungsvariable HISTTIMEFORMAT

HISTTIMEFORMAT in der ~/.bashrc mit dem folgenden Inhalt setzen:

HISTTIMEFORMAT="%F %T "

Hinweis: Der Zeitstempel kann nicht rückwirkend gesetzt, er wirkt sich nur auf die neu hinzugefügten Befehle aus!

 

Sonntag, 26. Juli 2020

Rund um Linux - Einige nützliche Befehle für die Shell II (Download mit wget und seq)

Nach 7 Jahren ein kurzes Update für meinen Beitrag "Rund um Linux - Einige nützliche Befehle für die Shell I" um die Shell als Downloadhelfer (wie auch hier Download von Video Streams mit ffmpeg und hier Regenradar - Bilder sammeln oder manuell abrufen beschrieben) verwenden zu können.


Der Download von Bildern mit einer Schleife ist relativ einfach möglich. Möchte man z.B. folgende Bilder mit einer bestimmten Nummerierung herunterladen:
Kann man dank seq Zahlen in einem definierten Bereich ausgegeben und mit Hilfe des Parameters -w auch führende Nullen hinzugefügen.

seq -w 3 10
03
04
05
06
07
08
09
10


Daraus ergibt sich der folgende Befehl:
for i in `seq -w 01 05`; do wget https://www.shemel.de/download/images/test_2020-${i}.jpg ; done

Will man die Statusmeldungen von wget unterdrücken, kann man noch den Parameter -q hinzufügen:
for i in `seq -w 01 05`; do wget -q https://www.shemel.de/download/images/test_2020-${i}.jpg ; done


Möchte man Bilder einer kompletten Gallery herunterladen, ist dies auch mit Hilfe von wget möglich.


wget -q -r -np https://www.tafel-hef.de/bilder.php

  • Mit Hilfe des Parameters -r werden rekursiv alle Dateien heruntergeladen, die bei der hinterlegten Adresse verlinkt sind.
  • Mit dem Parameter -np werden nur Dateien die unterhalb des Verzeichnisses liegen heruntergeladen (no-parent). Achtung: In dem oben genannten Beispiel funktioniert dies nicht, da die URL nicht mit "/" endet. So wird die komplette Webseite heruntergeladen (inkl. aller Bilder).

Mit Hilfe von youtube-dl, kann man per Kommandozeile Videos von youtube.com und anderen Video Plattformen herunterladen.


youtube-dl "https://www.youtube.com/watch?v=BvjterYmC98"

Viele Beispiele finden sich hier https://wiki.ubuntuusers.de/youtube-dl/ .

Samstag, 11. Juli 2020

Reguläre Ausdrücke (RegExp) mit Grep - Beispiele

Reguläre Ausdrücke (regular expression oder RegExp) bzw. Zeichenketten, können als Filterkriterien in Textsuchen verwendet werden. Der Text wird dabei mit dem "Muster" des regulären Ausdrucks abgeglichen. Somit kann man etwas suchen und finden, auch dann wenn man nicht mehr die genaue Schreibweise kennt.


Unter Linux kann man Hilfe von grep Dateien nach bestimmten Textzeichen durchsuchen. Unter Windows wäre die Verwendung mit Hilfe von grepWin (Regular expression search and replace for Windows) oder Select-String möglich.

Eine einfache Suche ist mit dem folgenden Befehl möglich:
  • grep 'hemel' \ ~/*
Der Parameter -E von grep definiert einen Regulären Ausdruck und die runden Klammern als Sonderzeichen. Mit dem Parameter -i ignoriert grep zusätzlich Groß- und Kleinschreibung.
Der | Strich (Pipe) steht für ein logisches "oder", somit wird nach dem "h" nach "hemel" und "hamel" gesucht.
  • grep -E -i 'h(e|a)mel' \ ~/*
Möchte man nach mehreren Zeichen inkl. Umlauten suchen, muss man die Zeichengruppe [] inkl. dem Quantifer + verwenden. Jetzt wird nach einem oder mehreren Zeichen gesucht, die innerhalb der [] vorkommen.
  • grep -E -i 'h[\0-9A-F]+mel' \ ~/*

Weitere Beispiele

  • [he]+ "h", "e", "hh", "hheeh" usw.
  • [0-6]{2,5} zwei bis fünf Ziffern von 0-6 in Folge, z. B. "16" oder "23456", jedoch nicht "7", "0.1" oder "1bca2“
  • h.{0,2}mel beliebiges Zeichen, min 0mal, max 2mal vorkommen, z.B. hemel, haemel, hmel

Wichtige Zeichen

  • . einzelnes Zeichen
  • (..) Gruppe von Elementen
  • ..|.. Oder Verknüpfung
  • ^ findet den Anfang einer Zeile
  • $ findet das Ende einer Zeile

Wichtige Zeichengruppen

  • [eam] ein Zeichen "e", "a" oder "m"
  • [0-9A-F] ein großer beliebiger Buchstabe oder eine beliebige Ziffer
  • [A-Za-z0-9] ein beliebiger Buchstabe oder eine beliebige Ziffer

Vordefinierte Zeichenklassen

  • \d Ziffer [0-9]
  • \D keine Ziffer [^\d] bzw. [^0-9]
  • \w Buchstabe [a-zA-Z_0-9]
  • \W weder Buchstabe noch Zahl noch Unterstrich [^\w]
  • \s whitespace Leerzeichen und Steuerzeichen \f, \n, \r, \t und \v
  • \S kein whitespace

Quantifier

  • ? optional, kommt null- oder einmal vor {0,1}
  • * beliebig oft oder auch keinmalt {0,}
  • +  mindestens einmal oder auch mehrfach {1,}
  • {n} muss exakt n-mal vorkommen {n,n}
  • {n,m} muss mindestens n-mal und darf maximal m-mal vorkommen

Unter debuggex.com kann man die erstellte regular expression testen und verstehen.


Dienstag, 29. Oktober 2019

Kommandozeilen Spiel - moon-buggy (Moon Patrol)

Für viele die mit dem Raspberry Pi experimentieren und ihn ohne GUI bzw. X-Server betreiben, gibt es mittlerweile einige Spiele, die man nur auf der Kommandozeile bzw. in der Shell spielen kann.
Siehe auch https://sebastianhemel.blogspot.com/2018/03/kommandozeilen-spiel-ninvaders-space.html .

Eines davon ist zum Beispiel moon-buggy, dabei handelt es sich um eine Variante des Rennspiels Moon Patrol.

Installieren kann man es einfach mit dem folgenden Befehl:
sudo apt-get install moon-buggy

Danach lässt sich das Spiel mit dem folgenden Befehl starten:
moon-buggy

Vielp Spaß beim Zocken!

Donnerstag, 22. August 2019

Raspberry Pi - Sensor BME280 Temperatur, Luftfeuchtigkeit, Luftdruck

Nachdem ich mit dem Ergebnis vom DHT22 Sensor nicht zufrieden war, erfolgt mit dem BME280 von Bosch ein erneuter Versuch.

Der Sensor BME280 misst Temperatur, Luftfeuchtigkeit, Luftdruck und Höhe. In dem Beitrag stelle ich die Anbindung und das Auslesen des Sensors vor.



Wie auch beim Anschluss des OLED Display (SSD1306) https://sebastianhemel.blogspot.com/2018/05/raspberry-pi-oled-display-ssd1306-i2c.html erfolgt auch die Ansteuerung des BME280 per I2C. Daher müssen auch hier die folgenden Einträge hinzugefügt werden:

sudo nano /etc/modules

i2c-bcm2708
i2c-dev


Jetzt muss noch die Konfigurationsdatei angepasst werden:
sudo vi /boot/config.txt

dtparam=i2c_arm=on #entfernen
dtparam=i2s=on     #entfernen
dtparam=i2c1=on

Jetzt muss noch ein reboot erfolgen, damit die Einstellungen übernommen werden:
sudo reboot 

Jetzt kann der Sensor analog dem OLED Display angeschlossen werden:


Damit man jetzt die Verbindung testen kann, sollte noch das folgemde Packet installiert werden:
sudo apt-get install i2c-tools

Mit dem folgenden Befehl kann überprüft werden, ob die Verbindung zum Sensor (Adressen 0x76 oder 0x77) Display funktioniert bzw. verbunden ist:
i2cdetect -y 1

Mit Hilfe des folgenden Scripts von Matt Hawkins, kann man den Sensor direkt abfragen (ggf. muss noch sudo apt-get install python-smbus -y installiert werden) oder auch die Befehle in seinen eigenen Python Scripts verwenden.

wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/python/bme280.py
python bme280.py

import bme280
...
temperature,pressure,humidity = bme280.readBME280All()
print "Temperature : ", temperature, "C"
print "Pressure : ", pressure, "hPa"
print "Humidity : ", humidity, "%"



Um die Daten jetzt auch im OLED I2C Display anzeigen zu können, habe ich folgende Methode hinzugefügt:

def GetTempBME280():
    temperature,pressure,humidity = bme280.readBME280All()
    print "Temperature : ", temperature, "C"
    print "Pressure : ", pressure, "hPa"
    print "Humidity : ", humidity, "%"
    time.sleep(0.2)
    value = "{:5.1f} °C {:.0f} %".format(float(temperature), float(humidity))
    value = unicode(value, 'utf-8')

    return value


wget http://www.shemel.de/download/raspberry/OLEDdisplayTempBME280.py


Alternativ kann man den Sensor auch mit der RPi.bme280 library ansteuern.
sudo pip install RPi.bme280

Montag, 19. August 2019

Raspberry Pi - Temperatursensor DHT22

Mit dem Temperatursensor DHT22 (ca. 5 EUR) kann man Luftfeuchtigkeit und Temperatur messen. Der Verkabelung ist analog zu dem Temperatursensor DS18B20.

In dem Beitrag stelle ich die Anbindung und das Auslesen des Sensors mit zwei verschiedenen Methoden vor. Ich habe auch den Quellcode vom https://sebastianhemel.blogspot.com/2018/05/raspberry-pi-oled-display-ssd1306-i2c.html angepasst, damit eine Ausgabe auf dem OLED I2C Display erfolgen kann.


Der DHT22-Sensor ist kostengünstig, lässt sich einfach ansteuern und ist digital (kein Analogkonverter/Kalibration notwendig). 
Der große Nachteil ist aber, dass er relativ langsam ist (Abfrage max. alle 3 Sekunden) und der Sensor stürzt oft ab und er muss vom Strom genommen werden, damit er neu gestartet werden kann.


Technische Daten des DHT22:
  • 3 - 5 V Spannungsversorgung und I/O
  • 2,5 mA Stromaufnahme
  • 0 bis 100 % Luftfeuchtigkeit-Messbereich, mit 2 bis 5 % Genauigkeit
  • -40 bis 80° Temperatur-Messbereich, mit +- 0,5°C Genauigkeit
  • maximal 0.5 Hz Sampling Rate (einmal jede zweite Sekunde)
  • Abmessungen: 15,1 mm x 25 mm x 7,7 mm (ohne Pins)
  • 4 pins mit 0.1'' Abstand (geeignet für Breadboards)
    • der dritte Pin  (zwischen DATA und GND)  ist nicht belegt
  • siehe auch https://cdn-shop.adafruit.com/datasheets/DHT22.pdf

Anschluss am Pi

Der Sensor darf am nur mit 3,3V Spannungsversorgung angeschlossen werden. Wichtig ist auch der 10 kilo-Ohm Widerstand, damit die Datenleitung nicht "gefloated" wird.


Als Alternative kann man auch den DHT22 mit integrierten Widerstand verwenden:


Sensor ansteuern mit pigpio

Mit der pigpio Bibliothek (C und Python) kann man beim Pi auf den GPIO Port zugreifen.
Damit dies funktioniert, muss pigpio als Daemon immer im Hintergrund laufen, damit ein Zugriff auf die Pins via Sockets und Pipes erfolgen kann.

Installtion erfolgt mit dem folgenden Befehl:
sudo apt-get install pigpio

Jetzt muss der pigpio daemon (pigpiod) als "root" gestartet werden:
sudo pigpiod

Am besten kann man dies auch gleich mit in der crontab vom "root" aufnehmen:
sudo crontab -e
@reboot pigpiod #start pigpio daemon

Über das folgenden Beispiel aus der pigpio Bibliothek, kann der Sensor angesprochen werden: https://github.com/joan2937/pigpio/raw/master/EXAMPLES/Python/DHT22_AM2302_SENSOR/DHT22.py (Download z.B. mit wget)

In der Datei "DHT22.py" muss jetzt noch der korrekte Daten-Pin eingestellt werden:
nano DHT22.py (Zeile 257)
...
s = DHT22.sensor(pi, 4, LED=16, power=8)
...


Je Zeile:
  • fortlaufende Nummer, Luftfeuchtigkeit, Temperatur, Staleness, Bad Checksum Counter, Short Message Counter, Missing Message Counter, Sensor Resets
Kommt es bei der Ausführung "python DHT22.py" zu der folgenden Fehlermeldung:
Traceback (most recent call last):
  File "DHT22.py", line 8, in <module>
    import pigpio
ImportError: No module named pigpio


Müssen noch die folgenden Module installiert werden:
sudo apt-get install python-pigpio python3-pigpio
Um die Daten jetzt auch im OLED I2C Display anzeigen zu können, habe ich folgende Methode hinzugefügt:

def GetTempDHT22():
    s.trigger()
    time.sleep(0.2)
    #print ("{:5.1f} °C {:.0f} %".format(s.temperature(), s.humidity()))
    value = "{:5.1f} °C {:.0f} %".format(s.temperature(), s.humidity())
    value = unicode(value, 'utf-8')
    return value


wget http://www.shemel.de/download/raspberry/OLEDdisplayTempDHT22pigpio.py


Sensor ansteuern mit Adafruit 

Der Open Source Treiber von Adafruit (C und Python) kann auch für die Ansteuerung verwendet werden.

Vor dem Download muss ggf. das System vorbereitet werden (Pakete build-essentail und python-dev):
sudo apt-get update
sudo apt-get install build-essential python-dev


Jetzt kann das GitHub Repository geklont werden:
git clone https://github.com/adafruit/Adafruit_Python_DHT.git

Anschließend muss der Quellcode noch konfiguriert werden:
cd Adafruit_Python_DHT/
sudo python setup.py install


Danach kann man die Library verwenden und das folgende Beispiel aufrufen:
cd examples
sudo ./AdafruitDHT.py 22 4

Temp=28.4*  Humidity=51.1%

Gibt es ein Problem oder wurde der falsche Pin verwendet, erscheint folgende Ausgabe:
Failed to get reading. Try again!

Um die Daten jetzt auch im OLED I2C Display anzeigen zu können, habe ich folgende Methode hinzugefügt:
...
import Adafruit_DHT
...
def GetTempDHT22():
    humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4)
    if humidity is not None and temperature is not None:
        print('Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity))
        value = '{0:0.1f}* {1:0.1f}%'.format(temperature, humidity)
    else:
        print('Failed to get reading. Try again!')
        value = 'Failed'
    return value


Donnerstag, 1. November 2018

Raspberry Pi - python Prozess automatisch neustarten

Ich habe festgestellt, dass sich mein python Script aus dem Beitrag Raspberry Pi - OLED Display (SSD1306) I2C ansteuern und Temperatur auslesen nach einer gewissen Zeit manchmal automatisch beendet.

Mit dem folgenden bash Script ist es möglich zu erkennen, ob der Prozess noch aktiv ist. Sollte dies nicht der Fall sein, wird das python Script wieder gestartet.

ps -aux | grep python
pi 2396  7.7  2.1  13904  9404 pts/0    S    20:08   0:01 python OLEDdisplayTemp.py


Update: Das Script muss ggf. als root (sudo) ausgeführt werden!
Eintrag in der "crontab -e" (check alle 9min):

*/9 *    *   *   *    sudo /home/pi/restartDisplay.sh >/dev/null 2>&1

restartDisplay.sh(www.shemel.de/download/raspberry/restartDisplay.sh)

#!/bin/bash
# (c) Sebastian Hemel, 2018
# show if the python script for the OLEDdisplay is running and do a restart

ps -aux | grep -v grep | grep OLEDdisplayTemp >/dev/null
if [ $? -eq 0 ];
then
     echo
     echo "Process 'OLEDdisplayTemp' is running."
     echo
else
     echo
     echo "Process 'OLEDdisplayTemp' is NOT running."
     echo "restarting..."
     echo
     python3 /home/pi/OLEDdisplayTemp.py &
fi

Montag, 27. August 2018

Regenradar - Bilder sammeln oder manuell abrufen

Auf der Internetseite des Bayerischen Rundfunk kann man sich für die jeweils letzten 3 Std. das aktuelle Regenradar anschauen. Auf dem Webserver selber werden aber die Daten der letzten 21 Tage zwischengespeichert.



Mit dem nachfolgenden Script getRadar.sh, kann man die Daten automatisch per Cron-Job oder manuell durch Parameter Übergabe abrufen.

wget http://www.shemel.de/download/bash/getRadar.sh
chmod +x getRadar.sh

Parameter Aufruf mit UTC Time
./getRadar.sh 2018-08-20 00:00:00

Cron-Job Aufruf (jede volle Std. mit 55min) für crontab -e
55  *  *  *  *       /home/pi/regen/getRadar.sh >> /home/pi/regen/myscript.log 2>&1



Quellcode: 


#!/bin/bash
#
echo '------------------------------------'
echo '| Hole Wetterradar-Daten von br.de |'
echo '| (c) Sebastian Hemel, 2018        |'
echo '------------------------------------'
echo ' '

#Aufruf per cron job am Besten jede volle Stunde mit 55min
#crontab -e
#55  *  *  *  *        /home/pi/regen/getRadar.sh >> /home/pi/regen/myscript.log 2>&1

#Beispiele der Dateien, Benamung erfolgt nach UTC (date -u), Bilder stehen ca. 10min nach der eigentlichern UTC Zeit zur Verfuegung
#http://www.br.de/wtr-data/img/radar_aroona/2018_08_08/aroona.radar.180808_0815.png
#http://www.br.de/wtr-data/img/radar_aroona/2018_08_08/aroona.radar.180808_0830.png
#http://www.br.de/wtr-data/img/radar_aroona/2018_08_09/aroona.radar.180809_1130.png
#
#Achtung beim Tageswechsel:
#http://www.br.de/wtr-data/img/radar_aroona/2018_08_20/aroona.radar.180820_2145.png => OK, 23:45
#http://www.br.de/wtr-data/img/radar_aroona/2018_08_20/aroona.radar.180820_2200.png => ERROR => http://www.br.de/wtr-data/img/radar_aroona/2018_08_21/aroona.radar.180820_2200.png

scriptFolder=/home/pi/aroona.radar.*
copyFolder=/home/pi/regen/radar

if [ $1 ]
  then
    echo Uebergabeparameter: $1 $2
    echo ' '
    Date=$1
    Time=$2
    DateTime=$Date' '$Time
    ##echo $DateTime
   
    DateArray=()
    for X in {00..59} ;                         # check every minute
    do
      # use manual date an time
      eval $(date -d "${DateTime}" -u +Y=%y\;m=%m\;d=%d\;H=%H\;M=%M)
      #eval $(date -d '2018-08-20 22:00:00' -u +Y=%y\;m=%m\;d=%d\;H=%H\;M=%M)
      M=$X
      [[ "$M" < "15" ]] && M=00                 # cater for octal clash
      M=$(((M/15)*15))
      ((M==0)) && M=00                             # the math returns 0, so make it 00
      ##echo $Y.$m.$d $H:$M
      DateArray+=($Y$m$d'_'$H$M)                # write in to array for the file name
    done
   
    #echo '--DateArray--'
    #for i in ${DateArray[@]}; do
    # echo $i
    #done
   
    # use manual date an time for the folder
    eval $(date -d "${DateTime}" -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
    DateTimePlusOneDay="${DateTime}+1 days"

    typeset -i i=0 max=${#DateArray[*]}
    while (( i < max ))
    do
        a=$( expr "$i" + 1 )
        # compare the array entries
        if [[ ${DateArray[$i]} != ${DateArray[$a]} ]]; then
            #catch error on midnight UTC
            if [ "$H" == "22" ]
                then
                    eval $(date -d "${DateTimePlusOneDay}" -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
                    echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
                    wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
                elif [ "$H" == "23" ]
                    then
                        eval $(date -d "${DateTimePlusOneDay}" -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
                        echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
                        wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
                    else
                        echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
                        wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
            fi      
            #echo "${DateArray[$i]}"
            #echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
            #wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
        fi
       i=i+1
    done  
   
########################################################################################################################################  
  else
    echo Es wurde kein Uebergabeparameter eingegeben! Verwenden Sie z.B. \"./getRadar.sh 2018-08-20 00:00:00\" UTC
    echo ' '
   
    DateArray=()
    for X in {00..59} ;                            # check every minute
    do
      eval $(date -u +Y=%y\;m=%m\;d=%d\;H=%H\;M=%M)
      M=$X
      [[ "$M" < "15" ]] && M=00                 # cater for octal clash
      M=$(((M/15)*15))
      ((M==0)) && M=00                             # the math returns 0, so make it 00
      ##echo $Y.$m.$d $H:$M
      DateArray+=($Y$m$d'_'$H$M)
    done
   
    # use manual date an time for the folder
    eval $(date -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)

    typeset -i i=0 max=${#DateArray[*]}
    while (( i < max ))
    do
        a=$( expr "$i" + 1 )
        # compare the array entries
        if [[ ${DateArray[$i]} != ${DateArray[$a]} ]]; then
            #catch error on midnight UTC
            if [ "$H" == "22" ]
                then
                    eval $(date -d tomorrow -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
                    echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
                    wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
                elif [ "$H" == "23" ]
                    then
                        eval $(date -d tomorrow -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
                        echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
                        wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
                    else
                        eval $(date -u +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
                        echo "wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png"
                        wget http://www.br.de/wtr-data/img/radar_aroona/"$Y"_"$m"_"$d"/aroona.radar."${DateArray[$i]}".png
            fi
        fi
       i=i+1
    done  
   
fi

#move files to folder
mv $scriptFolder $copyFolder

Sonntag, 4. März 2018

Kommandozeilen Spiel - ninvaders (Space Invaders)

Für viele die mit dem Raspberry Pi experimentieren und ihn ohne GUI bzw. X-Server betreiben, gibt es mittlerweile einige Spiele, die man nur auf der Kommandozeile bzw. in der Shell spielen kann.

Eines davon ist zum Beispiel ninvaders, dabei handelt es sich um eine Variante des Weltraum-Ballerspiels Space Invaders. Interessant ist sicherlicher auch der folgende Pacman-Klon.

Installieren kann man es einfach mit dem folgenden Befehl:
sudo apt-get install ninvaders

Danach lässt sich das Spiel mit dem folgenden Befehl starten:
ninvaders
/usr/games/ninvaders

Vielp Spaß beim Zocken!


Mittwoch, 13. Januar 2016

Raspberry Pi - Monitoring mit MRTG und Temperatursensor DS18B20

Mit Hilfe des Programms MRTG (Multi Router Traffic Grapher) und RRD (Round-Robin-Database) lassen sich unter Linux sehr schnell grafische Auswertungen und Darstellungen von Messwerten erstellen. Es können HTML Seiten mit Grafiken erstellt werden.

Falls man direkten Zugriff über den Browser auf die Dateien haben möchte, sollte vorher auf dem Pi noch ein Webserver installiert werden. Dafür kann man den Apache2 oder auch den Lighttpd verwenden.

Siehe hierzu auch http://sebastianhemel.blogspot.de/2015/09/raspberry-pi-webserver-installieren.html

 

Installation & Konfiguration von MRTG/RRD/SNMP:


Installation der benötigten Pakete für MRTG und RRD.
sudo apt-get install mrtg mrtg-rrd rrdtool snmp snmpd
Anschließend kommt die Frage, ob root der Eigentümer der Datei /etc/mrtg.cfg sein soll. Hier sollte NEIN ausgewählt werden.

Anschließend muss ein Verzeichnis angelegt werden, in dem die RRD Datenbank und die PNG-Grafiken abgelegt werden können. Dies muss im öffentlichen WWW-Ordner vom Webserver erfolgen.
/var/ $ sudo mkdir www
/var/www $ sudo mkdir mrtg
Anschließend hat man die folgende Ordner-Struktur:
/var/www/mrtg
Jetzt müssen wir noch das cgi-bin Verzeichnis erstellen, auch dieses liegt im WWW-Ordner. Nun kann ein Symlink (https://de.wikipedia.org/wiki/Symbolische_Verknüpfung) zur mrtg-rrd.cgi erstellt werden. Hierrüber kann dann später die generierte HTML-Seite aufgerufen.
sudo mkdir -p /var/www/cgi-bin
sudo ln -s /usr/lib/cgi-bin/mrtg-rrd.cgi /var/www/cgi-bin/mrtg-rrd.cgi
Im Nachgang müssen nun die Rechte für den Lighttpd-Benutzer und die Gruppe gesetzt werden:
sudo chown -R www-data:www-data /var/www/*
Da es bei SNMP noch einen Fehler gibt, siehe auch http://penguinbliss.com/?p=239, muss noch die folgende Datei angepasst werden:
sudo sed -i 's|import Socket6;|Socket6->import(qw(inet_pton getaddrinfo));|' /usr/share/perl5/SNMP_Session.pm
Bevor wir mit der Erstellung des Diagramms starten, sollte von der "alten" mrtg.cfg eine Sicherheitskopie angelegt werden.
sudo mv /etc/mrtg.cfg /etc/mrtg.cfg.bak

 

Temperaturwerte für RRD bereitstellen

Hierzu wird ein Skript benötigt. Diese kann man z.B. im Home-Verzeichnis ablegen.
mkdir ~/graph
temp-mrtg-update.sh (wget https://www.shemel.de/download/raspberry/temp-mrtg-update.sh)

#!/bin/sh
# Temperatur von Sensor auslesen
# (c) Sebastian Hemel

sensor="/sys/bus/w1/devices/28-00000511590a/w1_slave"
if [ -f $sensor ]
then
        sensorraw=`cat $sensor`
        crc=`echo $sensorraw | cut -f2 -d= | cut -c4-6`
        if [ "$crc" = "YES" ]
        then
                tempraw=`echo $sensorraw | cut -f3 -d=`
                temp=`echo "scale=3; $tempraw / 1000" | bc`
                #temp=`echo "scale=2; $tempraw / 1000" | bc`

                # Update database
                #echo $temp
                printf "%04.2f" $temp
                echo 0
                echo 0
                echo temperature
        fi
fi
 

Die Datei muss ausführbar sein:
chmod 750 /home/pi/graph/temp-mrtg-update.sh
Es ist zu beachten, dass die ID eures Sensors hinterlegt werden muss!

Das Script sollte die folgenden Werte liefern:
pi@pi-ingolstadt ~/graph $ ./temp-mrtg-update.sh
3.560
0
temperature

 

Erstellen des Diagramms vom Temperatursensor:


Zu Beginn muss eine neue mrtg.cfg erstellt werden, dies erfolgt mit dem Befehl:
sudo cfgmaker --global "Options[_]: growright" --global "IconDir: /mrtg" --global "WriteExpires: Yes" --global "Language: german" --global "RunAsDaemon: yes" --global "EnableIPv6: no" --global "LogFormat: rrdtool" --global "Interval: 1" '--if-filter=$if_admin && $default_iftype' --output /etc/mrtg.cfg public@localhost
Jetzt kann der folgende Teil in die sudo nano /etc/mrtg.cfg übernommen werden:

### Global Config Options

#  for UNIX
# WorkDir: /home/http/mrtg

#  for Debian
HtmlDir: /var/www/mrtg
WorkDir: /var/www/mrtg
Imagedir: /var/www/mrtg

#  or for NT
# WorkDir: c:\mrtgdata

### Global Defaults
#  to get bits instead of bytes and graphs growing to the right
# Options[_]: growright, bits

EnableIPv6: no
Options[_]: growright
IconDir: /mrtg
WriteExpires: Yes
Language: german
RunAsDaemon: yes
EnableIPv6: no
LogFormat: rrdtool
Interval: 1


#####################################################################
# System: DS18S20 Temperatur Sensor
# Contact: root
# Location: attached to Raspberry Pi
#####################################################################
### DS18S20 Temperatur SensorIngolstadt
TimeStrPos[temp_ingolstadt]: RU
Target[temp_ingolstadt]: `/home/pi/graph/temp-mrtg-update.sh`
Options[temp_ingolstadt]: gauge,growright,nopercent,expscale,transparent
Title[temp_ingolstadt]: Temperatur Ingolstadt
PageTop[temp_ingolstadt]: <h1>Temperatur Ingolstadt</h1>
MaxBytes[temp_ingolstadt]: 60
#Unscaled[temp_ingolstadt]: ymwd
Step[temp_ingolstadt]: 60
Legend1[temp_ingolstadt]: Gemessene Temperatur in Ingolstadt
LegendI[temp_ingolstadt]: Aussentemperatur
LegendO[temp_ingolstadt]:
YLegend[temp_ingolstadt]: Grad Celsius
ShortLegend[temp_ingolstadt]: Grad °C

Die restlichen Einträge habe ich auskommentiert, da ich nur das Temperatur Diagramm haben möchte.

Bei Bedarf können noch die MRTG-Icons in den WWW Ordner vom Webserver kopiert werden:
sudo cp /usr/share/mrtg/* /var/www/mrtg/
Jetzt kann durch Starten von MRTG überprüft werden, ob die Konfiguration erfolgreich durchgeführt wurde.
sudo env LANG=C /usr/bin/mrtg /etc/mrtg.cfg
Möchte man MRTG erneut starten, muss vorher der bestehende Prozess (Prozess-ID siehe auch /etc/mrtg.pid) beendet werden:
ps -aux | grep mrtg
sudo kill -9 16391
sudo env LANG=C /usr/bin/mrtg /etc/mrtg.cfg

Probleme mit negativen Temperaturwerten beheben

Da MRTG keine negativen Werte erlaubt, kann man diese nachträglich (mit rrdtool) mit dem folgenden Befehlen im Verzeichnis /var/www/mrtg anpassen.
sudo rrdtool tune temp_ingolstadt.rrd --minimum ds0:-20
sudo rrdtool tune temp_ingolstadt.rrd --minimum ds1:-20
Jetzt werden Temperaturen bis - 20 Grad Celsius unterstützt.

Der Aufruf des Diagramms erfolgt über den Browser http://192.168.1.110/cgi-bin/mrtg-rrd.cgi

Hinweise: Kommt es beim Aufruf der Datei zu einem "500 - Internal Server Error", wurden die Rechte chmod +x nicht gesetzt. Führte dies nicht zum Erfolg, sollte man die syslog Datei auslesen. Dies geht mit dem Befehl /var/log $ tail -f syslog . Erscheint hier die Meldung "Can't locate CGI.pm in @INC (you may need to install the CGI module)", muss noch das folgenden Paket installiert werden: sudo apt-get install libcgi-pm-perl 

Achtung es gibt ein Fehler im mrtg-rrd Package: https://bugs.launchpad.net/ubuntu/+source/mrtg-rrd/+bug/1618800

Nov  1 13:49:34 raspberrypi lighttpd[538]: Can't use an undefined value as an ARRAY reference at /var/www/cgi-bin/mrtg-rrd.cgi line 499.

Ich musste folgende Zeilen der "mrtg-rrd.cgi" anpassen:
Hinweis: Vorher am Besten den MRTG Prozess wieder beenden (siehe oben).

Aug  7 21:49:01 raspberrypi-zero lighttpd[461]: Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at /var/www/cgi-bin/mrtg-rrd.cgi line 499.
#       return @{$target->{args}} if defined @{$target->{args}};
        return @{$target->{args}} if ($target->{args} && @{$target->{args}});

Aug  7 21:52:28 raspberrypi-zero lighttpd[461]: Can't use 'defined(%hash)' (Maybe you should just omit the defined()?) at /var/www/cgi-bin/mrtg-rrd.cgi line 525.

#        %{$target->{options}} = ()
#                unless defined %{$target->{options}};           
         %{$target->{options}} = ()
                unless ($target->{options} && %{$target->{options}});   
           
Aug  7 21:58:11 raspberrypi-zero lighttpd[461]: Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at /var/www/cgi-bin/mrtg-rrd.cgi line 914.
       
#        if (defined @{$directories{$dir}{subdir}}) {
#                $subdirs_printed = 1
         if ($directories{$dir}{subdir} && @{$directories{$dir}{subdir}}) {
                $subdirs_printed = 1;
               
Aug  7 22:01:35 raspberrypi-zero lighttpd[461]: Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at /var/www/cgi-bin/mrtg-rrd.cgi line 929.

#        if (defined @{$directories{$dir}{target}}) {
         if ($directories{$dir}{subdir} && @{$directories{$dir}{subdir}}) {




Bei Bedarf kann das Diagramm noch auf einen anderen Server hochgeladen werden:

crontab -e: Aufruf per localhost, damit die temp_ingolstadt-day.png Datei erstellt wird (alle 7min).
*/7 *    *   *   *     curl http://localhost/cgi-bin/mrtg-rrd.cgi/temp_ingolstadt.html >/dev/null 2>&1

temp.sh: anpassen, siehe auch http://sebastianhemel.blogspot.de/2015/01/temperatursensor-ds18b20-raspberry-pi.html
ncftpput -f /home/pi/ftp.cfg /temp /var/www/mrtg/temp_ingolstadt-day.png


Danke an das Tutorial von http://kopfkino.irosaurus.com/tutorial-monitoring-mit-mrtg-rrd-support-auf-raspberry-pi-debian-wheezy, welches als Basis für diesen Eintrag diente.