JohannWeiher

Über Johann Weiher

Der Autor hat bisher keine Details angegeben.
Bisher hat Johann Weiher, 505 Blog Beiträge geschrieben.

TIA Openness Firewall

Ich darf mich gerade, für ein Kundenprojekt, mit der Siemens TIA Portal API beschäftigen. Ist schon einige Jahre her dass ich das gemacht habe.
Viel hat sich geändert, im API-Design, und es sind viele neue Funktionen dazu gekommen.

Wird eine Openness Applikation ausgeführt muss dies vom User bestätigt werden:

Dies muss jedesmal gemacht werden wenn sich der Hash des Programms oder das Datum (LastModified) geändert hat. Das ist natürlich beim Debuggen schlimm, wenn jedes mal der Dialog kommt.

Ich hab mal die Methode hier gebastelt welchen den Whitelist-Eintrag (Bestätigung durch User) selbst macht:

public static void SetTiaPortalFirewall()
{
  // Check if admin
  WindowsIdentity identity = WindowsIdentity.GetCurrent();
  WindowsPrincipal principal = new WindowsPrincipal(identity);
  bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
  if (!isAdmin)
  {
    return;
  }

  Assembly assembly = Assembly.GetExecutingAssembly();
  string exePath = assembly.Location;

  // Get hash
  HashAlgorithm hashAlgorithm = SHA256.Create();
  FileStream stream = File.OpenRead(exePath);
  byte[] hash = hashAlgorithm.ComputeHash(stream);
  string convertedHash = Convert.ToBase64String(hash);

  // Get date
  FileInfo fileInfo = new FileInfo(exePath);
  DateTime lastWriteTimeUtc = fileInfo.LastWriteTimeUtc;
  string lastWriteTimeUtcFormatted = lastWriteTimeUtc.ToString("yyyy'/'MM'/'dd HH:mm:ss.fff");

  // Get execution version
  AssemblyName siemensAssembly = Assembly.GetExecutingAssembly().GetReferencedAssemblies().First(obj => obj.Name.Equals("Siemens.Engineering"));
  string version = siemensAssembly.Version.ToString(2);

  // Set key and values
  string keyFullName = $@"SOFTWARE\Siemens\Automation\Openness\{version}\Whitelist\{fileInfo.Name}\Entry";
  RegistryKey key = Registry.LocalMachine.CreateSubKey(keyFullName);
  if (key == null)
  {
    throw new Exception("Key note found: " + keyFullName);
  }
  key.SetValue("Path", exePath);
  key.SetValue("DateModified", lastWriteTimeUtcFormatted);
  key.SetValue("FileHash", convertedHash);
}

Adminrechte müssen da sein. Somit muss man Visual Studio als Administrator starten.

Von |2019-07-22T13:51:34+02:002019-03-26|TIA Portal|

Spotify embed responsive

Ich mag Spotify, hab zwar kein bezahltes Abo, aber um schnell mal Musik nachzuschlagen ist es super.
Da nehme ich auch gerne mal die Werbung in kauf.

Für ein aktuelles Projekt möchte ich den Spotify-Player einbinden. Dafür gibt es hier einen schönen Generator.

Leider ist aber der Iframe nicht responsive. Nach bisl googlen und selbst im Javascript zu frickeln, bin ich auf diese Lösung gekommen:

$(document).ready(function() {
  /* Make Spotify fit initial layout */
  respondify();
});


$(window).resize(function() {
  /* Make Spotify fit layout on resize */
  respondify();
});


function respondify() {
  $('body').find('iframe[src*="spotify.com/"]').each(function() {
    var w = $(this).parent(1).width();
    $(this).css('width', w + 'px');
    
    var h = $(window).height();
    $(this).css('height', h + 'px');

    $(this).attr('src',$(this).attr('src'));
  });

}

Das ganze könnt ihr hier auf CodePen auch anschauen.

Von |2019-03-18T11:33:19+01:002019-03-18|Coding|

Festival Holledau App – 1.2

Ein kleines feines Update gab es schon am 17.02.19 mit diesen Features:

  • Runde Bandbilder in der Liste: Damit es besser rund läuft!
  • Bandbild zoombar: Jetzt noch näher an den Bands sein!
  • Bands 2012-2013 hinzugefügt: Endlich wissen wer, wann gespielt hat!

Bin großer Fan von FFImageLoading geworden… werde da noch einiges nutzen.

Mir fehlt grad bisl die Zeit weiter daran zu arbeiten… Aber es steht noch einiges auf der Liste.

Von |2019-12-05T09:07:10+01:002019-03-15|Coding, Festival Holledau App, Projekte, Xamarin|

Syntax Highlightning

Denke es ist schon das dritte oder vierte Plugin … Leider wird Crayon nicht mehr weiterentwickelt.
Somit hab ich mich mal für ne Alternative umgesehen und EnlighterJS gefunden. Es gibt auch WordPress-Plugin dafür.

Das Theme gefällt mir gut und kann man auch anpassen. Es ist auch ziemlich schnell. Und das Wichtigste: Es wird aktiv weiterentwickelt.

Es gibt noch einen Bug mit dem Horizontalen-Scrollbalken… aber der wird bald gefixed.

Von |2019-03-14T10:20:11+01:002019-03-14|Allgemein|

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+01:002019-02-16|C#, Projekte|
Nach oben