QuickStart

QuickStart 1:

Dieser Dokumentationsartikel gilt nur für den TwinCAT FTP Client ab Version 4.x.

Dieser Dokumentationsartikel soll Ihnen einen ersten, schnellen Start in die Verwendung dieses Produkts ermöglichen. Den untenstehenden Programmcode finden sie zum Herunterladen auch unter Beispiele. Dort ist auch der Programmcode für einen schnellen Start mit älteren Produktversionen zu finden. Nach der erfolgreichen Installation und Lizensierung führen Sie die folgenden Schritte aus, um eine Verbindung mit einem FTP/SFTP Server herzustellen und Variablen für den Lese-/Schreibzugriff zu konfigurieren.

Konfigurieren eines FTP/SFTP Servers

Dieser QuickStart Artikel setzt einen bereits vorkonfigurierten und funktionstüchtigen FTP/SFTP Server voraus. Hierfür können Sie prinzipiell eine beliebige FTP/SFTP Serverapplikation verwenden, z.B. FileZilla, Microsoft IIS, OpenSSH-Server, Tiny SFTP Server, uvm.

Im weiteren Verlauf dieses Artikels gehen wir von den folgenden Einstellungen aus, bitte ersetzen Sie ggf. die jeweiligen Parameter durch die Parameter aus Ihrem Versuchsaufbau:

Eigenschaft

Beschreibung

Server-Typ

SFTP Server

Hostname

Der Server ist auf dem lokalen System installiert und somit über die IP-Adresse 127.0.0.1 erreichbar.

Port

23

Benutzername

My_SFTP_User

Password

SomeSecurePassword##1

Rootverzeichnis

\

Berechtigungen

Benutzer hat Lese-/Schreibrechte auf dem Verzeichnis

Verwendung der Tc3_Ftp Bibliothek für den FileUpload

Wir wollen nun eine Verbindung zum SFTP Server herstellen und eine Datei in das Rootverzeichnis des o.g. Benutzers hochladen. Erstellen Sie hierfür ein neues TwinCAT Projekt, sowie ein SPS-Projekt und referenzieren Sie dort die Bibliothek Tc3_FTP. Wechseln Sie anschließend in das MAIN Programm und fügen Sie die folgenden Codezeilen hinzu.

Deklarationsteil:

PROGRAM MAIN
VAR
    fbSimpleUpload : FB_SimpleUpload;
END_VAR

Implementierungsteil:

fbSimpleUpload();

Fügen sie anschließend einen POU hinzu und nennen Sie diesen FB_SimpleUpload. Fügen Sie dort folgende Codezeilen hinzu.

Deklarationsteil:

FUNCTION_BLOCK FB_SimpleUpload
VAR
    bStart             : BOOL; // Starts the QuickStart sample

    fbConnection       : FB_FtpConnection(1) := (sNetID:= '', tTimeout:= T#60S);
    fbExplorer         : FB_FtpExplorer := (sNetID:= '', tTimeout:= T#60S);
    fbTransfer         : FB_FtpTransfer := (sNetID:= '', tTimeout:= T#60S);
  
    stTransferInfo     : ST_FtpTransferState;
    stNTDataProfile    : ST_FtpConfigProfile;
  
    sPathToOriginFile  : STRING(255) := 'C:\Temp\myFileUpload.txt';
    sPathToTargetDir   : STRING(255) := '\';

    bDone              : BOOL;
    bError             : BOOL;
    sErrorMSG          : STRING(255);
    nCase              : INT;
    nTransferHandle    : UDINT;
    fbTimer            : TON := (PT:=T#1S); 
END_VAR

Implementierungsteil:

CASE nCase OF
    0: (* Start the QuickStart sample. *)
        IF bStart THEN
            bDone := FALSE;
            bStart := FALSE;
            nCase := 10;
        END_IF
        
    10: (* Connect to server by specifying the profile. Create a new profile if the connection profile does not exist, yet. *)
        IF fbConnection.Connect(
            sFtpConfigProfileFileName:='QuickStart'
        ) THEN
            nCase := 15;
        END_IF
        
    11: (* Connection profile does not exist, yet. Specify connection parameters and store in a new profile. *)
        stNTDataProfile.stConnection.eAuth := E_FtpConnectionAuth.sftp_user_pwd;
        stNTDataProfile.stConnection.nPort := 23;
        stNTDataProfile.stConnection.sHostname := '127.0.0.1';
        stNTDataProfile.stConnection.sUsername := 'My_SFTP_User';
        stNTDataProfile.stConnection.sPassword := 'SomeSecurePassword##1';
        stNTDataProfile.stConnection.sFileName := 'QuickStart';
        
        IF fbConnection.AddProfile(
            stFtpConfigProfile := stNTDataProfile
        ) THEN
            nCase := 16;
        END_IF

    15: (* Check connection establishment for any errors. *)
        IF fbConnection.bError THEN
            IF fbConnection.ipResultMessage.EqualsToEventClass(Global.TC_EVENT_CLASSES.TcFtpClientEventClass) THEN
                CASE fbConnection.ipResultMessage.nEventId OF
                    E_FtpClientErrorCode.Code_1101_HostConnectionOpen: (* Already connected to the correct host, continue*)
                        nCase := 20;
                    E_FtpClientErrorCode.Code_1100_AnyConnectionOpen: (* Already connected to another host. Abort.*)
                        nCase := 210;
                    E_FtpClientErrorCode.Code_1102_FileLocationError: (* Profile has not been created yet. *)
                        nCase := 11;
                ELSE
                    nCase := 210; (* an unexpected FtpClient error has occured *)
                END_CASE
            ELSE
                nCase := 210; (* an unexpected other error (Ads, Router, ...) has occured*) 
            END_IF
        ELSE
            nCase := 20; (* Start file upload. *)
        END_IF

    16: (* Check profile creation for any errors *)
        IF fbConnection.bError THEN
            IF fbConnection.ipResultMessage.EqualsToEventClass(Global.TC_EVENT_CLASSES.TcFtpClientEventClass) THEN
                CASE fbConnection.ipResultMessage.nEventId OF
                    E_FtpClientErrorCode.Code_1106_ParametersImproper: (* The profile is configured improperly (e.g. HostName empty or Port 0) *)
                        nCase := 210;
                ELSE
                    nCase := 210; (* an unexpected FtpClient error has occured *)
                END_CASE
            ELSE
                nCase := 210; (* an unexpected other error (Ads, Router, ...) has occured*) 
            END_IF
        ELSE
            (* now that the profile has been created, try connecting again *)
            nCase := 10;
        END_IF 

    20: (* Initiate file upload. *)
        IF fbTransfer.Upload(
            fbFtpConnection         := fbConnection, 
            sLocalSourcePath         := sPathToOriginFile,    
            sServerTargetDirectory     := sPathToTargetDir,
            nTransferHandle         => nTransferHandle
        ) THEN
            nCase := 25;
        END_IF

    25: (* Check file upload initiation for any errors*)
        IF fbTransfer.bError THEN
            IF fbTransfer.ipResultMessage.EqualsToEventClass(Global.TC_EVENT_CLASSES.TcFtpClientEventClass) THEN
                CASE fbTransfer.ipResultMessage.nEventId OF
                    E_FtpClientErrorCode.Code_1106_ParametersImproper: (* Source or Target could be empty *)
                        nCase := 210;
                    E_FtpClientErrorCode.Code_1110_Busy_TryAgain: (* The connection is busy (ONLY FTP). Try again later. *)
                        nCase := 210;
                ELSE
                    nCase := 210; (* an unexpected FtpClient error has occured *)
                END_CASE
            ELSE
                nCase := 210; (* an unexpected other error (Ads, Router, ...) has occured*) 
            END_IF
        ELSE
            (* now that the transfer has been initialised, check transfer state *)
            nCase := 30;
        END_IF 
        
    30: (* File upload has been started, now cyclically check transfer state. *)
        fbTimer(IN:=TRUE); 
        IF fbTimer.Q THEN
            fbTimer(IN:=FALSE);
            nCase := 40;
        END_IF

    40: (* Request transfer state *)
        IF fbTransfer.GetState(
            fbFtpConnection         := fbConnection,
            nTransferHandle         := nTransferHandle,
            stTransferState            => stTransferInfo
        ) THEN
            nCase := 45;
        END_IF
        
    45: (* Check GetState for any errors*)
        IF fbTransfer.bError THEN
            IF fbTransfer.ipResultMessage.EqualsToEventClass(Global.TC_EVENT_CLASSES.TcFtpClientEventClass) THEN
                CASE fbTransfer.ipResultMessage.nEventId OF
                    E_FtpClientErrorCode.Code_1106_ParametersImproper: (* The transfer for the provided handle could not be found *)
                        nCase := 210;
                ELSE
                    nCase := 210; (* an unexpected FtpClient error has occured *)
                END_CASE
            ELSE
                nCase := 210; (* an unexpected other error (Ads, Router, ...) has occured*) 
            END_IF
        ELSE
            nCase := 50;
        END_IF

    50: (* Check if file transfer is completed and has not produced any errors *)
        IF (stTransferInfo.eProblem = E_FtpTransferProblemType.None) AND (stTransferInfo.eStep = E_FtpTransferStep.TransferCompleted) THEN
            nCase := 60; // file transfer completed with no errors
        ELSIF stTransferInfo.eProblem <> E_FtpTransferProblemType.None THEN
            nCase := 210; //file transfer encountered an error
        ELSE
            nCase := 30; // not completed yet, check state again
        END_IF
        
    60: (* Disconnect from server. *)
        IF fbConnection.Disconnect() THEN
            nCase := 65;
        END_IF
        
    65: (* Check disconnect for any errors *)
        IF fbConnection.bError THEN
            nCase := 200; (* continue, but warn user that something happened on disconnect *)
        ELSE
            nCase := 70; (* All clear, connection terminated. *)
        END_IF 

    70: (* File upload completed. *)
        bDone := TRUE;
        nCase := 0;

    200: (* File upload completed but unexpected error on disconnect from server. *)
        bDone := TRUE;
        bError := TRUE;
        sErrorMSG := 'Upload was completed successfully, but received error on disconnect. Check [fbConnection.ipResultMessage] for details.';
        nCase := 0;

    210: (* An error has occured. *)
        bDone := TRUE;
        bError := TRUE;
        sErrorMSG := 'Failed to Upload. Check [fbConnection.ipResultMessage] and [stTransferInfo.eProblem]';
        nCase := 0;

END_CASE

Erklärungen zum Programmablauf

Die State Machine führt beim Start des Programms (Setzen der Variablen bStart auf TRUE) einen Programmablauf durch, welcher zunächst ein Verbindungsprofil erstellt, falls dieses noch nicht existiert. Anschließend wird überprüft, ob schon eine Verbindung zum SFTP-Server existiert. Falls nein, so wird eine Verbindung mit den angegebenen Verbindungsparametern initiiert. Im nächsten Schritt wird der Dateiupload gestartet und die Datei „C:\Temp\myFileUpload.txt'“ auf den SFTP-Server in dessen Rootverzeichnis hochgeladen. Die State Machine springt anschließend sofort einen Schritt weiter und überwacht den Fortschritt des Dateiuploads in regelmäßigen Abständen. Ist der Upload abgeschlossen, so springt die State Machine in den finalen Schritt und trennt die Verbindung mit dem SFTP Server. Anschließend kehrt die State Machine in den initialen Schritt zurück.