# WAGO lib für Heizungsanlage?



## spec (18 Februar 2015)

Hallo SPS'er,

ich programmiere zurzeit eine Heizungsanlage mit Wago 880 und brauche eine gute lib. 
Die  Anlage hat jeweils Vor- und Rücklauf für Büros, Halle1 und Halle2. Die  drei Vorlauf sowie Rücklauf haben jeweils ein PT100 für Temperatur  messung. Büros und Halle2 haben jeweils ein Mischer der mit Hilfe eines  PID Regler geregelt werden sollen. Die Mischer werden nicht Analog  gesteuert sondern über Digitale Ausgänge. Heißt ein Ausgang für  Mischer_AUF ein für Mischer_ZU. Dazu gibt es noch ein PT100 für  Außentemperatur und ein für Kessel Temperatur sowie drei Pumpen für  Büro, Halle1 und Halle2. Die Anlage wird Visualisiert und die Visu zeigt  wie weit die Mischer geöffnet sind. 

Es können auch gerne andere libs vorgeschlagen werden.

mfg


----------



## GLT (19 Februar 2015)

Entweder die HLK-Libs von Wago oder die Oscat.lib.


----------



## amos (19 Februar 2015)

Den Part für die Messdatenerfassung poste ich hier mal:

http://web1.heissa.de/heizung4.png
bis
http://web1.heissa.de/heizung48.png

mit den 4 Analog Input Ports messe ich 8 PT1000, hierfür benötigt man 4 Stück 24V Relais als Multiplexer.

PROGRAM mysql_prg
VAR RETAIN
      cnt_strom: DINT;
      cnt_oel1: DINT;
      cnt_oel2: DINT;
END_VAR
VAR
      xDoIt : BOOL;
      analog0 AT %IW0: WORD;
      analog1 AT %IW1: WORD;
      analog2 AT %IW2: WORD;
      analog3 AT %IW3: WORD;
      analog0_int    :  INT;
      analog1_int    :  INT;
      analog2_int    :  INT;
      analog3_int    :  INT;
      temp0_int : INT := 0;
      temp4_int : INT := 0;
      cnt_stom_yes: BOOL;
      cnt_oel1_yes:BOOL;
      cnt_oel2_yes:BOOL;
      delta1c : REAL := 22;
      temp0c : INT := 7268;
      temp_real : REAL;
      Output_0 AT %QX0.0: BOOL;
       Input_10 AT %IW4 :WORD;
       Input10: INT;
       in0 AT %IX4.0: BOOL;
       in8 AT %IX4.8: BOOL;
       in9 AT %IX4.9: BOOL;
       i : INT;
       Timer_temp_fuehler:TON;
       rtrigg_out0 : R_TRIG;
       rtr2: R_TRIG;
       rtr8: R_TRIG;
       rtr9: R_TRIG;
      wState : WORD; (* Statemachine*)
    oMySql : MySql_Context; (* Used like Structure for keeping login and status information - Do not call it with in your program *)
    (* Functionblock to contact MySql server *)
    oMySqlLogin : MySql_Login;

       sHost0 : STRING := '192.168.178.162';
    uiPort : UINT := 3306;
    sUser : STRING := 'wag';
    sPwd : STRING := '12345';
    sDB : STRING := 'wagodb';       (* Optional - Name of database instance to connect to *)
    xConnect : BOOL;
    diErrorLogin : DINT;
    sStatusLogin : STRING(500);
    xConnected : BOOL;
    (* Functionblock to process SQL statements who do not return result sets *)
    oMySqlExec1 : MySql_Execute;
    asSqlStatement1 : ARRAY [0..gcMySql_iSqlUpperBound] OF STRING(gcMySql_iSqlLength);
    xExec1 : BOOL;
    diErrorExec1 : DINT;
    sStatusExec1 : STRING(500);
    (* Functionblock to process SQL statements who return result sets *)
    oMySqlQuery1 : MySql_Query;
    asSqlQuery1 : ARRAY [0..gcMySql_iSqlUpperBound] OF STRING(gcMySql_iSqlLength);
    xQuery1 : BOOL;
    diErrorQuery1 : DINT;
    sStatusQuery1 : STRING(500);
    stQueryResult1 : MySql_ResultSet;
    (* Convert "stQueryResult" to IEC *)
    stTableData : TableData;
    row, col : INT;
    sValue: STRING(500); (* Returns the value of requested row and col as STRING *)
    dwResult: DWORD; (* Error code of function "MySql_Convert2IEC() *)
    xConvertError : BOOL;
    (* Functionblock to disconnect MySql server *)
    oMySqlLogout : MySql_Logout;
    xDisconnect : BOOL;
    diErrorLogout : DINT;
    sStatusLogout : STRING(500);
    (* Helpers *)
    iHelp : INT;
    cnt_strom_yes: BOOL;
END_VAR


IF Output_0
   THEN  Timer_temp_fuehler.PT:=t#30s; (*on*)
   ELSE  Timer_temp_fuehler.PT:=t#30s; (*off*)
   analog0_int:=WORD_TO_INT(analog0);
   analog1_int:=WORD_TO_INT(analog1);
   analog2_int:=WORD_TO_INT(analog2);
   analog3_int:=WORD_TO_INT(analog3);
END_IF;
rtr2(CLK:=in0);
rtr8(CLK:=in8);
rtr9(CLK:=in9);
cnt_strom_yes := rtr2.Q;
cnt_oel1_yes := rtr8.Q;
cnt_oel2_yes := rtr9.Q;
input10 := input_10;
IF input10 >767 THEN input10 :=input10-768; END_IF;
IF input10 >255 AND input10 < 768 THEN input10 :=input10-256; END_IF;
IF cnt_strom_yes THEN cnt_strom:= cnt_strom+1; END_IF;
IF cnt_oel1_yes THEN cnt_oel1:= cnt_oel1+1; END_IF;
IF cnt_oel2_yes THEN cnt_oel2:= cnt_oel2+1; END_IF;
delta1c := 65.4;
temp_real := (analog2-7266)/delta1c;
Timer_temp_fuehler(IN:=NOT Timer_temp_fuehler.Q);
Output_0 := Output_0 XOR Timer_temp_fuehler.Q;
rtrigg_out0(CLK:= Output_0);
xDoit := rtrigg_out0.Q;
(* Call function block "MySql_Login" every cycle to monitor connection status *)
oMySqlLogin(sHost:= sHost0,
            uiPort:= uiPort,
            sUsername:= sUser,
            sPassword:= sPwd,
            sDatabase:= sDB,
            oMySql:= oMySql,
            xStart:= xConnect,
            diError=> diErrorLogin,
            sStatus=> sStatusLogin,
            xConnected=> xConnected);
CASE wState OF
0: (* Idle - Wait for something to do *)
    IF xDoIt THEN
         (* Clear old data *)
        stTableData.xValid := FALSE;
        stTableData.iRowCount := 0;
        FOR row:=1 TO mysql_prg.MAX_ROWS DO
            stTableData.astRow[row].iId       := -1;
            stTableData.astRow[row].xBool     := FALSE;
            stTableData.astRow[row].bByte     := 0;
            stTableData.astRow[row].wWord     := 0;
            stTableData.astRow[row].diDint    := 0;
            stTableData.astRow[row].rReal     := 0.0;
            stTableData.astRow[row].sString := '';
            stTableData.astRow[row].dtDt      := dt#1970-01-01-00:00:00;
            stTableData.astRow[row].todTod     := tod#00:00:01;
            stTableData.astRow[row].udiUdint:= 0;
        END_FOR
        (* Connect to database *)
        xConnect := TRUE;
        wState := 10;
    END_IF
10: (* Wait until database connection is established *)
    IF xConnected THEN
        wState := 20;
    END_IF
20: (* Prepare SQL-Insert-Statement *)
       asSqlStatement1[0] := 'INSERT INTO heizung ( F1,S1,DT,I1,I2,I3,I4,I5,I6,i7,i8,i9,i10,i11,i12) values (';
    asSqlStatement1[1] := '1.2,$'B$',now(),';
       asSqlStatement1[2] := WORD_TO_STRING(input10);
       asSqlStatement1[3] := ',';
       asSqlStatement1[4] := DINT_TO_STRING(cnt_strom);
       asSqlStatement1[5] := ',';
       asSqlStatement1[6] := DINT_TO_STRING(cnt_oel1);
       asSqlStatement1[7] := ',';
       asSqlStatement1[8] := DINT_TO_STRING(cnt_oel2);
       asSqlStatement1[9] := ',';
       asSqlStatement1[10] := WORD_TO_STRING(analog0);
       asSqlStatement1[11] := ',';
       asSqlStatement1[12] := WORD_TO_STRING(analog1);
       asSqlStatement1[13] := ',';
       asSqlStatement1[14] := WORD_TO_STRING(analog2);
       asSqlStatement1[15] := ',';
       asSqlStatement1[16] := WORD_TO_STRING(analog3);
       asSqlStatement1[17] := ',';
       asSqlStatement1[18] := INT_TO_STRING(analog0_int);
       asSqlStatement1[19] := ',';
       asSqlStatement1[20] := INT_TO_STRING(analog1_int);
       asSqlStatement1[21]:= ',';
       asSqlStatement1[22]:= INT_TO_STRING(analog2_int);
       asSqlStatement1[23]:= ',';
       asSqlStatement1[24]:= INT_TO_STRING(analog3_int);
    asSqlStatement1[25] := ')';

      xExec1 := TRUE; (* Execute SQL-Insert-Statement *)
    wState := 25;
25: (* Wait until SQL-Insert-Statement are processed *)
    oMySqlExec1( asSqlCommand:= asSqlStatement1,
                 oMySql:= oMySql,
                 xStart:= xExec1,
                 diError=> diErrorExec1,
                 sStatus=> sStatusExec1);
    IF NOT xExec1 THEN
        IF diErrorExec1 = 0 THEN
            wState := 30;
        END_IF
    END_IF
30: (* Prepare SQL-Select-Statement *)
    asSqlQuery1[0] := 'SELECT * FROM atable';
    asSqlQuery1[1] := ''; (* End of SQL-Statement *)
    xQuery1 := TRUE;
    wState := 35;
35: (* Wait until SQL-Select-Statement are processed *)
    oMySqlQuery1( asSqlCommand:= asSqlQuery1,
                  oMySql:= oMySql,
                  xStart:= xQuery1,
                  stResultSet:= stQueryResult1,
                  diError=> diErrorQuery1,
                  sStatus=> sStatusQuery1);
    IF NOT xQuery1 THEN
        IF diErrorQuery1 = 16#00000000 THEN
            xConvertError := FALSE; (* Reset merker *)
            wState := 40;
        END_IF
    END_IF
40: (* Convert query result set into user defined data type "TableData" *)
    stTableData.iRowCount := stQueryResult1.uiRowCount;
    FOR row:=1 TO stTableData.iRowCount DO
        IF row >= MAX_ROWS THEN
            EXIT; (* ERROR: astTableData is to small *)
        END_IF
        (* Convert table field "id" - MySql_Datatype "tinyint(1)" *)
        dwResult := MySql_GetStringValue( row, 1, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].iId := STRING_TO_INT(sValue);
              ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aBool"     - MySql_Datatype "tinyint(1)" *)
        dwResult := MySql_GetStringValue( row, 2, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            iHelp := STRING_TO_INT(sValue);
            IF iHelp = 0 THEN
                stTableData.astRow[row].xBool :=  FALSE;
            ELSE
                stTableData.astRow[row].xBool :=  TRUE;
            END_IF
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aByte"     - MySql_Datatype "smallint(6)" *)
        dwResult := MySql_GetStringValue(row, 3, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].bByte := STRING_TO_BYTE(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aWord"     - MySql_Datatype "int(11)" *)
        dwResult := MySql_GetStringValue(row, 4, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].wWord := STRING_TO_WORD(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aDint"     - MySql_Datatype "bigint(20)" *)
        dwResult := MySql_GetStringValue(row, 5, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].diDint := STRING_TO_DINT(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aReal"     - MySql_Datatype "float"  *)
        dwResult := MySql_GetStringValue(row, 6, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].rReal := STRING_TO_REAL(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aString"- MySql_Datatype "varchar(25)" *)
        dwResult := MySql_GetStringValue(row, 7, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].sString := sValue;
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aDT" - MySql_Datatype "datetime" *)
        dwResult := MySql_GetStringValue(row, 8, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].dtDt := STRING_TO_DT(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aTime"     - MySql_Datatype "time"  *)
        dwResult := MySql_GetStringValue(row, 9, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].todTod := STRING_TO_TOD(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
        (* Convert table field "aUdint" - MySql_Datatype "bigint(20) unsigned" *)
        dwResult := MySql_GetStringValue(row, 10, stQueryResult1, sValue);
        IF dwResult = 16#00000000 THEN
            stTableData.astRow[row].udiUdint := STRING_TO_UDINT(sValue);
        ELSE
            xConvertError := TRUE;
            EXIT;
        END_IF
    END_FOR
    IF xConvertError THEN
        wState:=45;
    ELSE
        stTableData.xValid := TRUE;
        (* Disconnect from database *)
        xDisconnect := TRUE;
        wState:=50;
    END_IF
45: (* Wait here to debug convert problem *)
    ;
50: (* Disconnect from database *)
    oMySqlLogout(oMySql:= oMySql,
                 xStart:= xDisconnect,
                 diError=> diErrorLogout,
                 sStatus=> sStatusLogout);
    IF NOT xDisconnect THEN
        xDoIt := FALSE;
        wState := 0;
    END_IF
END_CASE


----------



## .:WAGOsupport:. (24 Februar 2015)

Hallo,

also insoweit schon richtig, dass Wago Bibliotheken zur Verfügung Stellt.
Wago bietet dir, die HLK Makros die häufig angewandte und verschiedene Lösungsvorschläge beinhaltet.
Für dich wäre treffend das „Heizkreis_Makro_01“.

Die gesamten HLK-Makros kannst du unter folgender Seite herunter laden:

http://www.wago.de/suche/index.jsp?...dium=forum&utm_content=sps-forum&utm_term=APN

Zudem benötigst du die „HVAC_03.lib“ welche die Basisfunktionen mitliefert. Zu finden auf folgender Seite (benötigt 00_Libraries_BA.zip):

http://www.wago.de/suche/index.jsp?...dium=forum&utm_content=sps-forum&utm_term=LIB 


Der Makro-File, sowie die Gebäudebibliotheken beinhalten verschiedene „Exportdateien“.
Für deine Anwendung importierst du die Exportdatei der „HVAC_03.lib“in dein Projekt, welche die Basisvisualisierungsobjekte mitliefert. Zudem importierst du die Exportdatei des z.B. „Heizkreis_Makro_01“.

Somit hast du erst mal alles im Projekt was du benötigst.


----------



## wolfi-sps (24 Februar 2015)

Hallo spec,
wir haben vor gut 3 Jahren auch gebaut - habe die ganzen Lib´s von WAGO verwendet - einfach genial.
WAGO hat in der Vergangenheit sehr viele gute Lib´s rausgebracht die das Leben einfach macht.
Habe selber drei Steuerungen und ein PERSPECTO Control-Panel mit 12,1" Target-Visualisierung am start. 
EG, OG, Lüftung, Solar kommt noch.
Anbei zwei Bilder von meinen Verteilungen - vielleicht interessiert es jemand. Wenn nicht - auch nicht so schlim 

Gruss

Wolfi


----------

