FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: crusader am 28 Januar 2016, 22:59:32

Titel: "Remote Debugging" für User-Scripts
Beitrag von: crusader am 28 Januar 2016, 22:59:32
Wer schon mal ein User-Script mit Zugriff auf FHEM-Funktionen/Variablen geschrieben hat, kennt das Problem:

Wenn FHEM nicht gerade auf einem ausgewachsenen PC läuft, ist das Debuggen auf dem Zielsystem wenig komfortabel.
Andererseits erfordert eine Entwicklungsumgebung auf dem PC eine mehr oder weniger aufwändige Portierung des aktuellen Systems.

Wenn man mit dem Script Hardware-Komponenten ansprechen will, die nicht portierbar sind (wie z.B. Raspberry-I2C-Devices), wird das Debuggen endgültig zum 'Try and Error'-Spiel.

Eine einfache Möglichkeit, User-Scripte mit Zugriff auf Zielsystem-Devices in einer komfortablen IDE auf dem PC zu debuggen, besteht darin, FHEM-Funktionen an den laufenden FHEM-Server weiterzureichen.
Das kann z.B. durch Einbinden folgender subs (direkt in der script-Datei oder als eingebundenes Modul) geschehen :
##########################################################
# fhem-Function
sub fhem($)
{
    my ($a) = @_;
    chomp(my $result=`echo '$a' | nc raspberrypi 7072`);
    return $result;
}
##########################################################
# fhem-Evaluation
sub fhemEval($)
{
my ($a) = @_;
    chomp(my $result=`echo '{$a}' | nc raspberrypi 7072`);
    return $result;
}
##########################################################
# Functions used to make fhem-oneliners more readable,
sub InternalVal($$$)
{
my $result = FHEM_fcn('InternalVal',@_);
    return $result;
}

sub ReadingsVal($$$)
{
my $result = FHEM_fcn('ReadingsVal',@_);
    return $result;
}

sub ReadingsNum($$$)
{
my $result = FHEM_fcn('ReadingsNum',@_);
    return $result;
}

sub ReadingsTimestamp($$$)
{
my $result = FHEM_fcn('ReadingsTimestamp',@_);
    return $result;
}

sub Value($)
{
my $result = FHEM_fcn('Value',@_);
    return $result;
}

sub OldValue($)
{
my $result = FHEM_fcn('OldValue',@_);
    return $result;
}

sub OldTimestamp($)
{
my $result = FHEM_fcn('OldTimestamp',@_);
    return $result;
}

sub AttrVal($$$)
{
my $result = FHEM_fcn('AttrVal',@_);
    return $result;
}
########################################################
# Log-Functions
sub Log($$)
{
my $result = FHEM_fcn('Log',@_);
    return $result;
}
sub Log3($$$)
{
my $result = FHEM_fcn('Log3',@_);
    return $result;
}
########################################################
# Function-Wrapper
sub FHEM_fcn($@)
{
my ($fcn,@argv) = @_;

my $fcncall = "$fcn(";
foreach (@argv) {$fcncall .= "\"".$_."\","}
$fcncall =~ s/,+$//;
$fcncall .= ")";

chomp(my $result=`echo '{$fcncall}' | nc raspberrypi 7072`);
return $result;
}


Damit lässt sich sowohl der fhem()-Aufruf als auch der Zugriff auf die gängigsten Perl-Funktionen ohne Änderung am Script debuggen.
Wer auf globale Variablen zugreifen will, muss allerdings die Funktion 'fhemEval' verwenden und beim späteren Portieren auf das Zielsystem wieder entfernen.

Getestet habe ich mit Eclipse/EPIC unter openSuse sowie einer FHEM-5.7-Installation auf einem Raspberry unter Raspbian "Wheezy".
Wer andere Hardware einsetzt, muss ggflls. in den einzelnen subs die IP des Zielrechners anpassen.
Voraussetzung ist natürlich ein offener telnet-Port auf dem Zielrechner.

Viel Spass beim Ausprobieren !