| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- /*********************************************************************
- *
- * Afag Telnet C# Integration Sample Header
- *
- *********************************************************************
- * FileName: aflexCommunicationClass.cs
- * Dependencies: aflex_CSharp_Integration_Sample
- * Company: ima-tec GmbH
- *
- * Software License Agreement
- *
- *
- * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
- * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
- * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * AFAG BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
- * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
- * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
- * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
- * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
- *
- *
- ********************************************************************/
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace aflex_CSharp_Integration_Sample {
- class aflexCommunicationClass {
- //the target Values are the aflex Input values
- private UInt16 pr_target_direction;
- private UInt16 pr_target_intensity;
- private UInt16 pr_target_auxPowerOut;
- private Byte pr_target_ConfigNumber;
- private Byte pr_target_GeneralRelease;
- private Byte pr_target_ControllerRestart;
- //The actual device Values are the aflex Output values
- private UInt16 pr_actual_direction;
- private UInt16 pr_actual_intensity;
- private UInt16 pr_actual_auxPowerOut;
- private Byte pr_actual_ConfigNumber;
- private Byte pr_actual_AutoMode;
- private Byte pr_actual_GeneralRelease;
- private Byte pr_actual_ControllerRestart;
- //Bitoffset of the Values
- private const Byte pr_BitOff_direction = 48;
- private const Byte pr_BitOff_intensity = 64;
- private const Byte pr_BitOff_auxPowerOut = 8;
- private const Byte pr_BitOff_ConfigNumber = 0;
- private const Byte pr_BitOff_AutoMode = 32;
- private const Byte pr_BitOff_GeneralRelease = 40;
- private const Byte pr_BitOff_ControllerRestart = 24;
- //The aflex ControlUnit TelnetServer doesn't transmit a new package each time a value changed.
- //So the Client has to poll the aflex Outputs to detect the changes. For this the following TimeSpan are used.
- private TimeSpan pr_sync_direction= new TimeSpan();
- private TimeSpan pr_sync_intensity = new TimeSpan();
- private TimeSpan pr_sync_auxPowerOut = new TimeSpan();
- private TimeSpan pr_sync_ConfigNumber= new TimeSpan();
- private TimeSpan pr_sync_AutoMode = new TimeSpan();
- private TimeSpan pr_sync_GeneralRelease = new TimeSpan();
- private TimeSpan pr_sync_ControllerRestart = new TimeSpan();
- private const int TimerPeriod = 10; //fixed timer period in Milliseconds. Adjust that value due the Application requirements
- private TimeSpan tick = new TimeSpan(0, 0, 0, 0, TimerPeriod); //Timespan to Add each Timer tick
- private TimeSpan pr_MaxSync = new TimeSpan(0,0,0,0,100); //Timespan for polling the aflex Outputs. Adjust that value due the Application requirements, max value "ticks" * 7!
- private Timer objSyncTimer; //Timer for polling
-
- public TCPCommunicationClass objTelnetConnection; //connection interface
- private bool pr_b_LoggedIn; //Telnet Client logged in
- private bool pr_b_HBT; //Heartbeat state of the Telnet Server
- /// <summary>
- /// Occurs when a aflex value is recieved. Transmit the PropertyName as string.
- /// </summary>
- public event EventHandler aflexValueChanged;
- /// <summary>
- /// This Timer is used for cyclic polling the aflex outputs. TimerPeriod should be adjust due the Application requirements.
- /// </summary>
- /// <param name="state"></param>
- private void objSyncTimer_Tick(object state) {
- if (pr_b_LoggedIn) {
- pr_sync_direction = pr_sync_direction.Add(tick);
- pr_sync_intensity= pr_sync_intensity.Add(tick);
- pr_sync_auxPowerOut = pr_sync_auxPowerOut.Add(tick);
- pr_sync_ConfigNumber = pr_sync_ConfigNumber.Add(tick);
- pr_sync_AutoMode = pr_sync_AutoMode.Add(tick);
- pr_sync_GeneralRelease = pr_sync_GeneralRelease.Add(tick);
- pr_sync_ControllerRestart =pr_sync_ControllerRestart.Add(tick);
- //only send one "GO" command each tick --> return. The pr_sync_XXXX Timespan is reset when reading the "RO" input command from the Server.
- //So take care that the pr_MaxSync greater than "tick" * 7.
- if (pr_sync_AutoMode > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_AutoMode);
- return; //only send one Command each Tick
- }
- if (pr_sync_GeneralRelease > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_GeneralRelease);
- return; //only send one Command each Tick
- }
- if(pr_sync_intensity > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_intensity);
- return; //only send one Command each Tick
- }
- if (pr_sync_auxPowerOut > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_auxPowerOut);
- return; //only send one Command each Tick
- }
- if (pr_sync_ConfigNumber > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_ConfigNumber);
- return; //only send one Command each Tick
- }
- if (pr_sync_ControllerRestart > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_ControllerRestart);
- return; //only send one Command each Tick
- }
- if (pr_sync_direction > pr_MaxSync) {
- objTelnetConnection.SendCommand("GO " + pr_BitOff_direction);
- return; //only send one Command each Tick
- }
- }
- }
- public aflexCommunicationClass() {
- objSyncTimer = new Timer(objSyncTimer_Tick, null, TimerPeriod, TimerPeriod);
- objTelnetConnection = new TCPCommunicationClass();
- objTelnetConnection.ResultReceived += ObjTelnetConnection_ResultReceived;
- objTelnetConnection.ConnectionAbort += ObjTelnetConnection_ConnectionAbort;
- }
- private void ObjTelnetConnection_ConnectionAbort(object sender, EventArgs e) {
- this.pr_b_LoggedIn = false;
- if (aflexValueChanged != null) aflexValueChanged("LoggedIn", new EventArgs());
- }
- /// <summary>
- /// check the RX string for valid commands
- /// </summary>
- /// <param name="Result">input string</param>
- private void ObjTelnetConnection_ResultReceived(string Result) {
- if (Result != null) {
- string[] array_result = Result.Split(' '); //split with separator "space"
- string str_PropertyName = String.Empty;
- if (Result.Contains("\r\nTU")) { //Welcome String of Telnet server
- objTelnetConnection.SendCommand("admin");
- } else {
- if (array_result.Length == 1) { //TU & TP are the only commands with Lengt == 1
- switch (array_result[0]) { //after the TCP/IP connection is established the client has to log in on the Server. This is request by the server with the commands "TU" and "TP".
- case "TU": //Type User to login to TelnetServer
- objTelnetConnection.SendCommand("admin");
- break;
- case "TP": //Type Password of TelnetServer
- objTelnetConnection.SendCommand("TelnetServer");
- break;
- }
- } else if (array_result.Length > 1) { //all other Commands Length > 1
- switch (array_result[0]) {
- case "RO": //Read Output
- str_PropertyName = readRxValue(array_result);
- break;
- case "AK": //ACK from Set Input Command
- str_PropertyName = readRxValue(array_result);
- break;
- case "ER": //Errorcode
- str_PropertyName = "ER:" + array_result[1];
- break;
- case "LI": //Login/Logout response
- if (Convert.ToByte(array_result[1]) == 1) {
- pr_b_LoggedIn = true; //Now we can transfer aflex commands to the server
- } else {
- pr_b_LoggedIn = false;
- }
- str_PropertyName = "LoggedIn";
- break;
- case "HBT": //Heartbeat only for visualisation
- pr_b_HBT = array_result[1] == "1" ? true : false;
- str_PropertyName = "HBT";
- break;
- }
- }
- }
- if (aflexValueChanged != null) aflexValueChanged(str_PropertyName, new EventArgs());
- }
- }
- /// <summary>
- /// detect the RX commands and get the values
- /// </summary>
- /// <param name="Input">Rx input string array</param>
- /// <returns>PropertyName as string</returns>
- private string readRxValue(string[] Input) {
- if (Input.Length >= 2) {
- switch (Convert.ToByte(Input[1])) {
- case pr_BitOff_AutoMode:
- pr_actual_AutoMode = Convert.ToByte(Input[2]);
- pr_sync_AutoMode = pr_sync_AutoMode.Subtract(pr_sync_AutoMode); //Reset Sync Timespan
- return "AutoMode";
- case pr_BitOff_auxPowerOut:
- pr_actual_auxPowerOut = Convert.ToUInt16(Input[2]);
- pr_sync_auxPowerOut = pr_sync_auxPowerOut.Subtract(pr_sync_auxPowerOut); //Reset Sync Timespan
- return "AuxPowerOut";
- case pr_BitOff_ConfigNumber:
- pr_actual_ConfigNumber = Convert.ToByte(Input[2]);
- pr_sync_ConfigNumber = pr_sync_ConfigNumber.Subtract(pr_sync_ConfigNumber); //Reset Sync Timespan
- return "ConfigNumber";
- case pr_BitOff_ControllerRestart:
- pr_actual_ControllerRestart = Convert.ToByte(Input[2]);
- pr_sync_ControllerRestart = pr_sync_ControllerRestart.Subtract(pr_sync_ControllerRestart); //Reset Sync Timespan
- if (pr_actual_ControllerRestart != 0 && pr_target_ControllerRestart != 0) {
- pr_target_ControllerRestart = 0;
- objTelnetConnection.SendCommand("SI " + pr_BitOff_ControllerRestart + " " + pr_target_ControllerRestart); //After setting ControllerRestart, reset the Command to start the Restart.
- }
- return "ControllerRestart";
- case pr_BitOff_direction:
- pr_actual_direction = Convert.ToUInt16(Input[2]);
- pr_sync_direction = pr_sync_direction.Subtract(pr_sync_direction); //Reset Sync Timespan
- return "Direction";
- case pr_BitOff_GeneralRelease:
- pr_actual_GeneralRelease = Convert.ToByte(Input[2]);
- pr_sync_GeneralRelease = pr_sync_GeneralRelease.Subtract(pr_sync_GeneralRelease); //Reset Sync Timespan
- return "GeneralRelease";
- case pr_BitOff_intensity:
- pr_actual_intensity = Convert.ToUInt16(Input[2]);
- pr_sync_intensity = pr_sync_intensity.Subtract(pr_sync_intensity); //Reset Sync Timespan
- return "Intensity";
- }
- }
- return String.Empty;
- }
- #region Commands
- /// <summary>
- /// Establish the connetion to the Telnet Server
- /// </summary>
- /// <param name="IPAdress">IP Adress of the ControlUnit</param>
- /// <param name="Port">Port that is configured in the ControlUnit (default Port 23) </param>
- public bool Connect(IPAddress IPAdress,int Port) {
- return this.objTelnetConnection.Connect(IPAdress, Port);
- }
- /// <summary>
- /// disconnects from Telnet Server
- /// </summary>
- public void Disconnect() {
- this.pr_b_LoggedIn = false;
- this.objTelnetConnection.Disconnect();
- }
- /// <summary>
- /// Calculates the target direction and transmits the value to the aflex
- /// </summary>
- /// <param name="Degree">Direction [°]: 0-360 allowed</param>
- public void SetDirection (double Degree) {
- //Direction Value = (MaxValue / 360) * target dircetion (user manual 6.6.1)
- //MaxValue (16Bit) = 65535
- if (pr_b_LoggedIn) {
- //Calculate UINT16 Value 7
- if (Degree <= 360.0 && Degree >= 0.0) {
- pr_target_direction = (UInt16)((UInt16.MaxValue / 360.0) * Degree);
- objTelnetConnection.SendCommand("SI " + pr_BitOff_direction + " " + pr_target_direction);
- }
- }
- }
- /// <summary>
- /// Calculates the target intensity and transmit value to the aflex
- /// </summary>
- /// <param name="Intensity">Intensity [%]: 0-100 allowed</param>
- public void SetIntensity(double Intensity) {
- //Intensity Value = (MaxValue / 100%) * target direction[%] (user manual 6.6.1)
- //MaxValue (16Bit) = 65535
- if (pr_b_LoggedIn) {
- if (Intensity <= 100.0 && Intensity >= 0.0) {
- pr_target_intensity = (UInt16)((UInt16.MaxValue / 100.0) * Intensity);
- objTelnetConnection.SendCommand("SI " + pr_BitOff_intensity + " " + pr_target_intensity);
- }
- }
- }
- /// <summary>
- /// Set the general release of the ControlUnit
- /// </summary>
- /// <param name="Value">true = release | false = inhibit</param>
- public void SetGeneralRelease (bool Value) {
- if (pr_b_LoggedIn) {
- if (Value) pr_target_GeneralRelease = Byte.MaxValue;
- else pr_target_GeneralRelease = 0;
- objTelnetConnection.SendCommand("SI " + pr_BitOff_GeneralRelease + " " + pr_target_GeneralRelease);
- }
- }
- /// <summary>
- /// Calculates the target AuxPowerOutput of the ControlUnit and transmitt it. (AuxPowerOut --> Backlight)
- /// </summary>
- /// <param name="Intensity">Intensity [%]: 0-100 allowed</param>
- public void SetAuxPowerOut(double Intensity) {
- //Intensity Value = (MaxValue / 100%) * target direction[%] (user manual 6.6.1)
- //MaxValue (16Bit) = 65535
- if (pr_b_LoggedIn) {
- if (Intensity <= 100.0 && Intensity >= 0.0) {
- pr_target_auxPowerOut = (UInt16)((UInt16.MaxValue / 100.0) * Intensity);
- objTelnetConnection.SendCommand("SI " + pr_BitOff_auxPowerOut + " " + pr_target_auxPowerOut);
- }
- }
- }
- /// <summary>
- /// Load a aflexConfiguration
- /// </summary>
- /// <param name="ConfigNumber">Config number to load. 1-49 allowed</param>
- public void LoadConfiguration(byte ConfigNumber) {
- if (pr_b_LoggedIn) {
- if (ConfigNumber < 50 && ConfigNumber > 0) {
- pr_target_ConfigNumber = ConfigNumber;
- objTelnetConnection.SendCommand("SI " + pr_BitOff_ConfigNumber + " " + pr_target_ConfigNumber);
- }
- }
- }
- /// <summary>
- /// restart the ControlUnit. Telnet connection will be lost. Manual reconnect required.
- /// </summary>
- public void RestartController() {
- if (pr_b_LoggedIn) {
- pr_target_ControllerRestart = Byte.MaxValue;
- objTelnetConnection.SendCommand("SI " + pr_BitOff_ControllerRestart + " " + pr_target_ControllerRestart);
- }
- }
- #endregion
- #region Get/Set
- /// <summary>
- /// Client logged in on the Telnet Server
- /// </summary>
- public bool LoggedIn {
- get {
- return pr_b_LoggedIn;
- }
- }
- /// <summary>
- /// actual state of the Telnet Hearbeat. Toggles if connection established
- /// </summary>
- public bool HeartbeatState {
- get {
- return pr_b_HBT;
- }
- }
- /// <summary>
- /// actual aflex intensity as double [%] 0-100%
- /// </summary>
- public double actual_intensity {
- get {
- return (double)((pr_actual_intensity * 100.0 / UInt16.MaxValue));
- }
- }
- /// <summary>
- /// actual aflex direction as double [°] 0-360°
- /// </summary>
- public double actual_direction {
- get {
- return (double)((pr_actual_direction * 360.0 / UInt16.MaxValue)); //Convert uint16 value to double [°]
- }
- }
- /// <summary>
- /// actual ControlUnit auxPowerOutput as double [%] 0-100%
- /// </summary>
- public double actual_auxPowerOut {
- get {
- return (double)((pr_actual_auxPowerOut * 100.0 / UInt16.MaxValue));
- }
- }
- /// <summary>
- /// actual aflex Configuration Number as byte.
- /// </summary>
- public byte actual_ConfigNumber {
- get {
- return pr_actual_ConfigNumber;
- }
- }
- /// <summary>
- /// actual ControlUnit AutoMode. False - Manual | True - Automatic
- /// </summary>
- public bool actual_AutoMode {
- get {
- return pr_actual_AutoMode > 0 ? true : false;
- }
- }
- /// <summary>
- /// actual ControlUnit General Release. False - inhibit | True - released (if inhibit all power outputs are blocked)
- /// </summary>
- public bool actual_GeneralRelease {
- get {
- return pr_actual_GeneralRelease > 0 ? true : false;
- }
- }
- /// <summary>
- /// actual ControlUnit Restart bool
- /// </summary>
- public bool actual_ControllerRestart {
- get {
- return pr_actual_ControllerRestart > 0 ? true : false;
- }
- }
- #endregion
- }
- }
|