Hallo,
Ich baue gerade an meinem ersten wirklichen 2 stufigen Modul und hänge nun ein klein wenig am Dispatcher und ParseFn
2017.01.22 12:54:36 5: HEOSTest: dispatch {"heos": {"command": "player/set_play_state", "result": "success", "message": "pid=-512565195&state=stop"}}
2017.01.22 12:54:36 3: HEOSTest: Unknown code {"heos": {"command": "player/set_play_state", "result": "success", "message": "pid=-512565195&state=stop"}}, help me!
Die relevanten Teile sehen bei mir so aus
physikalisches Modul
$hash->{Clients} = ":HEOSPlayer:";
...
sub blabla() {
Dispatch($hash,$json,undef);
...
}
Hash ist der Hash vom physikalischen Modul und json ist ein JSON String
logisches Modul
$hash->{Match} = "^[\[{].*[}\]]\$";
$hash->{ParseFn} = "HEOSPlayer_Parse";
...
So habe ich das ganze verstanden. Der Dispatcher schaut nach ob der $hash->{Match} meiner $hash->{Clients} mit dem im Dispatcher übergebenen string überein stimmt. Wenn dem so ist wird automatisch die ParseFn des logischen Modules gestartet. Habe ich es wenigstens Ansatzweise richtig verstanden?
Da ich nur ein logisches Module und nur eine passende ParseFn habe, kann ich nicht das $hash->{Match} weg lassen und er sollte dennoch die korrekte ParseFn starten?
Im Moment passiert nichts und ich bekomme nur die obrige Fehlermeldung
Grüße
Leon
Dispatch geht erst alle Clients vom physikalischen durch, und falls sie geladen sind (z.Bsp. durch define) und die aktuelle Rohdaten dem logischen Match entsprechen, dann ruft sie die logische ParseFn auf. Falls hier keiner sich als zustaendig meldet, dann wird MatchList des physikalischen Moduls durchgearbeitet, das passende Modul geladen, und dessen ParseFn ausgefuehrt.
Ich gehe davon aus, dass du kein logisches Geraet definiert hast, oder dein Regexp nicht funktioniert. Regexp kann auch .* sein, da keine andere logische Module gibt. Weiterhin fehlt MatchList im physikalischen Modul fuer autoload bzw. autocreate.
Zitat von: rudolfkoenig am 22 Januar 2017, 13:39:52
Dispatch geht erst alle Clients vom physikalischen durch, und falls sie geladen sind (z.Bsp. durch define) und die aktuelle Rohdaten dem logischen Match entsprechen, dann ruft sie die logische ParseFn auf. Falls hier keiner sich als zustaendig meldet, dann wird MatchList des physikalischen Moduls durchgearbeitet, das passende Modul geladen, und dessen ParseFn ausgefuehrt.
Ich gehe davon aus, dass du kein logisches Geraet definiert hast, oder dein Regexp nicht funktioniert. Regexp kann auch .* sein, da keine andere logische Module gibt. Weiterhin fehlt MatchList im physikalischen Modul fuer autoload bzw. autocreate.
Hallo Rudi,
Vielen Dank für Deine Hilfe. Ich habe sowohl ein logisches als auch ein physikalisches Gerät definiert. Das mit der Regex probiere ich gleich mal und füge in das physikalische Modul noch eine MatchList hinzu.
Melde mich dann noch mal.
Grüße
Hallo CoolTux,
ich habe das zweistufige Modell ausführlich im Wiki dokumentiert: https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Zweistufiges_Modell_f.C3.BCr_Module
Sollte etwas unklar sein, freue ich mich gerne über Anregungen.
Viele Grüße
Markus
Zitat von: Markus Bloch am 22 Januar 2017, 14:24:22
Hallo CoolTux,
ich habe das zweistufige Modell ausführlich im Wiki dokumentiert: https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Zweistufiges_Modell_f.C3.BCr_Module
Sollte etwas unklar sein, freue ich mich gerne über Anregungen.
Viele Grüße
Markus
Hallo Markus,
Ich weiß und das hast Du auch wirklich gut gemacht. Es liegt, was das an geht, wohl er an mir. Nicht wegen dem Verstehen sondern an meiner seltsamen Art und Weise die Welt und deren Dinge komplexer zu sehen wie sie eigentlich sind. Frag mal Andre der kann Dir da ein Lied von singen ;D
Aber was hälst Du davon wenn ich mich einfach mal bei Dir melde wie meine neuen Erfahrungen in den Tests ausgefallen sind ;)
Grüße
Leon
Hallo Leon,
ein Thema richtig zu Verstehen ist die eine Hälfte, es verständlich rüberbringen die andere Hälfte ;) . Ist durchaus möglich, dass ich aufgrund von "Betriebsblindheit" den Inhalt nicht komplett verständlich transportiere, insbesondere, wenn man als Leser einen ganz anderen Blickwinkel besitzt. Daher bin ich immer froh, wenn es Leute gibt, die mit einem komplett anderen Verständnis an solche Artikel herangehen.
Zitat von: CoolTux am 22 Januar 2017, 14:27:52
Aber was hälst Du davon wenn ich mich einfach mal bei Dir melde wie meine neuen Erfahrungen in den Tests ausgefallen sind ;)
Das würde mich sehr freuen, dann können wir schauen, wo es hakte und ob man das im Artikel noch etwas herausarbeiten kann.
Vielen Dank
Gruß
Markus
Hallo Leute,
@Rudi
Vielen Dank es war in der Tat der RegEx
@Markus
Ich habe mir das noch mal durchgelesen. Vorschläge
1. Wenn nur ein logisches Modul vorhanden ist würde ich Rudis RegEx als default empfehlen
2. Mir war nicht klar das im physischen und logischen Modul jeweils eine Matchlist und eine ParseFn sein sollte. Das hatte ich auch so nicht raus gelesen. (Was nicht heißen muss das es nicht da steht)
LG
Leon
Zitat von: CoolTux am 22 Januar 2017, 21:45:50
@Markus
Ich habe mir das noch mal durchgelesen. Vorschläge
1. Wenn nur ein logisches Modul vorhanden ist würde ich Rudis RegEx als default empfehlen
OK, kann ich ergänzen.
Zitat von: CoolTux am 22 Januar 2017, 21:45:50
2. Mir war nicht klar das im physischen und logischen Modul jeweils eine Matchlist und eine ParseFn sein sollte. Das hatte ich auch so nicht raus gelesen. (Was nicht heißen muss das es nicht da steht)
Eine ParseFn ist nur im logischen Modul notwendig. Ein physikalisches Modul ruft Dispatch() auf um Daten an ein logisches Modul zu geben. Dadurch ruft es die ParseFn des passenden Moduls (basierend auf der Match-Regexp) auf. Ein physikalisches Modul benötigt keine ParseFn.
Vorsicht mit der Benennung! Das physikalische Modul benötigt eine Match-Liste (Zuordnung Modul => Nachrichten-Regexp). Das logische Modul benötigt NUR einen einzelnen Match-Ausdruck (Prüfung Nachricht für eigenes Modul).
Daher habe ich im Wiki eine Extra-Unterscheidung gemacht zwischen Match-Liste und Match-Ausdruck, da es eine unterschiedliche Verwendung hat. Zusammenfassend ist das im Wiki unter https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Die_vollst.C3.A4ndige_Implementierung aufgelistet, welche Funktionen/Daten ein logisches bzw. physisches Modul implementieren muss.
Gruß
Markus
Aha, deswegen klappt mein Anlegen eines logischen Devices nicht wenn es nicht da ist. Wenn ein passendes logisches Device da ist klappt die Zustellung prima, nur wenn keines da will er noch nicht so ganz ;D
Ich lese mal weiter.
Daaaanke
So ich habe es nun hin bekommen und es sieht supi aus. Nur noch ein klitze kleiner Schönheitsfehler
2017.01.22 22:43:52 1: ERROR: >HEOSPlayer512565195 HEOSPlayer -512565195 IODev=HEOSTest< returned by the HEOSPlayer ParseFn is invalid, notify the module maintainer
Meine PatchList
$hash->{MatchList} = { "1:HEOSPlayer" => ".*" };
Meine ParseFn vom logischen Modul
sub HEOSPlayer_Parse($$) {
my ($io_hash,$decode_json) = @_;
my $name = $io_hash->{NAME};
my $pid = $decode_json->{payload}{pid};
Log3 undef, 3, "HEOSPlayer - ParseFn wurde aufgerufen";
my $code = abs($pid);
$code = $io_hash->{NAME} ."-". $code if( defined($io_hash->{NAME}) );
if( my $hash = $modules{HEOSPlayer}{defptr}{$code} ) {
my $name = $hash->{NAME};
HEOSPlayer_WriteReadings($hash,$decode_json);
Log3 $name, 3, "HEOSPlayer ($name) - finde logisches Device: $hash->{NAME}";
return $hash->{NAME};
} else {
my $devname = "HEOSPlayer".abs($pid);
return "$devname HEOSPlayer $pid IODev=$name";
}
}
Kann mir bitte jemand einen Schups geben.
Hat sich erledigt. Vielen Dank Euch. Habe es hinbekommen. Manchmal muss man einfach bisschen mehr nachdenken ;D
Hallo Leon,
in deiner ParseFn gibt es einen else-Zweig für den Fall, dass eine entsprechende Definition für HEOSPlayer noch nicht existiert:
else {
my $devname = "HEOSPlayer".abs($pid);
return "$devname HEOSPlayer $pid IODev=$name";
}
Der Rückgabewert ist so aber nicht korrekt, sondern muss folgendermaßen lauten:
return "UNDEFINED $devname HEOSPlayer $pid";
Der Präfix "UNDEFINED" signalisiert, dass eine entsprechende logische Definition noch nicht existiert und diese durch autocreate automatisch angelegt wird. Siehe dazu https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Automatisches_Anlegen_von_logischen_Ger.C3.A4tedefinitionen_.28autocreate.29
Viele Grüße
Markus
Zitat von: CoolTux am 22 Januar 2017, 23:14:43
Hat sich erledigt. Vielen Dank Euch. Habe es hinbekommen. Manchmal muss man einfach bisschen mehr nachdenken ;D
Hallo Markus,
Vielen lieben Dank für Deine Antwort. Das mit dem UNDEFINED war der Teil mit dem bisschen mehr Nachdenken ;D
Grüße aus Potsdam
Leon
Nun habe ich da doch noch mal eine Frage.
Sieht so aus als wenn ich nun doch 2 logische Module anlegen werden. Klappt ja auch gerade so gut mit dem Verstehen ;D
Allerdings ist es so das sie Daten welche ich an den Dispatcher weiterreiche im Moment Hash's sind. json_decode Hash's. Kann man da eine Regex machen? Ich wüsste nicht wie, ausser auf Hash.
Oder ist es besser ich übergebe den json string und decodiere in ihm logischen Modul?
Grüße
Entweder, du unterscheidest die Daten aufgrund eines bestimmten Keywords innerhalb des JSON, an denen man die Hashes unterscheiden kann und dies als Match-Regex verwendest. Alternativ, könnte man den JSON-Daten einen Präfix voranstellen, woran die Module ihre Daten erkennen.
Woran erkennst Du denn, dass es sich um Daten für unterschiedliche Module handelt?
Gruß
Markus
Es handelt sich um ein Multiroomsystem. Hier habe ich bis jetzt Master (physisches Device) und Player (logische Devices).
Nun habe ich gesehen das es noch groups gibt wo man Player mit der selben grouId zusammen schalten kann. Und ich dachte mir das ich da dann ein drittes Modul mache um groupen Devices zu bekommen. Erkennen tut man das am JSON String
Response:
{
"heos":{
}
}
"command": " player/ set_volume ",
"result": "success",
"message": "pid='player_id'&level='vol_level'"
heos->{command} hat hier player
Response:
{
"heos":{
}
}
"command": "group/get_volume ",
"result": "success",
"message": "gid='group_id'&level='vol_level'"
Example: heos://group/get_volume?gid=1
Und hier group
Oder ist es besser wenn ich ein groupvolume im Player einbaue? aber das ist dann nicht mehr FHEM Media Konform
Grüße
In dem Fall könnte man ja folgende Match-Regexp / Match-Liste nehmen:
logisches Modul Player:
$hash->{Match} = '{.*"command": " player.*}';
logisches Modul Gruppe:
$hash->{Match} = '{.*"command": " group.*}';
Und beide Regexp's analog dann auch in der MatchList.
Zitat von: CoolTux am 24 Januar 2017, 08:32:47
Oder ist es besser wenn ich ein groupvolume im Player einbaue? aber das ist dann nicht mehr FHEM Media Konform
Ich bin immer für Konformität zu bestehenden Modulen/Standards.
Gruß
Markus
Hallo Markus,
Dann übergebe ich an den Dispatcher den json String und nicht wie bisher decode_json. Ist ja kein Beinbruch. Muss ich halt in den logischen Modulen noch mal encode_json machen.
Grüße