FHEM Datenaustausch mit SPS S7-315 über UDP

Begonnen von ToVo, 12 Mai 2014, 22:17:02

Vorheriges Thema - Nächstes Thema

ToVo

Hallo,

ich suche eine Möglichkeit Daten via UDP Protokoll von einer SPS in Richtung FHEM und zurück zu senden. Mit meinem PC und einem kleinen Perl Script (UDP_Server) funktioniert das wunderbar.
Mein Problem ist nun die Einbindung des Scripts in FHEM.


probiert habe ich bis jetzt:

# Button sps schalten
define btn_SPS dummy
attr btn_SPS room SPS
attr btn_SPS webCmd on:off

define not_SPS notify btn_SPS { if (Value("btn_SPS") eq "on"){SPS_COMM("Ein")} else {SPS_COMM("Aus")}}


Eine 99_myUtils angelegt mit folgendem Inhalt:

package main;
use strict;
use warnings;
use POSIX;
sub
myUtils_Initialize($$)
{
my ($hash) = @_;
}
sub
SPS_COMM($) {

#!/usr/bin/perl
#udpserver.pl

use IO::Socket::INET;

# flush after every write
$| = 1;

my ($senddata) = @_;
#my ($received_data);
my ($socket);
#my ($peeraddress);
#my ($peerport);

#  we call IO::Socket::INET->new() to create the UDP Socket and bound
# to specific port number mentioned in LocalPort and there is no need to provide
# LocalAddr explicitly as in TCPServer.
#socket = new IO::Socket::INET (LocalPort => '2000',Proto => 'udp',) or die "ERROR in Socket Creation : $!\n";

$socket = new IO::Socket::INET (PeerAddr => '192.168.178.90:2000',Proto => 'udp') or die "ERROR in Socket Creation : $!\n";

# while(1)
#{

# read operation on the socket
#$socket->recv($recieved_data,1024);

#get the peerhost and peerport at which the recent data received.
#$peer_address = $socket->peerhost();
#$peer_port = $socket->peerport();
#print "\n($peer_address , $peer_port) said : $recieved_data";

$socket->send($data);


#}

$socket->close();

}
1;


Im Logfile steht nicht viel drin.

2014.05.12 22:12:04 5: Cmd: >set btn_SPS on<
2014.05.12 22:12:04 4: dummy set btn_SPS on
2014.05.12 22:12:04 5: Triggering btn_SPS (1 changes)
2014.05.12 22:12:04 5: Notify loop for btn_SPS on
2014.05.12 22:12:04 4: eventTypes: dummy btn_SPS on -> on
2014.05.12 22:12:04 5: Triggering not_SPS
2014.05.12 22:12:04 4: not_SPS exec { if (Value("btn_SPS") eq "on"){SPS_COMM("Ein")} else {SPS_COMM("Aus")}}
2014.05.12 22:12:04 5: Cmd: >{ if (Value("btn_SPS") eq "on"){SPS_COMM("Ein")} else {SPS_COMM("Aus")}}<
2014.05.12 22:12:04 3: not_SPS return value: 1


Was bedeutet: not_SPS return value: 1 ??? In der SPS kommt leider nichts an.

Probiert habe ich auch schon iTach und Listenlive (umgestellt auf UDP) aber leider ohne Erfolg.

Zu meiner Hardware: FHEM läuft auf einem Raspberry <-> Fritzbox 7270 <-> SPS. Port ist in der Fritzbox freigegeben.

Was mache ich verkehrt?Seht ihr noch eine Möglichkeit?

SpenZerX

Hallo,

hast du Erfolg gehabt?

Ich habe ähnliches Problem.

Perl Script mit UDP Transfer läuft auf dem PC gut, auf der Fritzbox im FHEM Modul nicht ...

ToVo

Hallo,

ja funktioniert bei mir wunderbar. Ich kann entweder per TCP oder UDP in beiden Richtungen Telegramm schicken.
Ich nutze UDP weil hier die Daten im Empfangs DB der SPS immer überschrieben werden und ich das damit besser
auswerten kann.

Hier das Script aus meiner 99_myUtils

SPS_COMM($) {

#!/usr/bin/perl
#udpserver.pl

# Sub Script sendet beliebige Daten aus FHEM übergeben mit dem Parameter

use IO::Socket::INET;

# flush after every write
$| = 1;
my ($senddata) = @_;
my ($socket,$recieved_data);
my ($peer_address,$peer_port);
#  we call IO::Socket::INET->new() to create the UDP Socket and bound
# to specific port number mentioned in LocalPort and there is no need to provide
# LocalAddr explicitly as in TCPServer.
$socket = new IO::Socket::INET (
LocalPort => '2020',
Proto => 'udp',
) or die "ERROR in Socket Creation : $!\n";

# read operation on the socket
$socket->recv($recieved_data,1024);

#get the peerhost and peerport at which the recent data received.
$peer_address = $socket->peerhost();
$peer_port = $socket->peerport();


#send the data to the client at which the read/write operations done recently.

$socket->send($senddata);

$socket->close();


in der FHEM Config sende ich dann mit:


{SPS_COMM("HALLO")}


Für den Empfang springe ich per at aller 3 Sekunden in das Receive Script.


define SPS_Recv at +*00:00:03 {SPS_RECV()}
attr SPS_Recv verbose 0


Das Script aus der 99_myUtils sieht dann so aus:



sub
SPS_RECV() {

############# SUB empfängt zyklisch aktuelle Status Daten von der SPS ###############

use IO::Socket::INET;

# flush after every write
$| = 1;

my ($socket,$recieved_data,$Pong,$Alarm);
my ($peer_address,$peer_port);

$socket = new IO::Socket::INET (
LocalPort => '2020',
Proto => 'udp',
) or die "ERROR in Socket Creation : $!\n";

# read operation on the socket
$socket->recv($recieved_data,1024);

# SPS Daten lesen und in Dummy RECV schreiben

{fhem ("set RECV ".$recieved_data)};

# Teil Strings erzeugen

# Ping/Pong Lifebit
$Pong = substr ($recieved_data,0,4);
{fhem ("set RECV_Pong ".$Pong)};

# Alarm ON/OFF
$Alarm = substr ($recieved_data,4,4);
{fhem ("set RECV_Alarm ".$Alarm)};



$socket->close();



Ich ziehe aus dem Gesamt String die Daten raus und übergebe sie direkt an FHEM Dummys.


50er

Hey,

super Sache....  ;D

wäre das nicht etwas fürs WIKI...

Grüße
50er

Jiml

Hi ToVo,

ich bin gerade dran Daten vom 1-Wire Controller 2 von ESERA (eservice-online.de) https://www.eservice-online.de/shop/e-service-1-wire-bus/controller-gateway-intelligente-schnittstellen/374/controller-2-ethernet-1-wire-und-i/o , welche per UDP auf den Miniserver gepusht werden, zu verarbeiten.
Habe mal Dein Ablauf zur Vorlage genommen, leider ohne Erfolg.  :(

Was ist an meinen Daten anderst als an Deinen von der SPS?

Wie verarbeitst Du die Daten in fehm.cfg? per Dummy und ReadingsVal?

Meine Daten sind alle 10s ein Block von ca. 20 Zeilen mit cr und lf am Ende