Archiv für den Monat: März 2015

ExternalTestAssembly

Daniel Papp ist immer fleißig, vielen Dank nochmal an dieser Stelle.

Aufgrund der Implementierung von CAE-Consulting ist nun bekannt wie man DLLs im Scripting nutzen kann. Somit kann man auch Excel oder SQL bedienen… eigentlich Alles außer der immer noch kostenpflichtigen EPLAN API…

Vielen Dank für das Beispiel! Wie gewohnt findet man die Daten auf Daniels GitHub Repo.

using System;
using System.Reflection;
using System.Windows.Forms;

namespace ExternalTestAssembly
{
    public class Script
    {
        [Start]
        public void Run()
        {
            //AbsoluteAssemblyPath: for example "C:\Users\Public\EPLAN\Data\Binaries\MyWPFControlLibrary.dll
            Assembly myAssembly = Assembly.LoadFrom(@"AbsoluteAssemblyPath");

            //Namespace.ClassName: absolute name of the class to instaciate 
            //"InstAttibute": if the constructor of the class needs some attributes
            Object objectOfTestClass = myAssembly.CreateInstance("Namespace.ClassName", false, BindingFlags.ExactBinding, null, new Object[] {"InstAttibute"}, null, null);

            //Namespace.ClassName: again the class name to get the methode to execute
            //MethodName: Name of the method to execute
            MethodInfo show = myAssembly.GetType("Namespace.ClassName").GetMethod("MethodName");

            //result: remove if methode has no return type (void)
            //"MethodAttribute": attributes for the methode (could also be empty)
            Boolean result = (Boolean)show.Invoke(objectOfTestClass, new Object[]{ "MethodAttribute" });

            //go on with simple scriptcode
            if (result == true)
            {
                MessageBox.Show("Welcome to wonderland!");
            }
            else
            {
                MessageBox.Show("So you're not the chosen one!");
            }
            
        }
    }
}

 

Von |2017-11-09T12:23:40+01:002015-03-26|EPLAN, EPLAN-Scripts|

MenuCreator

Kennt Ihr das…?
Man hat ein Projekt längere Zeit im Kopf und man kommt nicht zur Umsetzung… Bei MenuCreator sind es ca. fünf Jahre.

Scripting in EPLAN macht Spaß, aber das Menübauen ist meiner Meinung nach nicht schön gelöst. Es ist somit fast unmöglich für einen EPLAN Anwender ohne Programmierkenntnissen sich selbst eins zu bauen.

Somit war das Ziel eine einfache UI zu bauen, in der man sich ein oder mehrere Menüs zusammenbauen kann.

Es können alle Scripte vom ShopForProcess einfach hinzugefügt werden. Aber auch eigene Scripte oder EPLAN Actions.

1

2

ShopForProcess: MenuCreator

Von |2015-03-25T13:08:01+01:002015-03-25|EPLAN, ShopForProcess|

Eigenschaftsanordnungsprojekt

Als EPLAN-Admin kennt man wohl die mühselige Arbeit alle Eigenschaftsanordnungen auf einen Standard zu bringen. Es ist sehr zeitintensiv und schwer zu organisieren. Hier kann ich jedem empfehlen es in einem eigenen Projekt zu machen und die Eigenschaftsanordnungen zu Im-/Exportieren über Projekt>Organisieren.

Eigenschaftsanordnungen-exportieren

Wenn man alle EPLAN-Symbole in allen Varianten platzieren möchte benötigt man dafür sehr viel Zeit. Ich habe es kurz mal gebenchmarked:

  • Symbolbibliotheken: 22
  • Symbole: 11590
  • Varianten: 87548

Bei manueller Platzierung wären es 251h vorausgesetzt man hat einen schnellen Rechner und arbeitet lokal. Wir haben ein Projekt vorbereitet welches alle Symbole in allen Varianten beinhaltet. Die Projekt-Struktur ist identisch mit der unter Einfügen>Symbol. Somit findet man sich schnell zurecht.

EPLAN-Projekt-Eigenschaftsanordnungen-Deutsch-2-3

Folgende Symbolbibliotheken wurden platziert:

  • BaseSymbolLibrary
  • CCL1ESS
  • GB_single_symbol
  • GB_symbol
  • GOST_single_symbol
  • GOST_symbol
  • GRAPHICS
  • HVAC_ESS
  • HYD1ESS
  • HYD2ESS
  • IEC_ED_ESS
  • IEC_SC_ESS
  • IEC_single_symbol
  • IEC_symbol
  • LUB1ESS
  • NFPA_single_symbol
  • NFPA_symbol
  • OS_SYM_ESS
  • PID_ESS
  • PNE1ESS
  • PPE_SYM SPECIAL

EPLAN-Projekt-Eigenschaftsanordnungen-Deutsch-2-3-Motorschutz

 

Pro Symbol und Variante wird eine eigene Eigenschaftsanordnung erstellt. Der Name ist Customer_A (wobei “A” die Variante darstellt). Gerne können wir auch z.B. euer Firmenkürzel voranstellen. Somit ist sogar dieser Aufwand minimiert einen Namen zu wählen.

2015-03-10_13-52-27

Das Projekt gibt es in Deutsch & Englisch in Version 2.3 & 2.4. Auf Anfrage erstellen wir gerne auch das Projekt in einer anderen Sprache bzw. Version. Im Artikel findet Ihr auch Beispiel-PDFs der Projekte:

Von |2016-01-11T14:35:18+01:002015-03-12|EPLAN, ShopForProcess|

KinderChocolateBot

Zu Weihnachten habe ich mir bisl Zeit genommen und wollte etwas mit Servo und NETMF machen. Brauche immer ein Projekt welches auch Sinn macht… Naja ob das Resultat sinnig ist, darf jeder selber Entscheiden.

Eigentlich sollte ich das Projekt unter Homeautomation einstellen, da es mir jeden Tag Zeit spart. Denn wir lieben Kinderschokolade :^)

Bevor ich aber jedes Mal alles rauskrame, dachte ich mir wäre doch ein Roboter, welcher mir die Arbeit abnimmt, sinnvoll.

Lego

Gesagt getan, endlich wieder mit Legos etwas bauen, passt irgendwie zu Weihnachten.

Bau 1 Bau 2

Bau Vorne Bau Hinten

Bau 3 Schalter

 

Rückansicht Seitlich Links

Seitlich Rechts Vorne

Folgende Komponenten wurden verbaut:

Gesamtkosten ca. 56€ was nicht gerade billig ist. Achja, Lego hatte ich schon, sonst wären es wahrscheinlich locker über 100€.

Das programmieren des Servos ist nicht ganz so einfach mit NETMF aufgrund fehlender Libraries für die Taktzeiten… hab mir bisl was zusammengesucht, denke aber ist nicht das beste Setup, da hier viel manuell gerechnet wurde (Clocktime). Da ist wohl ein nicht NETMF Controller besser.

Aber es funktioniert wie es sollte und schaut auch gut aus :^)

using Gadgeteer;
using Servo_API;
using Button = Gadgeteer.Modules.GHIElectronics.Button;

namespace Program
{
    public partial class Program
    {
        Servo servo; 
        private bool IsRunning;

        void ProgramStarted()
        {
            Debug("Set it UUUUP!");

            // Setup
            Mainboard.SetDebugLED(true);
            button.ButtonPressed += ButtonOnButtonPressed;
        }

        private void ButtonOnButtonPressed(Button sender, Button.ButtonState state)
        {
            if (!IsRunning)
            {
                Debug("Chocolate!");
                
                ledLeft.FadeOnce(Color.Red);
                ledRight.FadeOnce(Color.Red);

                IsRunning = true;

                servo = new Servo(extender);
                servo.Degree = -180;
                servo.Dispose();

                IsRunning = false;

                Debug("Bedtime!");                
            }
        }

        void Debug(string text)
        {
            Microsoft.SPOT.Debug.Print("==> " + text);
        }
    }
}
// Orginal http://stackoverflow.com/questions/22699174/netduino-class-servo-4-3-1

using Gadgeteer;
using Gadgeteer.Modules;
using Microsoft.SPOT.Hardware;
using System;
using System.Threading;

namespace Servo_API
{
    public class Servo : IDisposable
    {
        /// <summary>
        /// PWM handle
        /// </summary>
        private PWM servo;

        /// <summary>
        /// Timings range
        /// </summary>
        private int[] range = new int[2];

        /// <summary>
        /// Set servo inversion
        /// </summary>
        public bool inverted = false;

        /// <summary>
        /// Create the PWM Channel, set it low and configure timings
        /// </summary>
        public Servo(Module module)
        {
            // Init the PWM pin
            // servo = new PWM((Cpu.PWMChannel)channelPin, 20000, 1500, PWM.ScaleFactor.Microseconds, false);
            Socket SocketExtender = Socket.GetSocket(4, true, module, "socketExtender");
            servo = new PWM(SocketExtender.PWM9, 20000, 1500, PWM.ScaleFactor.Microseconds, false);
            servo.Period = 20000;

            // Typical settings
            range[0] = 900;
            range[1] = 2100;
        }

        public void Dispose()
        {
            disengage();
            servo.Dispose();
        }

        /// <summary>
        /// Allow the user to set cutom timings
        /// </summary>
        /// <param name="fullLeft"></param>
        /// <param name="fullRight"></param>
        public void setRange(int fullLeft, int fullRight)
        {
            range[1] = fullLeft;
            range[0] = fullRight;
        }

        /// <summary>
        /// Disengage the servo. 
        /// The servo motor will stop trying to maintain an angle
        /// </summary>
        public void disengage()
        {
            // See what the Netduino team say about this... 
            servo.DutyCycle = 0; //SetDutyCycle(0);
        }

        /// <summary>
        /// Set the servo degree
        /// </summary>
        public double Degree
        {
            set
            {
                // Range checksJa
                if (value > 180)
                    value = 180;

                if (value < 0)
                    value = 0;

                // Are we inverted?
                if (inverted)
                    value = 180 - value;

                // Set the pulse
                //servo.SetPulse(20000, (uint)map((long)value, 0, 180, range[0], range[1]));
                servo.Duration = (uint)map((long)value, 0, 180, range[0], range[1]);
                servo.Start();
                Thread.Sleep(360);
            }
        }


        private long map(long x, long in_min, long in_max, long out_min, long out_max)
        {
            return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
        }
    }
}
Von |2018-05-14T15:23:21+02:002015-03-10|Gadgeteer, NETMF, Projekte|

MainMenuName

Man lernt nie aus…
Menü-Erzeugung ist etwas was man beim EPLAN-Scripting meist als erstes macht… da schaut man sich auch keine Methoden an…

Wie im vorherigen Post erwähnt, habe ich bisl was mit mehreren Oberflächensprachen gemacht. Hier gab es ein Problem wenn man ein Hauptmenü hinzufügen will, denn normalerweise gibt man ja den Namen an (z.B. “Hilfe”). Aber im englischen heißt es eben anders…

Dafür hat EPLAN die Enumeration MainMenuName implementiert, was eigentlich immer der empfohlene Weg wäre:

public enum MainMenuName {
  eMainMenuProject = 0,
  eMainMenuPage,
  eMainMenuEdit,
  eMainMenuView,
  eMainMenuProjectData,
  eMainMenuFind,
  eMainMenuOptions,
  eMainMenuUtilities,
  eMainMenuWindow,
  eMainMenuHelp,
  eMainMenuInsert,
  eMainMenuLayoutspace,
}

Die Verwendung sieht wie folgt aus:

uint menuId = menu.AddMainMenu("MyMenu", Eplan.EplApi.Gui.Menu.MainMenuName.eMainMenuHelp,
    "MyMenu", "ActionName", "Description", 1);

Hätte ich das eher Gewusst das besser recherchiert als ich das Buch geschrieben habe, wäre die Info eher gekommen :^)

Von |2017-11-09T12:23:40+01:002015-03-09|EPLAN, EPLAN-Scripts|
Nach oben