Donnerstag, 3. Oktober 2019

Raspberry Pi - Sicherheits Checkliste


Kurze Checkliste, um seinen Pi zu "härten".


Passwort ändern

Nach der Inbetriebnahme sollte das Passwort "raspberry" des "pi" Benutzer geändert werden.

Updates durchführen

In regelmäßigen Abstanden und auch nach der Erstinstallation sollten die installierten Pakete auf Updates geprüft werden. Aufruf über die Konsole mittels apt-get https://wiki.ubuntuusers.de/apt/apt-get/ .
  • sudo apt-get update (Neueinlesen der Paketlisten)
  • sudo apt-get dist-upgrade (im Gegensatz zu upgrade werden nicht nur neue Pakete installiert sondern diese auch durch neue Abhängigkeiten unnötig gewordene Pakete ersetzt)

Regelmäßige Backups

Hat die Speicherkarte des Pi einen defekt, kann eine erneute komplette Einrichtung sehr viel Zeit kosten. Mit einem Windows Rechner und dem Win32 Disk Imager, kann man sehr schnell eine ISO Kopie der aktuellen Speicherkarte erstellen.

Externer Zugriff per VPN

Von unterwegs sollte man nach Möglichkeit nur per VPN auf den Pi (z.B. per SSH) zuzugreifen. Mit Hilfe einer Fritzbox von AVM lässt sich dies mittlerweile sehr schnell realisieren.

Freitag, 27. September 2019

Download von Video Streams mit ffmpeg

Viele Filme und Serien von Mediatheken kann man nicht einfach als MP4 Datei herunterladen, da diese im "m3u8" Format vorliegen (siehe auch https://en.wikipedia.org/wiki/HTTP_Live_Streaming). 


Mit Hilfe von ffmpeg ist einfacher Download möglich, ohne das man ein "mächtiges" Tool wie z.B. jDownloader installieren muss.

ffmpeg.exe -i https://xyz.akamaihd.net/.../09/film_2.../index_5_av.m3u8 -c copy FilmXYZ.mp4

Den Streaminglink kopieren und in den oberen Befehl einbauen (Dateiendung: m3u8).

Samstag, 21. September 2019

Klassische Desktop-Symbole unter Windows 10

Auch unter Windows 10 kann man die klassischen Desktop-Symbole z.B. "Computer" oder "Systemsteuerung" wieder aktivieren.


Die Einstellung dafür findet sich unter "Einstellungen" => "Personalisierung" => "Designs" => "Desktopsymboleinstellungen".


Dienstag, 17. September 2019

Online Visitenkarte mit GitHub Pages

Mit Hilfe von GitHub Pages ist es relativ schnell möglich eine online Visitenkarte oder auch einen Blog vollkommen kostenlos zu erstellen.


Alles was hierzu nötig ist, ist ein GitHub Account (in der kostenlosen Version):
 
Jetzt muss man ein Repository erstellen (z.B. mit dem Namen "card"):


Anschließend kann man das noch "leere" Repository aufrufen:

Jetzt kann man direkt eine neue Datei mit dem Namen "index.md" anlegen (https://github.com/shemel/card/new/master) und dort seine Informationen (Visitenkarte etc.) hinterlegen:

Hierbei handelt es sich dann um ein Markdown (vereinfachte Auszeichnungssprache): https://github.com/shemel/card/blob/master/index.md

Unter den Einstellungen (Settings) des Repository kann man unter dem Punkt "GitHub Pages" verschiedene Themes aussuchen:


Hier sollte man jetzt den "master branch" und ein passendes "Theme" auswählen. Das Theme selber wird in der "_config.yml" abgelegt:

Jetzt ist die Visitenkarte unter der folgenden URL abrufbar: https://shemel.github.io/card/


Montag, 2. September 2019

Webseite mit interaktiver Karte ohne Google Maps? Leaflet.js


Leaflet.js ist eine Open-Source-JavaScript-Bibliothek für interaktive Karten auf der eigenen Webseite.


Die JavaScript Bibliothek ist klein, einfach und flexibel und derzeit wahrscheinlich die beliebteste Open-Source-Mapping-Bibliothek. Gleichzeitig ist Leaflet.js auch eine gute Alternative zu Google Maps, da eine Verwendung nur noch nach Registrierung möglich ist und nur noch in einem geringen Umfang kostenlos ist.

Die Bibliothek ist kostenlos und frei nutzbar (2-Clause BSD License).
Desweiteren ist es möglich, dass die Karten vom eigenen Server ausgeliefert werden können, somit muss im Impressum bei der Datenschutzerklärung (DSGVO) nicht auf einen externen Service verwiesen werden.

Aktuelles Beispiel, wenn die Verwendung der Google Maps API ohne Registrierung erfolgt:


  • Are you using an API key?
  • Is billing enabled on your account?
  • Is the provided billing method no longer valid (for example an expired credit card)?
  • Is there an exceeded self-imposed daily limit on the API?
  • Does your API key have an IP addresses restriction?

Integration von Leaflet.js in die eigene Webseite:

  • Ordner entpacken und unter ../leaflet speichern
  • In der HTML-Datei ein div element mit einer id hinterlegen:
    • <div id="map_leaflet"></div>
  • Die CSS‐Datei und das Leaflet‐API‐Script einbinden:
    • <link rel="stylesheet" href="leaflet/leaflet.css" rel="stylesheet" />
    • <script src="leaflet/leaflet.js"></script>
  • Der Kartencontainer (mapid) muss eine definierte Höhe hat z.B. per CSS festlegen:
    • #map_leaflet{ height: 392px; } 
    • <div id="map_leaflet" style="width:800px; height:392px"></div>
  • Damit ein Layer anzeigt werden kann, muss der Kartenbereich (hier mit den Koordinaten) initalisiert werden:
    • var map = L.map('map_leaflet').setView([50.869333, 9.715948], 14);
  • Wie auch die Google Maps API benötigt die Leaflet API Kartenbilder (Tiles im .png oder .jpeg Format), diese werden je nach Zoomstufe schachbrettartig zu einer Karten zusammengesetzt:
    • https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png (Templatestring hinzufügen)
    • Servernummer = (s)
    • Zoomlevel = (z)
    • Koordinaten = (x,y)
    • Zoom Bereich und Copyright werden festgelegt
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
    attribution: 'Map data © OpenStreetMap and contributors CC-BY-SA',
    maxZoom: 18,
    minZoom: 9
}).addTo(map);
  • Metrischen Maßstab in der Karte einblenden:
    • L.control.scale({imperial:false}).addTo(map); // metrisch
  • Mit der Methode L.marker. kann man Orte auf der Karte markieren:
    • L.marker([50.869333, 9.715948]).addTo(map);


  • Mit bindPopup kann ein Popup hinterlegt werden und beim Aufrufen der Karte geöffnet werden:
    • L.marker([50.869333, 9.715948]).addTo(map).bindPopup("Bahnhofsmission Bad Hersfeld").openPopup();

Weitere Beispiele finden sich auch auf der Herstellerseite: https://leafletjs.com/examples.html

Anbei der komplette Quellcode:

<html>
    <head>
...
        <link rel="stylesheet" href="leaflet/leaflet.css" rel="stylesheet" />
...
        <script src="leaflet/leaflet.js"></script>
...
        <script type="text/javascript"> 
            function showMap() {           
                // initialize the map
                var map = L.map('map_leaflet').setView([50.869333, 9.715948], 14);
               
                // load a tile layer
                L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                    {
                        attribution: 'Map data © OpenStreetMap and contributors CC-BY-SA',
                        maxZoom: 18,
                        minZoom: 9
                    }).addTo(map);
               
                L.control.scale({imperial:false}).addTo(map); // metrisch
               
                //L.marker([50.869333, 9.715948]).addTo(map);
                L.marker([50.869333, 9.715948]).addTo(map).bindPopup("Bahnhofsmission Bad Hersfeld").openPopup();
            }
        </script>
    </head>
   
    <body onload="showMap()">
...
        <div id="map_leaflet" style="width:800px; height:392px"></div>
...
    </body>
</html>

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