MariaDB Datenbank aus Beckhoff TwinCat3 mit Daten füllen

Wir wollen alle Daten der Sensoren und alle Aktionen über die Beckhoff Steuerung im Haus in einer Datenbank protokollieren. So ist es uns später möglich zu erkennen, welche Aktionen häufig ausgeführt werden und welche eher selten. Außerdem können wir Temperaturkurven für die einzelnen Räume erstellen. Von daher benötigen wir eine einfache Möglichkeit, Daten in eine Datenbank zu schicken. Hierfür setzen wir auf MariaDB, einen Ableger von MySQL.

Anlegen der MariaDB Datenbank

Beim Anlegen der Datenbank gehen wir den einfachen Weg und nutzen die MySQL Workbench. Mit dieser lassen sich ganz einfach Datenbanken und Tabellen anlegen. Da dies eine einmalige Aktion ist, lohnt es sich nicht, dafür etwas im SPS Programm vorzusehen. Dies bedeutet aber auch, dass wir nicht in der Software sicherstellen, dass es die Datenbank wirklich gibt. Für unser Häuschen ist das aber auch nicht notwendig.

Die Datenbank wird hier im Beispiel mit folgenden Daten angelegt:

Datenbankname: sensors
User: myuser
Passwort: mypassword

In dieser Datenbank legen wir eine Tabelle an, die folgende Spalten hat:

sensor    : INT
timestamp : TIMESTAMP
value     : REAL

Als Datenbank Befehl sieht das wir folgt aus:

CREATE SCHEMA `sensors`

CREATE TABLE `sensors`.`sensing_values` (
  `sensor` INT NOT NULL,
  `timestamp` TIMESTAMP NOT NULL,
  `value` REAL NOT NULL);

Jetzt muss sichergestellt werden, dass auch von Remote auf die Datenbank zugegriffen werden kann. Dazu muss die Konfiguration unter /etc/mysql/my.cnf folgendes eingetragen werden:

bind-address = 0.0.0.0

Danach muss der MariaDB Service neu gestartet werden:

sudo /etc/init.d/mysql restart

Einrichtung der MariaDB Datenbank in der Beckhoff Steuerung

Für TwinCAT 3 gibt es von Beckhoff das „TF6420 TC3 Database Server“ Supplement für Datenbankzugriffe. Damit wir in der SPS auf die Datenbank zugreifen können, muss die Datenbank erst einmal eingerichtet werden. Nach der Installation des Supplements gibt es ein Extra Tool unter C:\TwinCAT\Functions\TF6420-Database-Server\Win32\Configurator, in dem man die Datenbanken verwalten kann. Hier werden die Daten eingetragen.

Hier wird unter Edit – NewDBConnection die neue Datenbank Verbindung angelegt.

Konfiguration der Datenbank

Danach muss die Datenbank zum Datenbank-Pool hinzugefügt werden. Dazu einen Rechtsklick auf den Namen ServerDB in der linken Box und „Add to DB  Configuration Pool“ auswählen. Die Datenbank taucht dann unten rechts in der Box auf.

Als nächstes muss die Datenbank in das eigentliche Projekt eingebunden werden. Dazu wählen wir als erstes die Toolbar „TwinCAT Database Server“ (unter View-Toolbars) aus. Jetzt kann die Datenbank eingebunden werden. Die Datenbank taucht im Datenbank Pool auf, die man mit folgendem Icon aufrufen kann:

Datenbank Menu in TwinCat XAE

Hier findet man dann die Datenbank.

Senden von Daten an die Datenbank

Für das Senden von Daten an die Datenbank verwenden wir den SPS Baustein „FB_SQLDatabase“ und „FB_SQLCommand“. Das Ganze wird in einer Klasse gekapselt, so dass von außen nur neue Daten hinzugefügt werden müssen.

VAR
    nWriteState : DBWriterState;

    _buffers: ARRAY[0..1] OF ARRAY[0..lengthOfBuffer-1] OF DBSensorData;
    _actBufferNumber : INT := 0;
    _actPos: INT := 0;
  
    fbSQLDatabase: FB_SQLDatabase(sNetID:=ip, tTimeout:=T#10S);
    fbSQLCommand: FB_SQLCommand(sNetID:=ip, tTimeout:=T#10S);
    nDBID: UDINT := 1;
END_VAR
VAR CONSTANT
    ip : T_AmsNetID := '';
    lengthOfBuffer : INT := 20;
END_VAR

Dabei wird bei jedem Aufruf der Klasse die Update Funktion aufgerufen:

Update();

So kann im Hauptprogramm einfach das Update der DB in jedem Zyklus gestartet werden. Die Update Funktion ruft einfach nur die Funktion „WriteToDatabase“ Funktion auf.

METHOD WriteToDatabase : BOOL
VAR_INPUT
  nBufferID : INT := -1;
END_VAR
VAR_STAT
  actBuffer : POINTER TO ARRAY[0..lengthOfBuffer-1] OF DBSensorData;

  insertdata : STRING[65 + 35 * lengthOfBuffer];
  insertLength : UDINT := 0;	
END_VAR

IF nBufferID >= 0 THEN
  actBuffer := ADR(_buffers[nBufferId]);
END_IF;
CASE nWriteState OF
  DBWriterState.waiting:(*Idle*)
    IF nBufferID >= 0 THEN
      nWriteState := DBWriterState.openDB;
    END_IF

  DBWriterState.openDB: // Connect to database
    IF NOT fbSQLDatabase.Connect(hDBID:= nDBID) THEN
      IF LogError(fbSQLDatabase.ipTcResultEvent) THEN
        nWriteState := DBWriterState.closeDBStep1;
      END_IF
    ELSE
      nWriteState := DBWriterState.openDBWait;
    END_IF
 	DBWriterState.openDBWait:
    fbSQLDatabase();
    IF NOT fbSQLDatabase.bBusy THEN
      IF LogError(fbSQLDatabase.ipTcResultEvent) THEN
        nWriteState := DBWriterState.closeDBStep1;
      ELSE
        fbSQLDatabase.CreateCmd(ADR(fbSQLCommand));
        nWriteState := DBWriterState.prepareWriteDB;
      END_IF
    END_IF

  DBWriterState.prepareWriteDB:
    BuildInsertCommand(buffer := actBuffer, insertCommand => insertdata, length => insertLength );
    nWriteState := DBWriterState.writeDB;

  DBWriterState.writeDB: 
    IF NOT fbSQLCommand.Execute(ADR(insertdata), insertlength) THEN
      IF LogError(fbSQLCommand.ipTcResultEvent) THEN
        nWriteState := DBWriterState.closeDBStep1;	
      END_IF	
    ELSE
      nWriteState := DBWriterState.writeDBWait;
    END_IF

  DBWriterState.writeDBWait:
    fbSQLCommand();
    IF NOT fbSQLCommand.bBusy THEN
      IF LogError(fbSQLCommand.ipTcResultEvent) THEN
        nWriteState := DBWriterState.writeDB;
      END_IF
      nWriteState := DBWriterState.closeDBStep1;
    END_IF

  DBWriterState.closeDBStep1:
    IF NOT fbSQLDatabase.Disconnect() THEN
      IF LogError(fbSQLDatabase.ipTcResultEvent) THEN
        nWriteState := DBWriterState.openDB;
      END_IF			
    ELSE
      nWriteState := DBWriterState.closeDBStep2;
    END_IF	

  DBWriterState.closeDBStep2:
    fbSQLDatabase();
    IF NOT fbSQLDatabase.bBusy THEN
      nWriteState := DBWriterState.waiting;
    END_IF
END_CASE

Einbinden der Tabellen in Django

Jetzt haben wir die Daten in der Datenbank. Überprüfen kann man sie direkt per SQL:

SELECT * FROM sensing_values;

So helfen sie uns gerade aber nicht sehr viel. Wir wollen die Daten in unserer Visualisierung auch darstellen können. Dazu brauchen wir eine einfacher Möglichkeit auf unsere Tabelle zuzugreifen. Hier bietet Django mit seinen Models eine einfache Möglichkeit. Wir tragen hier die Datenbank ein und können sie dann über die normalen Models Funktionen verwenden.

Damit wir auf unsere Datenbank zugreifen können, müssen wir sie erstmal in den Settings als Datenbank eintragen. Hier nutzen wir aus, dass MariaDB und MySQL sich sehr ähneln.

DATABASES = {
  'default': {
     'ENGINE': 'django.db.backends.mysql',
     'USER': 'myuser',
     'PASSWORD': 'mypassword',
     'NAME': 'sensors',
     'sql_mode': 'STRICT_ALL_TABLES',
     'OPTIONS': {
        'charset': 'latin1',
        'use_unicode': 'True', 
     },
  },    
}

In der entsprechenden models.py wird jetzt die Datenbank eingebunden:

class SensingValue(models.Model):
    sensor = models.IntegerField(primary_key=True, editable=False)
    timestamp = models.DateTimeField(primary_key=True, editable=False)
    value = models.FloatField(editable=False)
    
    class Meta:
        db_table = 'sensing_values'
        managed = False

Jetzt kann direkt auf die Daten zugegriffen werden, um sie zum Beispiel in der Oberfläche anzuzeigen. Hier werden alle Daten des Sensors mit der ID id ausgelesen, die zwischen since und now liegen.

values = SensingValue.objects.filter(sensor=id, timestamp__lte = now, timestamp__gte = since)

Mit den Standard Django Funktionen lassen sich nun weitere Funktionen und passende Datenbanken zur Verwaltung hinzufügen.

3 Antworten auf „MariaDB Datenbank aus Beckhoff TwinCat3 mit Daten füllen“

  1. Hi,
    i tried several time to startup MySql connection through TF6420 but every time i check the connection i retrive this message
    „Configuration check failed SQLState_HY000 General error“. Any suggestions?
    I tried with firebird databese and works, but i would like to use MySql.
    Thx

    TF6420 version 3.2.32.2
    MySql version 8.0.17
    TwinCAT version 3.1.4022.22

    1. Hi Michele,

      sorry, I never had this message. Can you connect from the PC to the MySQL database using another client? Perhaps your firewall is the error source.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.