Projekte

Startseite>Projekte

Doorbell – OpenSSL & PiCamera

Ich kümmere mich alle Zeit mal, dass alle Geräte im Haus die Updates bekommen.

Never change a running system

… halte ich für nicht die beste Wahl. Mir geht es bei den Updates in erster Linie um die Sicherheit™. Neue Funktionalitäten bringen die Updates selten, zumindest welche mich interessieren.

Nun gut… Somit schnell mal per SSH den Raspberry geupdatet… kurze Zeit drauf fällt mir auf dass der Push der Türklingel nicht mehr geht. Mal nachgeschaut, stimmt, der Log sagt dass alles gemacht wird: Gong, Bild abspeichern… aber beim Push ist nichts los… Warum dann keine Exception? Tja, da hat Jemand (ich) nicht aufgepasst und es fehlte der Log in die Logdatei:

except Exception, e:
    logger.info(e)
    traceback.print_exc()
    logging.exception("!!!")

Das schönste an der Geschichte: Wenn ich das Python Script als User pi oder auch als sudo starte geht der Push. Dann mal den Autostart angeschaut. Den hab ich dann mal schnell auf crontab umgestellt, weil mir das am liebsten ist:

crontab -e

Aber nix… dann schauen wir mal in den jetzt verfügbaren Log. Der Log sagt mir aber dann komische Sachen:

2019-07-13 16:42:11,225 INFO HTTPSConnectionPool(host='api.pushover.net', port=443): Max retries exceeded with url: /1/messages.json (Caused by SSLError(SSLError("bad handshake: Error([('', 'osrandom_rand_bytes', 'getrandom() initialization failed.')],)",),))

Mhhh, Google sagt da nicht viel… eigentlich dass das SSL Zertifikat von Pushover kaputt ist. Stimmt aber nicht. Und es geht ja nur nicht wenn es beim Boot gestartet ist.

Lange Rede kurze Lösung:
Ich hab mal OpenSSL vom Pi geupdatet, da ich diesen Issue gefunden habe.
Nutze requests, weil es so in der Pushover API Hilfe drin steht um Bilder hochzuladen.

So wie ich es verstehe wird das lokal geprüft ob die Zertifikate OK sind, wundert mich aber OK. Warum dass dann nur Probleme macht beim Boot, keine Ahnung. Aber es geht dann zumindest wieder. Kann sein dass ihr paar Pakete manuell installieren müsst damit OpenSSL über apt-get läuft.

 

Weil ich grad dabei war, hab ich auch den Code für das Erstellen des Fotos geändert von:

cmdCam='raspistill -q 10 -o ' + '/home/pi/Desktop/doorbell/web/photos/' +  filename
subprocess.call(cmdCam, shell=True)

auf:

camera = PiCamera()
[...]
camera.capture('/home/pi/Desktop/doorbell/web/photos/' +  filename)

Gibt es nun standardgemäß im Raspbian via from picamera import PiCamera.
Hab die Änderungen gleich ins Repo, hier ist der Commit.

Von |2019-07-18T16:15:10+02:002019-07-18|Doorbell, Projekte|

Festival Holledau App – 1.3

Und wieder ein Update das die Musikherzen höher schlagen lässt:

  • Prost: Krüge Archiv hinzugefügt
  • Zelt wiederfinden: Standorte speichern & teilen*
  • Musik auf die Ohren: Spotify Player Integration
  • Fit For Festival: App ist schlanker und schneller

*Deine Daten sind sicher: Es werden / wurden zu keiner Zeit personenbezogene Daten irgendwo gespeichert

 

Von |2019-05-09T20:00:57+02:002019-05-09|Coding, Festival Holledau App, Xamarin|

MuteToHue

Ich hatte ja einen CallMonitor für meine Fritzbox, welcher eine Lampe anschaltet wenn ich telefoniere.
Da wir unsere Telefonanlage nun auf Starface umgestellt haben, musste eine andere Lösung her.

Lange habe ich mir Gedanken gemacht, was hier wohl die beste Lösung ist.
Das Projekt wollte ich unbedingt in .NET Core machen, da ich hier noch nichts gemacht habe.

Da ich nun ausschließlich mit dem Headset telefonieren (dazu noch Skype, WebEx, usw.), läuft das komplette Audio über den Mac.
Wenn ich den Audio-Out mute, weil z.B. Radio läuft, geht das Audio trotzdem am Headset. Das ist sehr angenehm… denn nun musste ich nur noch den Mute-State überprüfen.

Am Mac ist das leider nicht mehr so einfach, aber habe eine Lösung hier gefunden:

public bool GetMuteState()
{
    var readMuteCommand = "osascript -e 'output muted of (get volume settings)'";
    string isMutedString = ReadFromBash(readMuteCommand);
    isMutedString = isMutedString.TrimEnd(Environment.NewLine.ToCharArray()).ToUpper();
    bool newState = isMutedString == "TRUE";
    return newState;
}

public string ReadFromBash(string readMuteCommand)
{
    var escapedArgs = readMuteCommand.Replace("\"", "\\\"");
    var process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = "/bin/bash",
            Arguments = $"-c {QUOTE}{escapedArgs}{QUOTE}",
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true,
        }
    };
    process.Start();
    string result = process.StandardOutput.ReadToEnd();
    process.WaitForExit();
    return result;
}

Das überprüfe ich nun alle 5s und wenn sich der Wert ändert, dann wird die Lampe geschalten:

Console.WriteLine("Monitoring mute state...");
bool isMuted = GetMuteState(); // Starting state
while (true)
{
    try
    {
        // Read state
        bool newState = GetMuteState();
        if (isMuted != newState)
        {
            Console.WriteLine("Muted: " + isMuted + " --> " + newState);
            SetHueState(newState);
            isMuted = newState; // All OK, set new state
        }

        Thread.Sleep(SLEEPTIME);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + Environment.NewLine + ex);
    }
}

Aber das Lampen schalten war nicht so einfach…

  • Erster Versuch über Q42.HueApi: Leider stürzt das Programm beim Zugriff auf die Klassen ab
  • Zweiter Versuch über IronPython ein kleine Script zu laden und ausführen: Das Compilieren gestaltet sich bisschen schwierig
  • Lösung: Ich habe ein kleines Python Script mit Platzhalter (True/False) ob die Lampe an ist. Zur Laufzeit ersetzt ich den Wert und führe es über die Bash aus
public void SetHueState(bool newState)
{
    // Read python script and replace placeholder
    var filename = @"/Users/moz/Documents/GitHub/Suplanus.MuteToHue/src/ControlViaPhue.py"; // todo: relative path
    var tempFile = Path.Combine(Path.GetTempPath(), "MuteToHue.py");
    string content = File.ReadAllText(filename, Encoding.UTF8);
    string stateString = FirstCharToUpper(newState.ToString());
    content = content.Replace("$STATE$", stateString);
    File.WriteAllText(tempFile, content, Encoding.UTF8);

    // Execute python script
    var command = $"python {QUOTE}{tempFile}{QUOTE}";
    var result = ReadFromBash(command);
}

public static string FirstCharToUpper(string input)
{
    return input.First().ToString().ToUpper() + input.Substring(1);
}
#!/usr/bin/python

from phue import Bridge
import os
import logging

HUEBRIDGEIP = "192.168.178.79"
LIGHTNAME = "OnAir" # OnAir # Buro

# Init hue
logging.basicConfig()

Bridge = Bridge(HUEBRIDGEIP)
Bridge.connect() # If the app is not registered and the button is not pressed, press the button and call connect() (this only needs to be run a single time)
Bridge.get_api() # Get the bridge state (This returns the full dictionary that you can explore)
light_names = Bridge.get_light_objects('name') # Get a dictionary with the light name as the key
LAMP = light_names[LIGHTNAME] # Get light object
LAMP.on = $STATE$ # True # $STATE$
LAMP.brightness = 254

Das Ganze findet ihr wie gewohnt auf GitHub.

Von |2019-03-13T07:22:19+02:002019-02-16|C#, Projekte|

Doorbell – Gong

Wir haben ja als Gong eine Funkbox eingesetzt welche über den AUX des Raspberries bespielt wird.
Leider bekommen wir Störgeräusche der Nachbarn rein, welche Funkkopfhörer benutzen. Diese funken wohl auf der gleichen Frequenz.

Nach Tests mit verschiedenen Kanälen (A & B) haben wir aber immer noch Hörspiele der Nachbarn gehört.

Generell war ich nie Fan von der Lösung da die Box und der Sender ständig am Strom hängen.
Ich hatte im Kopf schon die Lösung, aber mir fehlte die Zeit.

Da die Störungen aber immer mehr wurden hab ich mich mal hingesetzt und folgendes umgesetzt:

  • Box weg
  • Audio abspielen über Pi weg
  • Eine Funktürklingel gekauft
  • Den Sender an den Pi über Relais angebunden (12V)
  • Die Gong-Musik von den Kindern einstellen lassen

Technisch ist es nun meiner Meinung nach die bessere Lösung. Einziger Nachteil ist, dass ich die Gong-Musik nicht mehr selbst wählen kann. Somit musste meine geliebtes Super-Mario-Theme weichen.

Der Sender der Türklingel hatte einen SMD Taster den ich entlötet habe. Danach getestet ob es auch ein Schließer ist (ja).
Dort hab ich dann den Relaiskontakt integriert.

Die 12V Batterie vom Sender muss ich noch durch ein Netzteil tauschen wenn Sie oft leer ist.
Hier noch ein Bild der wilden Verdrahtung:

Als Ausgang hab ich die rote LED genommen. Diese ist während der Aufnahme des Fotos aktiv gewesen. Den Code musste ich dem entsprechend anpassen.

 

Von |2019-02-02T11:24:35+02:002019-02-02|Doorbell, Projekte|

Wippe selber bauen

Ich hab ja hier schon über viel geschrieben… aber dass ich mal zeige wie ich eine Wippe selber baue, hätte ich nicht gedacht.
Bei uns gibt es den Brauch, einen sogenannten Kindsbaum zur Hochzeit aufzustellen. Hier mal ein Auszug aus Wikipedia:

Vor allem in südbayerischen Raum ist es üblich, zur Hochzeit einen sogenannten Kindsbaum aufzustellen. Es handelt sich hierbei um einen 5 bis 10 m langen, weiß-blau bemalten Stamm, an dessen „Ästen“ diverse Baby-Sachen aufgehängt werden (Strampler, Schnuller, Flasche, etc.). In der Regel ist an der Spitze des Kindsbaums ein Storch montiert. Zudem befindet sich am unteren Ende des Baumes in Augenhöhe eine Tafel mit einem Gedicht, in dem das frisch vermählte Ehepaar an seine Pflicht erinnert wird, innerhalb eines Jahres Nachwuchs auf die Welt zu bringen. Gleich, ob sich Nachwuchs einstellt oder nicht, nach einem Jahr ist auf jeden Fall eine Brotzeit fällig, die nicht von den Kindsbaumaufstellern, sondern von dem Paar auszurichten ist.

Unserer war nicht ganz klassisch:

  • Anstatt 5-10m hoch, mit 18m riesig
  • Anstatt weiß blau, pink und grün, angemalt
  • Anstatt eines Storches einen Yoshi
  • LED-Solar-Lampen welche Sommer wie Winter schön geleuchtet haben

Der Kindsbaum wurde ein Jahr nach der Hochzeit umgelegt. Er hat auch gut funktioniert…
Viele wissen wohl dass ich Vater von Zwillingen geworden bin und da bietet sich eine Wippe als Spielgerät an :)
Hatte den Baum schon dafür eingelagert…

Hab mir dann bei Ebay das Gelenk und die Sitze mit Haltebügel gekauft. Sind im Internet zum Teil sehr teuer, darum vergleicht die Preise.
Das Gelenk habe ich seitlich gekürzt, da es sonst zu breit gewesen wäre. Wir mussten das Gelenk dann noch mit Eisen verstärken (seitlich angeschweißt und verschraubt). Habe dann noch Schaumstoff angebracht als Fingerschutz. Finde es auch albern dass das Gelenk für öffentlich Spielplätze gedacht ist und man sich so leicht einklemmen kann. Als Puffer, habe ich zwei alte Autoreifen eingegraben.

Meinen Mädels gefällt es sehr gut!

Von |2018-09-17T17:05:30+02:002018-09-17|Garten, Projekte|