Skript

EPLAN API: Geschachtelte Strukturen

Setzt man per EPLAN API die Strukturkennzeichen über die PagePropertyList, werden geschachtelte Strukturen (z.B. =F1.F2) nicht erkannt.

Als Workaround einfach bei den einzelnen Seiten folgendes ausführen:

page.Name = page.Name; // fix: sub name parts not recordnized by EPLAN (T1094079)

Sieht schlimm aus, darum auch bitte immer fleißig kommentieren :^)

Zu beachten: Es kann sein dass dadurch mehrere Strukturkennzeichen im Projekt erzeugt werden. Diese evtl. per Komprimierungslauf entfernen.

Von |2016-10-05T18:00:45+02:002016-10-10|EPLAN, EPLAN-API, EPLAN-Bugs|

FritzboxOnAir

Wenn man ein Büro für sich alleine hat, kennt man bestimmt die Situation: Man telefoniert gerade und eine andere Person klopft bzw. kommt zur Tür herein.

Aus diesem Grund wollte ich eine “OnAir” Lampe, welche man ja oftmals in Studios sieht. Diese soll anzeigen, dass ich gerade telefoniere.

Habe mir überlegt dass mit einem Raspberry Pi / Arduino zu machen… bin aber dann bei der Recherche darauf gekommen, dass die Hue-Lampen (ohne Farbe) garnicht so teuer sind. Diese kann man auch über eine API steuern.
Danach ist mir eingefallen: Wäre es nicht praktisch wenn bei einem eingehenden & ausgehenden Telefonat gleich die Lautstärke des Macs auf 0 gesetzt wird? Somit braucht man das auch nicht mehr machen…

Auf dem Video sieht hört man schlecht, dass die Musik aus geht, das ist aber der Fall und sooo praktisch :^)

Überlegte mir das in Mono mal zu schreiben, aber das ist immer noch ein graus, wenn man fertige Libraries einsetzen möchte, da diese nicht unter Mono laufen. Dann müsste ich den CallMonitor der Fritzbox neu schreiben, wie auch die C# Hue API. Das macht aber keinen Spaß.

Auf der Suche nach fertigen APIs bin ich bei Python hängengeblieben. Bin da zwar nicht so fit, aber kann doch nicht schaden. Und es war einfacher als gedacht, mit ein paar Zeilen Code und diesen Libraries, war das Projekt getan:

FritzboxOnAir on GitHub

#############################################################################
# FritzboxOnAir
#############################################################################

import os
from call_monitor import callmonitor
from phue import Bridge

import colorama
from colorama import Fore, Back, Style

HUEBRIDGEIP = "192.168.178.79"
LIGHTNAME = "OnAir"
PHONENUMBER = "9767518"
Volume = "" # todo: volumne only saved once (on startup)

# Reads the system volume to set it after call back to the value
def readVolume():
    v = os.popen('volume-osx')
    return v.read()

# Executes if calling
def Calling():
    print(Back.GREEN + 'Calling' + Style.RESET_ALL)
    Volume = readVolume() # for later
    os.system("volume-osx 0") # mute system volume
    Bridge.set_light(LIGHTNAME,'on', True) # turn light on

# Executes if no calling
def Sleeping():
    print(Back.CYAN + 'Sleeping' + Style.RESET_ALL)
    os.system("volume-osx " + Volume) # set to old value
    Bridge.set_light(LIGHTNAME,'on', False) # turn light off

# Get event from fritzbox
def callBack (self, id, action, details):
    print("Call: " + str(id) + " - " + action)
    print(details)

    # Check if the phonenumber is is in details
    if ("'to': '" + PHONENUMBER + "'" in str(details) or "'from': '" + PHONENUMBER + "'" in str(details)):
        # Parse Calling
        if (action == "outgoing" or action == "CALL" or action == "CONNECT" or action == "accepted" or action == "incoming" or action == "RING"):
            Calling()
        # Parse Sleeping: Checks also if calling is active
        if (action == "closed" or action == "DISCONNECT") and ("CONNECT" in str(details)):
            Sleeping()

# Read volume for later
print(Fore.LIGHTBLUE_EX + 'Get volume' + Style.RESET_ALL)
Volume = readVolume()

# Init hue
print(Fore.LIGHTBLUE_EX + 'Init hue' + Style.RESET_ALL)
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)

# Init call monitor
print(Fore.LIGHTBLUE_EX + 'Init Call monitor' + Style.RESET_ALL)
call = callmonitor() # Create new instance of py-fritz-monitor, Optinal parameters: host, port
call.register_callback (callBack) # Defines a function which is called if any change is detected, unset with call.register_callback (-1)
call.connect() # Connect to fritzbox

print(Fore.LIGHTBLUE_EX + 'Write close to end the script' + Style.RESET_ALL)
while(True):
    inputText = input()
    if inputText == "close":
        print(Fore.LIGHTBLUE_EX + 'Closing...' + Style.RESET_ALL)
        call.disconnect()
        break

 

Von |2016-12-05T07:49:38+01:002016-10-05|FritzboxOnAir, Python|

PlaceHolderMultiAddRecord

Frank hat ein schönes Script erstellt um mehrere Wertesätze schnell anzulegen.
Das Script wird über das Kontextmenü aufgerufen.

Download on GitHub

// PlaceHolderMultiAddRecord, Version 1.1.0, vom 04.11.2014
//
// Erweitert das Kontextmenü vom Platzhalterobjekt (Reiter Werte) um den Menüpunkt "Neuer Wertesatz (Mehrfach)..."
// Erlaubt darüber das anlegen von mehreren leeren Wertesätzen.
//
// Copyright by Frank Schöneck, 2013-2014
// letzte Änderung: Frank Schöneck, 16.01.2013 V1.0.0, Projektbeginn
//					Frank Schöneck, 04.11.2014 V1.1.0, Umgestellt von SendKeys auf Action "MacrosGuiIGfWindNewRecord"
//
// für Eplan Electric P8, ab V2.2
//

using System.Drawing;

public class FrankS_PlaceHolder
{
	[DeclareMenu()]
	public void PlaceHolderMultiAddRecordContextMenu()
	{
		//Context-Menüeintrag (hier im Platzhalterobjekt)
		Eplan.EplApi.Gui.ContextMenu oContextMenu = new Eplan.EplApi.Gui.ContextMenu();
		Eplan.EplApi.Gui.ContextMenuLocation oContextMenuLocation = new Eplan.EplApi.Gui.ContextMenuLocation("PlaceHolder", "1004");
		oContextMenu.AddMenuItem(oContextMenuLocation, "Neuer Wertesatz (&Mehrfach)...", "PlaceHolderMultiAddRecord", false, false);
	}

	[DeclareAction("PlaceHolderMultiAddRecord")]
	public void PlaceHolderMultiAddRecord_Action()
	{
		string value = "2";
		if (InputBox.Show("Neuer Wertesatz (Mehrfach)", "Wieviele Wertesätze sollen angelegt werden?", ref value) == DialogResult.OK)
		{
			int iValue = Convert.ToInt32(value); // Eingabe von Typ string in ein Typ int wandeln
			for (int i = 1; i <= iValue; i++)
			{
				new CommandLineInterpreter().Execute("MacrosGuiIGfWindNewRecord");
				//SendKeys.SendWait("^+{F10}W"); //Taste Kontextmenü aufrufen und direkt Taste W
			}
		}
		return;
	}
}

public class InputBox
{
	/// <summary>
	/// Displays a dialog with a prompt and textbox where the user can enter information
	/// </summary>
	/// <param name="title">Dialog title</param>
	/// <param name="promptText">Dialog prompt</param>
	/// <param name="value">Sets the initial value and returns the result</param>
	/// <returns>Dialog result</returns>
	public static DialogResult Show(string title, string promptText, ref string value)
	{
		Form form = new Form();
		Label label = new Label();
		TextBox textBox = new TextBox();
		Button buttonOk = new Button();
		Button buttonCancel = new Button();

		form.Text = title;
		label.Text = promptText;
		textBox.Text = value;

		buttonOk.Text = "OK";
		buttonCancel.Text = "Abbrechen";
		buttonOk.DialogResult = DialogResult.OK;
		buttonCancel.DialogResult = DialogResult.Cancel;

		label.SetBounds(9, 18, 372, 13);
		textBox.SetBounds(12, 36, 372, 20);
		buttonOk.SetBounds(228, 72, 75, 23);
		buttonCancel.SetBounds(309, 72, 75, 23);

		label.AutoSize = true;
		textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
		buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
		buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;

		form.ClientSize = new Size(396, 107);
		form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
		form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
		form.FormBorderStyle = FormBorderStyle.FixedDialog;
		form.StartPosition = FormStartPosition.CenterScreen;
		form.MinimizeBox = false;
		form.MaximizeBox = false;
		form.AcceptButton = buttonOk;
		form.CancelButton = buttonCancel;

		DialogResult dialogResult = form.ShowDialog();
		value = textBox.Text;
		return dialogResult;
	}
}

 

Von |2018-08-17T12:30:23+02:002016-10-04|EPLAN, EPLAN-Scripts|

Projekt ermitteln bei Event OnPostOpenProject

Ich habe in einem Script verschiedene Eventhandler die was im Projektordner (DOC) machen…
Klappt auch alles wunderbar… bis auf das Event vom Projekt öffnen. Ist mehr als ein Projekt geöffnet stimmt die Pfadvariable nicht:

var docFolder = PathMap.SubstitutePath("$(DOC)");

 

Durch den (immer tollen) EPLAN API Support habe ich folgende Lösung:

[DeclareEventHandler("Eplan.EplApi.OnPostOpenProject")] // project open
public void EventProjectOpen(IEventParameter iEventParameter)
{
   EventParameterString eventParameterString = new EventParameterString(iEventParameter);
   string projectFile = eventParameterString.String;

   FileInfo fileInfo = new FileInfo(projectFile);
   string projectDirectory = projectFile.Replace(fileInfo.Extension, ".edb");
   var docFolder = Path.Combine(projectDirectory, "DOC");
}
Von |2017-11-09T11:22:14+01:002016-07-27|EPLAN, EPLAN-Scripts|

7-Zip Sicherheitslücke

Ich persönlich nutze unter Windows ausschließlich 7-Zip für die ganze “Packerei”.
EPLAN nutzt das auch für z.B. die Projektsicherung (ZW1 ist auch ein Zip-Container).

Aus diesem Grund betrifft die Sicherheitslücke auch die EPLAN Software.
Nach Rücksprache mit EPLAN gibt es kein Update mehr für aktuelle Versionen, was ich sehr schade finde. Erst zur Version 2.6 wird die DLL ersetzt und somit die Sicherheitslücke geschlossen.

Man könnte die DLL manuell ersetzen, habe ich nicht getestet. Es ist auch nicht sichergestellt ob EPLAN dann noch korrekt funktioniert.

Von |2016-07-25T07:59:32+02:002016-07-25|EPLAN, EPLAN-Bugs|
Nach oben