Doppelte Icons im Launchpad entfernen

Dieser Beitrag beschreibt mein erster Lösungsansatz für Mac-Geräte.

Problem

Ich hatte das Problem, dass im Launuchpad eine Applikation mehrfach vorhanden war. Kann durchaus auch vorkommen, dass dies mehrere Applikationen betrifft.

Lösung

Ohne den Weg über das Terminal geht es nicht, also öffnen wir dieses und gibt folgenden Befehl ein:

rm ~/Library/Application\ Support/Dock/*.db

Damit wird, ausgehend vom Home-Verzeichnis,  alle Infodatei gelöscht. Nun muss der Dock neu gestartet werden:

killall Dock

Zu bemerken ist, dass sofern man Unterordner angelegt und die Anwendungen entsprechend sortiert hat, dies wieder erneut einrichten muss.

Photobox

Ausgangslage

Offenbar gibt es aufsteigenden Trends für Verwendung einer Photobox. Vor allem solche mit Sofortdruckfunktion sind aufgrund ihres Unterhaltungswerts und wegen der tollen Erinnerungen auf Feierlichkeiten beinahe unverzichtbar.

Diese Erkenntnis überbrachte mir eine Kundin mit dem Auftrag mit Raspberry Pi(RasPi) die Software dazu zu realisieren. Die Hardware wurde mir zur Verfügung gestellt und die Box wurde auch von der Kundin gebaut. Für mich war das Neuland, aber solche Herausforderungen reizen mich bei meinen Arbeiten.

Dies ist keine vollständige Beschreibung, sondern für mich um die Schritte zu dokumentieren. Aber eventuell hilft es anderen bei der Umsetzung.

Funktion

Der Wunsch war, dass von der Kamera ein Live-Bild an RasPi gesendet und im Display angezeigt wird. Darin sollen drei Buttons für Aufnahme, Drucken und Live Bild eingeblendet sein. Über einen Präsenter soll das Foto geschossen und das Live-Bild eingefroren und bei „Neu“ wieder zurückgeschaltet werden. Mit „Speichern“ soll das Bild in höherer Auflösung auf die Karte gespeichert und mit „Drucken“ ausgedruckt werden.

Material

Zur Verfügung hatte ich neben Raspberry Pi folgende Teile:

  • 10,1 Zoll HDMI Touch-Screen Display
  • Canon EOS 450D
  • DNP DS-40

Installation

System update

Als erstes sollte RasPi aktuell gehalten werden:

sudo apt-get -y update && sudo apt-get -y upgrade

Display einrichten

Das Display anzuschliessen war nicht so ein Problem. Der RasPi benötigte noch eine Treiber-Installation, da die Proportion der Anzeige nicht stimmte:

cd /boot/
wget https://www.waveshare.com/w/upload/1/1e/LCD-show-180817.tar.gz
tar xzvf /boot/LCD-show-*.tar.gz  
cd LCD-show/
chmod +x LCD101-1024x600-show
./LCD101-1024x600-show

Nach dem Neustart stimmt nun die Auflösung

Druckerinstallation

Das Einrichten des Druckers lief auch ohne Probleme mit Hilfe von Cups und

sudo apt-get install cups
sudo usermod -a -G lpadmin pi

Nun kann der Drucker angeschlossen und eingeschaltet werden. Cups erkennt diesen automatisch. Wenn RasPi im Grafikmodus läuft, kann über den Webbrowser mit der Adresse http://127.0.0.1:631 der Drucker konfiguriert werden.

Kamerasteuerung

Für die Ansteuerung der Kamera erweist sich GPhoto als hilfreich.

sudo apt-get install gphoto2   # Installation von GPhoto
gphoto2 --capture-image-and-download # Testen

Nun war das „Problem“, dass RasPi automatisch ein Laufwerk mit der Kamera verbunden hat. Ansich eine gute Sache, aber damit hat GPhoto keinen Zugriff auf die Kamera. Mit einem Kniff muss demnach die Überwachung ausgeschaltet werden. Ich mache das, indem ich die Betreffenden Dateien umbenenne:

cd /usr/share/dbus-1/services/
sudo mv org.gtk.vfs.GPhoto2VolumeMonitor.service *.orig
sudo mv *.orig org.gtk.vfs.GPhoto2VolumeMonitor.service.orig
cd /usr/share/gvfs/mounts/
sudo mv gphoto2.mount gphoto2.mount.orig
cd /usr/share/gvfs/remote-volume-monitors/
sudo mv gphoto2.mount gphoto2.mount.orig
sudo mv gphoto2.monitor gphoto2.monitor.orig
cd /usr/lib/gvfs/
sudo mv gvfs-gphoto2-volume-monitor gvfs-gphoto2-volume-monitor.orig

Und dann klappt’s auch mit dem Nachbarn.

Ein Life-Bild kann auf folgende Weise angezeigt werden:

gphoto2 --capture-movie --stdout> fifo.mjpg & omxplayer fifo.mjpg

Allerdings habe ich darüber keine Kontrolle, sodass ich das in meinem Programm nicht einbauen konnte.

Nun ist alles eingerichtet und man kann beginnen die Software zu schreiben.

 

Software

Als erste war die Überlegung, in welcher Programmier-Umgebung möchte ich das umsetzen. Aufgrund des Systems kam eigentlich Python in Frage. Die nächste Frage war, da Python standardmässig keine grafischen Elemente kennt, was verwende ich dafür und entschied mich für Pygame als Erweiterung.

Die grosse Herausforderung war, die Live-Bilder von der Kamera angezeigt zu bekommen, das Streamen funktioniert leider nicht per Python. Die Dokumentation war nicht sehr hilfreich und im Netz war dazu nur wenig Info auffindbar. Der Kamera Einzelbilder zu entlocken war nicht klug, da der Spiegel sich jeweils öffnete (die Mechanik lässt grüssen). Nach dem ich duzende Codes durch gestrählt habe, fand ich endlich den Befehl, der den Spiegel offenlässt. Somit lade ich Einzelbilder von der Kamera und zeige sie dann im Display an.

Ram-Disk einrichten

Der letzte Knackpunkt war eher ein versteckter, an den man nicht denkt: Das Betriebssystem und damit auch der Code und die Ablage der Einzelbilder vom Live-Bild liegen auf der SD-Karte. Diese Karten haben aber nur eine begrenzte Anzahl an Schreibzyklen, danach verabschieden sie sich allmählich. Die Lösung war, da RaspPi genügend Reserve hat, ein Ram-Disk einzurichten, wo die Ablage des Live-Bildes im Arbeitsspeicher stattfindet.

Dazu erst ein Verzeichnis anlegen:

sudo mkdir /mnt/RAMDisk

und dann folgenden Eintrag in die Datei /etc/fstab einfügen:
tmpfs /mnt/RAMDisk tmpfs nodev,nosuid,size=16M 0 0

 

Die Größe wird über den Parameter „16M“ auf 16 MB festgelegt. Jetzt alle Filesysteme über einbinden:

sudo mount -a

Der Erfolg lässt sich mit Diskfree überprüfen:

 sudo df

Photobox Code V1.0 Beta

Nachfolgend ist der Python-Code, mit dem Userinterface was die Kamera und den Drucker steuert:

import piggyphoto
import pygame
import os
import time
import subprocess as sub
from shutil import copyfile


usecamera         = True
cameraonline      = False
running           = True
freeze            = False
pos               = [0,0]
click             = [0,0,0]
width             = 1024
height            = 600
button_width      = 200
button_hight      = 50

white             = (255,255,255)
black             = (0,0,0)
save_button       = (200,100,50)
save_button_light = (255,155,105)
print_button      = (200,200,0)
print_button_light= (255,255,0)
live_button       = (34,177,76)
live_button_light = (90,230,130)

intro_file        = "images/intro.jpg"
preview_file      = "/mnt/RAMDisk/preview.jpg"
capture_file      = "/mnt/RAMDisk/capture.jpg"
discon_file       = "images/offline.jpg"
photo_dest_file   = "photos/capture_"

def DrawCenterMessage(message,width,height,x,y):
    #displays notification messages onto the screen

    backgroundCenterSurface = pygame.Surface((width,height))#size
    backgroundCenterSurface.fill(black)

    main_surface.blit(backgroundCenterSurface,(x,y))#position
    main_surface.blit(pygame.font.SysFont("freeserif",40,bold=1).render(message, 1, white),(x+10,y+10))
    pygame.display.update()




def text_objects(text, color):
    textSurface = pygame.font.SysFont("comicsansms", 50).render(text, True, color)
    return textSurface, textSurface.get_rect()




def text_to_button(msg, color, buttonx, buttony, buttonwidth, buttonheight):
    textSurf, textRect = text_objects(msg,color)
    textRect.center = ((buttonx+(buttonwidth/2)), buttony+(buttonheight/2))
    main_surface.blit(textSurf, textRect)





def button(text, x, y, width, height, inactive_color, active_color, action = None):
    global pos
    global click
    if x + width > pos[0] > x and y + height > pos[1] > y:
        pygame.draw.rect(main_surface, active_color, (x,y,width,height))
        if click[0] == 1 and action != None:
            if action != None:
                action()
                click = [0,0,0]
            
    else:
        pygame.draw.rect(main_surface, inactive_color, (x,y,width,height))

    text_to_button(text,black,x,y,width,height)



def keypressed_event():
    global pos
    global click
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            return "quit"

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                return "photoshut"
            if event.key == pygame.K_RIGHT:
                return "photoshut"
            if event.key == pygame.K_LEFT:
                return "photoshut"
            if event.key == pygame.K_q:
                return "quit"

        if event.type == pygame.MOUSEBUTTONDOWN: 
            pos = pygame.mouse.get_pos()
            click = [1,0,0]




def show(file):
    picture = pygame.image.load(file)
    picture = pygame.transform.scale(picture, (width, height))
    main_surface.blit(picture, (0, 0))
 




def doPhotoShut():
    if cameraonline:
        DrawCenterMessage("CHEEEEESSSSSE....",400,70,((width/2)-220),((height/2)-2))
        print C.abilities
        C.capture_image(capture_file)
        show(preview_file)


def doCopy():
    DrawCenterMessage("BILD GESPEICHERT!",400,70,((width/2)-220),((height/2)-2))
    date_string = time.strftime("%Y-%m-%d-%H:%M")
    copyfile(capture_file, photo_dest_file + date_string + ".jpg")



def doPrint():
    DrawCenterMessage("PRINT....",400,70,((width/2)-220),((height/2)-2))
    cmd = "lpr -P DNP_DP-DS620 -o PageSize=w288h432 " + capture_file
    p = sub.Popen(cmd,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
    show(preview_file)



def doCatch():
    global freeze
    freeze = False



def initCamera():
    global main_surface
    global usecamera
    global cameraonline
    global C
    if usecamera:
        try:
            C = piggyphoto.camera()
            C.leave_locked()
            C.capture_preview(preview_file)
            cameraonline = True
        except:
            print "PiggyPhoto Fehler: Keine Kammera verbunden oder nicht eingeschaltet!"
            cameraonline = False
    else:
        cameraonline = False

    picture = pygame.image.load(intro_file)
    picture = pygame.transform.scale(picture, (width, height))
    pygame.display.set_mode(picture.get_size(), pygame.FULLSCREEN)
    main_surface = pygame.display.get_surface()

pygame.init()
initCamera()

while running:
    if cameraonline:
        if freeze == False:
            try:
              C.capture_preview(preview_file)
              show(preview_file)
            except:
                cameraonline = False

    else:
        initCamera()
        show(discon_file)

    if freeze:
        button("Speichern", 150,500,button_width,button_hight, save_button, save_button_light, action = doCopy)
        button("Drucken",   400,500,button_width,button_hight, print_button, print_button_light, action = doPrint)
        button("Neu",       650,500,button_width,button_hight, live_button, live_button_light, action = doCatch)

    pygame.display.update()

    event = keypressed_event()
    if event == "quit":
        running = False
    if event == "photoshut":
        doPhotoShut()
        freeze = True

So, damit ist das Projekt auch gesichert  😆

Jingle Desk (Prototyp)

Die Software „Jingle Desk“ ist eine Applikation, welche verschiedene Sounds abspielt. Die Sounds können auf verschiedene Buttons im Fenster abgelegt mit der Mausklick abgespielt werden.

Applikation

Manager

Einzelne Elemente können individuell konfiguriert werden. Die Reihenfolge und Platzierung von Gruppe und Medien kann einfach mit der Maus vorgenommen werden.

Ausführungen

Es werden zwei Editionen, Freeware und Bezahlversion, entstehen. Folgende Eigenschaften unterscheiden sie:

Eigenschaft Freeware Pro
Unlimitierte Mediendatei X X
Unlimitierte Spalten X X
Mehrere Player parallel abspielbar  X X
Hot-Key Steuerung X X
Playerfarbe beliebig wählbar X X
Grosser Infobereich mit Uhr, Timer Player- und Audiosteuerung X X
Unlimitierte Assets-Gruppen X
Ausschnitt aus einer Datei abspielen X
Interne Medienliste* X
Fernsteuerung (via weiteren Jingle Desk oder Android)* X
Loopfunktion X
MIDI-Ansteuerung* X

*) Funktion geplant.

Eigenschaften:

  • Unbegrenzte Assets-Gruppen
  • Unbegrenzte Buttons
  • Mehrere Stücke parallel abspielbar
  • Loop-Funktion
  • Individuelle Lautstärke
  • Individuelle Beschreibung z.B. für Vorführinfo
  • Gruppe und Medien beliebig positionierbar (Drag and Drop)
  • Grosser Infobereich für Uhr, Timer und Mediensteuerung
  • Ausschnitt (Sequenz) abspielen
  • Fade-In / Fade-Out
  • V/U-Meter
  • Hotkey
  • Geplant: Interne Medienliste
  • Geplant: Farbliche Hervorhebung bei bestimmten Ereignis
  • Geplant: Zeitplan für Erinnerungen
  • Geplant: Fernbedienung
  • Geplant: MIDI-Ansteuerung

Download

Download unter http://www.adi.ch/?Projekte___Jingle_Desk

Internet der Dinge (IoT)

In diesem Abschnitt möchte ich meine derzeitige Arbeit im Zusammenhang der Internet of Things (IoT -> Internet der Dinge) beschreiben.

Was ist IoT und wozu wird das Verwendet? Ist das gefährlich?

IoT bezeichnet die Vernetzung von Gegenständen untereinander und mit dem Internet. Dies kann vom Kühlschrank bis zur Alarmanlage gehen, welche zentral gesteuert werden. Die Gedanke ist, dass diese Gegenstände selbstständig über das Internet kommunizieren und so verschiedene Aufgaben für den Besitzer erledigen können. Der Anwendungsbereich erstreckt sich dabei von einer allg. Informationsversorgung über automatische Bestellungen bis hin zu Warn- und Notfallfunktionen.

Übersicht und Prinzip vom IoT

Risiko

Risiko besteht tatsächlich, da es von Aussen zugänglich ist, dass das System gehakt, als „Verteiler“ für kriminelle Zwecke missbraucht werden könnte oder das System sonstige Schabernack treiben kann. Ein Gerät mit einem Betriebssystem, das sich zum Internet verbindet, lässt sich nun mal auch potenziell kompromittieren und die Anwender müssen sich auf zahlreichen Probleme in diesem Zusammenhang einstellen (was aber auch generell für PCs oder sogar Vernetzung im Auto betrifft):

  • Betriebsstörung
  • DoS-Angriffe (Denial-of-Service)
  • Hacking-Angriffe
  • Verwendung von Standardbenutzernamen und -passwörter

https://de.wikipedia.org/wiki/Internet_der_Dinge

Weitere zum Thema

Linux Tipps

Benutzer anlegen und sudo Recht vergeben:

adduser <username>
usermod -a -G sudo <username>

Berechtigung für Verzeichnis und Datei getrennt setzen:

chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)

GNU Lizens und ’no warranty‘ Dinger löschen beim  SSH-Login:

# Eine leere Datei ".hushlogin" ins Homeverzeichnis anlegen z.B. mit
touch ~/.hushlogin

Benutzerdefinierte Anzeige beim Anmelden im Terminal oder SSH

let upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
let secs=$((${upSeconds}%60))
let mins=$((${upSeconds}/60%60))
let hours=$((${upSeconds}/3600%24))
let days=$((${upSeconds}/86400))
UPTIME=`printf "%d days, %02dh%02dm%02ds" "$days" "$hours" "$mins" "$secs"`

# get the load averages
read one five fifteen rest < /proc/loadavg

echo "$(tput setaf 2)
   .~~.   .~~.    `date +"%A, %e %B %Y, %r"`
  '. \ ' ' / .'   `uname -srmo`$(tput setaf 1)
   .~ .~~~..~.    
  : .~.'~'.~. :   Uptime.............: ${UPTIME}
 ~ (   ) (   ) ~  Memory.............: `cat /proc/meminfo | grep MemFree | awk {'print $2'}`kB (Free) / `cat /proc/meminfo | grep MemTotal | awk {'print $2'}`kB (Total)
( : '~'.~.'~' : ) Load Averages......: ${one}, ${five}, ${fifteen} (1, 5, 15 min)
 ~ .~ (   ) ~. ~  Running Processes..: `ps ax | wc -l | tr -d " "`
  (  : '~' :  )   IP Adressen........: eth0: `/sbin/ifconfig eth0 | grep 'inet Adresse:' | cut -d: -f2 | awk '{ print $1}'`; wlan0: `/sbin/ifconfig wlan0 | grep 'inet Adresse:' | cut -d: -f2 | awk '{ print $1}'`
   '~ .~~~. ~'    Free Disk Space....: `df -Pk | grep -E '^/dev/sda1' | awk '{ print $4 }' | awk -F '.' '{ print $1 }'`k on /dev/sda1
       '~'
$(tput sgr0)"

Im terminal (hier über MobaXterm) sieht das dann so aus:

SSH-Terminal Darstellung nach Login
SSH-Terminal Darstellung nach Login

Projekte

Unter Projekte stelle ich gerne meine Prototypen und Projekte vor.

Aufruf:

Im Bereich Internet of Things (IoT) stelle ich mein Projekt vor. Es ist ein Prototyp mit dem Ziel eine Umgebung zu schaffen, welche benutzerfreundlich sein soll. Daher bitte ich allen Interessenten ihre Anregungen und Erwartungen diesbezüglich mir mitzuteilen. Die spannendsten Beiträge werden hier veröffentlicht.

Wenn Sie Fragen oder Anregungen habe in diesem Zusammenhang, können Sie gerne dieses Formular verwenden:

Programmierung

Primär entwickle ich mit Netbeans IDE, wenn ich in Java programmiere. Netbeans ist eine Entwicklungsumgebung, in der man für verschiedene Programmiersprachen entwickeln kann. Java ist eine Plattform unabhängige Programmierung für Windows, Mac oder Linux aber auch für Android lässt sich mit Netbeans programmieren.

Auch wenn ich alleine programmiere, verwende ich eine Versionsverwaltung. In meinem Fall verwende ich als Service den TortoiseSVN, welcher ich lokal einrichte. Daher kann ich im Netbeans nach verfolgen, welche Änderungen ich gemacht habe, wie das anhand der farbigen Balken angezeigt wird.

Netbeans lässt sich auch hervorragend als „Remote-Debugger“ einsetzen. So kann ich, wenn ich eine Applikation für den Raspberry Pi programmiere, das ganz bequem unter Windows erledigen und dann direkt von dort aus über SSH das Resultat auf dem Rasperry Pi ausführen.

Wenn Sie Fragen oder Anregungen habe in diesem Zusammenhang, können Sie gerne dieses Formular verwenden: