WinCC

It is possible to transmit signals to Databoom using platforms to supervise and industrial control making use of HMI/Scada software technology, like WinCC.

Data forwarding is implemented through the writing of a VBScript.

Requirements

To run the script correctly, you need curl. It is possible to check its installation by running the command in a command line. If it is not present in your system, get the installer at the download page of th cURL site.

VBScript

The script consists of two parts:

  • Loop, deals with the cyclic execution of the script
  • Handlers, handles errors, if any, while running
Loop
 
Sub PostDataboom
    Dim prev, apiClock, apiPost, apiKey, curl, curlGet, jsonEmpty

    'File di log per tutte le variabili
    Dim logs<SIGNAL 1>
    Dim logs<SIGNAL 2>

    Dim logError 'memorizza tutti gli errori
    Dim logBulk 'memorizza il post prima dell'inoltro in caso di bulk
    Dim resultPost 'memorizza temporaneamente la risposta delle post request
    Dim resultDate 'memorizza temporaneamente la risposta delle date request
    Dim resultBulk 'memorizza temporaneamente la risposta delle bulk request
    
    prev = -1
    apiClock = "https://api.databoom.com/v1/auth/gmtclock/plain"    
    apiPost = "https://api.databoom.com/v1/signals/push"
    apiKey = "<API KEY DATABOOM>"
    curl = "cmd /C <PATH COMPLETO>\curl.exe --header ""apikey: " & apiKey & """" & " --header ""Content-Type: application/json"" -X POST -d """
   curlGet = "cmd /C <PATH COMPLETO>\curl.exe -X GET "
    jsonEmpty = "{\""MSG\"":\""OK\""}"

    'Definisco i percorsi dei file di log
    logs<SIGNAL 1> = "<PATH COMPLETO>\<SIGNAL 1>.txt"
    logs<SIGNAL 2> = "<PATH COMPLETO>\<SIGNAL 2>.txt"

    logError = "<PATH COMPLETO>\ERRORS.txt"
    logBulk = "<PATH COMPLETO>\bulkToPost.txt"
    resultPost = "<PATH COMPLETO>\resultPost.txt"
    resultDate = "<PATH COMPLETO>\resultDate.txt"
    resultBulk = "<PATH COMPLETO>\resultBulk.txt"
    
    Do While True    
        If (Minute(Now) <> prev) And (Minute(Now) Mod 5 = 0) Then    
            Dim sDate, postResult, bulkResult, JSONString, canConn, FSO, TS
            Const ForReading = 1, ForWriting = 2, ForAppending = 8
            Set FSO = CreateObject("Scripting.FileSystemObject")
            'Verifica la presenza dei file di log, li genera se non li trova
            On Error Resume Next
                Set TS = FSO.OpenTextFile(logs<SIGNAL 1>, ForAppending, True)
                TS.Close
                Set TS = FSO.OpenTextFile(logs<SIGNAL 2>, ForAppending, True)
                TS.Close             
            If Err.Number <> 0 Then
                storeError logError, Err, "Can't create log file"
                Err.Clear
            End If
                            
            canConn = True    
            sDate = ""
            postResult = ""
            bulkResult = ""
            
            Dim objWshShell, result
            Set objWshShell = CreateObject("Wscript.Shell")
                    
            On Error Resume Next    
                objWshShell.run curlGet & apiClock & "  > " & resultDate, 0, True
            If Err.Number <> 0 Then
                storeError logError, Err, "Can't curl date"
                Err.Clear
            End If         
            
            Set result = FSO.OpenTextFile(resultDate, ForReading)
            sDate = result.ReadAll
            result.Close    
            
            If Len(sDate) <> 21 Then
                HandleDateRequest canConn,sDate                
                Set TS = FSO.OpenTextFile(logError, ForAppending)
                TS.Write ((Year(Now)*100 + Month(Now))*100 + Day(Now))*10000 + Hour(Now)*100 + Minute(Now) & " - ERROR: Can't retrieve date" & vbCrLf
                TS.Close
            End If                    
            
            'Definisco le variabili per la lettura dei dati
            Dim <SIGNAL 1>
            Dim <SIGNAL 2>

            'Assegno alle variabili quelle di WinCC
            Set <SIGNAL 1> = HMIRuntime.Tags("<SIGNAL 1>")
            Set <SIGNAL 2> = HMIRuntime.Tags("<SIGNAL 2>")

            JSONString = "{\""device\"":\""<DEVICE TOKEN>\"",\""date\"":\""" & sDate & "\"", \""signals\"":["
            JSONString = JSONString & "{\""name\"":\""<SIGNAL 1>\"",\""value\"":"& Replace(pressioneCondottaForzata.Read(1),",",".") & "},"
            JSONString = JSONString & "{\""name\"":\""<SIGNAL 2>\"",\""value\"":"& Replace(portataCondotta.Read(1),",",".") & "}"
            JSONString = JSONString & "]}"
            
            On Error Resume Next
                objWshShell.run curl & JSONString & """ " & apiPost & "  > " & resultPost, 0, True
            If Err.Number <> 0 Then
                storeError logError, Err, "Can't curl post, " & JSONString
                Err.Clear
            End If         
            
            Set result = FSO.OpenTextFile(resultPost, ForReading)
            postResult = result.ReadAll
            result.Close    
            
            If postResult <> "{""message"":""ALL_INFO_PROCESSED""}" Then
                HandleFailedPost canConn, FSO, TS, sDate, Replace(<SIGNAL 1>.Read(1),",","."), logs<SIGNAL 1>
                HandleFailedPost canConn, FSO, TS, sDate, Replace(<SIGNAL 2>.Read(1),",","."), logs<SIGNAL 2>
            
                Set TS = FSO.OpenTextFile(logError, ForAppending)
                TS.Write ((Year(Now)*100 + Month(Now))*100 + Day(Now))*10000 + Hour(Now)*100 + Minute(Now) & " - ERROR: Can't send post " & postResult & vbCrLf
                TS.Close
            End If                    
            
            If canConn = True Then
                Dim bulk, emptyBulk
                emptyBulk = True
                bulk = "{""device"":""<DEVICE TOKEN>"",""Date"":""" & sDate & """, ""signals"":{"

                'Per ogni segnale aggiungo i dati raccolti nei rispettivi bulk
                  bulk = bulk & " ""<SIGNAL 1>"" : {""description"":""<SIGNAL 1>"", ""history"":["
                  addHistory logs<SIGNAL 1>, bulk                 
                If StrComp(Right(bulk, 1),",") = 0 Then
                    bulk = Left(bulk, Len(bulk) - 1) & "]},"
                    emptyBulk = False
                Else
                    bulk = bulk & "]},"
                End If

                bulk = bulk & " ""<SIGNAL 2>"" : {""description"":""<SIGNAL 2>"", ""history"":["
                  addHistory logs<SIGNAL 2>, bulk                 
                If StrComp(Right(bulk, 1),",") = 0 Then
                    bulk = Left(bulk, Len(bulk) - 1) & "]}}}"
                    emptyBulk = False
                Else
                    bulk = bulk & "]}}}"
                End If                                        

                  If emptyBulk = False Then    
                      On Error Resume Next
                          Set TS = FSO.OpenTextFile(logBulk, ForWriting)
                        TS.Write bulk
                        TS.Close                                        
                      If Err.Number <> 0 Then
                        storeError logError, Err, "Can't log bulk"
                        Err.Clear
                    End If         
                        
                      On Error Resume Next                          
                          objWshShell.run curl & "@" & logBulk & """ " & apiPost & "  > " & resultBulk, 0, True                                 
                      If Err.Number <> 0 Then
                        storeError logError, Err, "Can't run bulk curl"
                        Err.Clear
                    End If         
                                  
                    Set result = FSO.OpenTextFile(resultBulk, ForReading)
                    bulkResult = result.ReadAll
                    result.Close    
                    
                    If bulkResult <> "{""message"":""ALL_INFO_PROCESSED""}" Then    
                        HandleFailedConn canConn        
                        Set TS = FSO.OpenTextFile(logError, ForAppending)
                        TS.Write ((Year(Now)*100 + Month(Now))*100 + Day(Now))*10000 + Hour(Now)*100 + Minute(Now) & " - ERROR: Can't send bulk " & bulkResult & vbCrLf & bulk & vbCrLf
                        TS.Close
                    End If

                       If canConn = True Then
                        cleanHistory logs<SIGNAL 1>
                        cleanHistory logs<SIGNAL 2>
                       End If
                  End If
             End If
        
            FSO.DeleteFile(logBulk)
            FSO.DeleteFile(resultPost)
            FSO.DeleteFile(resultDate)
            FSO.DeleteFile(resultBulk)
            
            Set TS = Nothing
            Set FSO = Nothing
            prev = Minute(Now)
        End If    
    Loop    
End Sub
 
logs<SIGNAL 1> and logs<SIGNAL 2> are the logging files, the files are created if they don't exist. The directories specified with their full path <FULL PATH> must be existing.
 
WARNING! Make sure the directories are existing or the script will not be able to create files and work correctly.

The example has two tags, you can add more by following the same procedure.

WARNING! When adding new variables, always check closing parenthesis. Last variable must not have commas at the end, as the <Signal 2> in the example, while other variables must mirror <Signal 1>.

Handlers
 
Const ForReading = 1, ForWriting = 2, ForAppending = 8

Sub    HandleFailedConn(Byref canConn)
    canConn = False
End Sub

Sub HandleDateRequest(Byref canConn, Byref sDate)
    canConn = False    
    sDate = Year(Date) & "-" & Right(String(2, "0") & Month(Date), 2) & "-" & Right(String(2, "0") & Day(Date), 2) & "T" & Right(String(2, "0") & Hour(Now), 2) & ":" & Right(String(2, "0") & Minute(Now), 2) & ":" & Right(String(2, "0") & Second (Now), 2)
End Sub

Sub HandleFailedPost(Byref canConn, Byref FSO, Byref TS, Byval sDate, Byval variable, Byval logsVariable)
    canConn = False

    Set TS = FSO.OpenTextFile(logsVariable, ForAppending, True)
    TS.Write "{""date"":"""& sDate &""",""value"":"& variable &"}" & vbCrLf
    TS.Close

    JSONString = ""
End Sub

Sub addHistory(ByVal logFile, ByRef bulk)
  Dim FSO, TS
  Set FSO = CreateObject("Scripting.FileSystemObject")
  Set TS = FSO.OpenTextFile(logFile, ForReading)
  Do Until TS.AtEndOfStream
   bulk = bulk & TS.ReadLine & ","
  Loop
  TS.Close
End Sub

Sub cleanHistory(ByVal logFile)
  Dim FSO, TS
  Set FSO = CreateObject("Scripting.FileSystemObject")
  Set TS = FSO.OpenTextFile(logFile, ForWriting, True)
  TS.Write ""
  TS.Close
End Sub

Sub storeError(Byval logError, Byref Err, Byval errExtra)
  Dim FSO, TS
  Set FSO = CreateObject("Scripting.FileSystemObject")
  Set TS = FSO.OpenTextFile(logError, ForAppending, True)
  TS.Write ((Year(Now)*100 + Month(Now))*100 + Day(Now))*10000 + Hour(Now)*100 + Minute(Now) & " - Error: [" & Err.Number &  ", "& Err.Source &", "& Err.Description & "] "& errExtra & vbCrLf
  TS.Close
End Sub 

Script execution

Once the scripts are ready in WinCC, you can start recording data in Databoom.
One possible approach is to call the main function when opening the main window of your project.

Open the Graphics Designer functionality from the side menu and access the main windows, <NAME>.PDL. Click the right mouse button on the base level and choose the Properties menu. Go on the Event tab and set a VBS action.

Azione VBS

The action to write is:

Sub OnOpen()
 PostDataboom
End Sub

Configuration completed!

Once the procedure has been completed, Databoom starts to record data sent from WinCC. To examine your data and have a correct representation, follow the instructions in Edit/validation of a signal.

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.