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.