Statusabfrage in *.classdef verarbeiten

Begonnen von NeuFehm, 03 Januar 2016, 21:25:20

Vorheriges Thema - Nächstes Thema

NeuFehm

Liebe FHEM/PERL-Freunde,

ich muss in meiner classdef den Status einer "Lampe" (hier LED1) abfragen.
Wenn ich den Status der leuchtenden LED über die Kommandozeile abfrage "getstate LED1",
erhalte ich:
state:1

Da ich nur die "1" brauche, war meine Idee einen Substring zu erzeugen und in der classdef zu verwenden:
my $TLed1 = substr(fhem "getstate LED1",6,1);;\

Aber das erzeugt die Fehlermeldung im log:
myleds: sending command "Not enough arguments for substr at (eval 124) line 1, near "1)"\n"

Der einfache Programm-Gegencheck funktioniert einwandfrei:
my $TLed1 = 1;;\

Hat jemand eine Idee, wie ich eine Statusabfrage in der classdef verwenden kann?
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

NeuFehm

erledigt.
Habe den Code einfach "erweitert":
my $Status = fhem "getstate LED1";;\
my $TLed1 = substr($Status,6,1);;\
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

viegener

Ich würde Dir empfehlen Dich etwas in perl und auch in einige der (normalerweise vor allem für Entwickler relevanten) Dokumente im fhemwiki einzuarbeiten. Eigentlich schreibst Du ja perl-code.

Hintergrund:
- fhem "getstate LED1" ist eigentlich ein Aufruf der Funktion fhem also wäre es besser hier
fhem( "getstate LED1")
- Auf der anderen Seite wird hier ein Kommando zusammengebaut, dass dann in fhem erst wieder mühsam zerlegt und interpretiert werden muss. Wenn Du also bereits auf der perl-Ebene bist, wäre ein Aufruf der Funktion ReadingsVal() einfacher.
In diesem Fall wäre das vermutlich ReadingsVal("LED1", "state", "0") einfacher.
- Interessanterweise nehme ich an, dass das Ergebnis dann sogar einfach der Text (nur bestehend aus der 1) zurückgegeben wurde, denn ich vermute der Präfix "state:" kommt vermutlich aus dem getstate-Kommando.

Kein Support über PM - Anfragen gerne im Forum - Damit auch andere profitieren und helfen können

NeuFehm

Oh das klingt gut.
Denn nun kann ich weiter "ausholen":
Im Prinzip habe ich 5 Ports in einem Byte zu schalten. Darum muss ich auch die anderen Ports/Geräte abfragen,
um eine Änderung am NUR am jeweiligen Gerät auszuführen und den Status der anderen Geräte zu belassen.
Allerdings möchte ich auch nicht alle Ports in FHEM definieren müssen, sodass ich eigentlich eine IF-Bedingung geplant hatte:
Wenn keine 0 oder 1 zurück, weil Device gar nicht da, dann einfach 0 nehmen.
Die ReadingsVal sehen so aus, als ob der DEFAULT-Wert genommen wird, wenn kein Wert zu diesem Reading vohanden ist.
Das wäre genau das, was ich bräuchte, dann würde für alle Gerräte/Ports, die er nicht kennt "0" zurückgeben und ich kann mir die ganzen IFs sparen ;)

Ich teste das heute mal :)
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

NeuFehm

Ich habe ersetzt:
my $Status = fhem "getstate LED1";;\
my $TLed1 = substr($Status,6,1);;\


mit:
my $TLed1 = ReadingsVal("LED1", "state", 0);;\

Gibt ein Fehler im log:
PERL WARNING: Illegal binary digit 'o' ignored at (eval 178) line 1.

Unabhängig von Hilfe, werde ich mich trotzdem in Perl weiter einarbeiten ;)
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul

NeuFehm

#5
Ahhh...der gibt ein "off" oder "on" zurück...
funktioniert also theoretisch schon mal :)

Muss nun nur noch den ReadinsVal in eine 0 bei "off" und 1 bei "on" umwandeln.

...Stunden später.....
Und da ich mich inzwischen noch ein bisschen mit Perl angefreundet habe,
habe ich gleich mal eine Subroutine probiert, die auch funktioniert ;)
Hier meine led.classdef
params T_Adresse T_Port
set on cmd {\
my $Led1 = onoff("Led1");;\
my $Led2 = onoff("Led2");;\
my $Led3 = onoff("Led3");;\
my $Relais1 = onoff("Relais1");;\
my $Relais2 = onoff("Relais2");;\
my $TLeer = 0;;\
my $DeziCode = oct("0b".$TLeer.$TLeer.$Led3.$Led2.$Led1.$TLeer.$Relais2.$Relais1);;\
chr(35).chr(84).chr(%T_Adresse).chr(80).chr(59).chr($DeziCode).chr(13).chr(10);;\
sub onoff {my $Port = shift;if ("%T_Port" eq $Port) {$Port=1} else {if (ReadingsVal("$Port", "state", "off") eq "on"){$Port=1} else {$Port=0}}};;\
}

set off cmd {\
my $Led1 = onoff("Led1");;\
my $Led2 = onoff("Led2");;\
my $Led3 = onoff("Led3");;\
my $Relais1 = onoff("Relais1");;\
my $Relais2 = onoff("Relais2");;\
my $TLeer = 0;;\
my $DeziCode = oct("0b".$TLeer.$TLeer.$Led3.$Led2.$Led1.$TLeer.$Relais2.$Relais1);;\
chr(35).chr(84).chr(%T_Adresse).chr(80).chr(59).chr($DeziCode).chr(13).chr(10);;\
sub onoff {my $Port = shift;if ("%T_Port" eq $Port) {$Port=0} else {if (ReadingsVal("$Port", "state", "off") eq "on"){$Port=1} else {$Port=0}}};;\
}


Und hier die entsprechenden Einträge in der fhem.cfg:
# LEDs definieren
define myleds ECMD serial /dev/ttyUSB0@9600
attr myleds classdefs myleddevice=/opt/fhem/led.classdef
attr myleds partial 1
attr myleds verbose 5
deleteattr myleds requestSeparator
attr mylampe split \r\n

define Led1 ECMDDevice myleddevice 33 Led1
attr Led1 IODev myleds
attr Led1 room Test

define Led2 ECMDDevice myleddevice 33 Led2
attr Led2 IODev myleds
attr Led2 room Test


Nun fällt mir in der fhem.cfg nur noch der wahrscheinlich überflüssige extra Parameter für den Devicenamen "Led1" auf.
Muss mal die commandref nach der passenden Variablen durchsuchen, oder hat gleich einer diese parat?
Raspberry Pi B+
RS 485 Schnittstellen: DIGITUS DA-70157, LINKSPTITE RS485/GPIO Shield for Raspberry Pi
RS485 Geräte: Ultraschallsensor für Zisternenfüllstand (Eigenbau), 4x8 Relais-M-Mastermodule (Eigenbau), 6 T-Module (Schalter und 3 analoge Eingänge) (Eigenbau)
sonstige Hardware: 2 Relay Modul