DevelopmentIntroduction: Unterschied zwischen den Versionen
Yfhem (Diskussion | Beiträge) K (→Application Lifecycle:  Improved list.)  | 
				Krikan (Diskussion | Beiträge)  K (Kategorie:Development (Archive) zugeordnet)  | 
				||
| (2 dazwischenliegende Versionen von einem anderen Benutzer werden nicht angezeigt) | |||
| Zeile 26: | Zeile 26: | ||
## For FHZ devices, the FHZ_CheckCRC method is used to validate the received data  | ## For FHZ devices, the FHZ_CheckCRC method is used to validate the received data  | ||
## Call the Dispatch method in FHEM.pl to pass the message onto the correct device and corresponding module (Parse function)  | ## Call the Dispatch method in FHEM.pl to pass the message onto the correct device and corresponding module (Parse function)  | ||
$server->fileno() is used to check for and accept new connections to the server  | |||
For each connected client:  | |||
# Read data from the client using sysread  | # Read data from the client using sysread  | ||
# Pass the received input into the AnalyzeInput method to execute the command  | # Pass the received input into the AnalyzeInput method to execute the command  | ||
== Configuration and State Files ==  | == Configuration and State Files ==  | ||
Note that these are just lists of commands to execute in a text file! So anything in these files will be interpreted by FHEM in the exact same way if a user keys the commands manually into a client application, eg a telnet connection.  | Note that these are just lists of commands to execute in a text file! So anything in these files will be interpreted by FHEM in the exact same way if a user keys the commands manually into a client application, eg a telnet connection.  | ||
| Zeile 62: | Zeile 62: | ||
Die Funktion '''readingsEndUpdate'''aktualisiert $hash->{STATE} grundsätzlich immer bei jedem Aufruf nach folgendem Algorithmus:  | Die Funktion '''readingsEndUpdate''' aktualisiert $hash->{STATE} grundsätzlich immer bei jedem Aufruf nach folgendem Algorithmus:  | ||
Falls $sr= $attr{$name}{stateReading} gesetzt ist:  | Falls $sr= $attr{$name}{stateReading} gesetzt ist:  | ||
| Zeile 80: | Zeile 80: | ||
Aus '''DoTrigger'''werden  | Aus '''DoTrigger''' werden  | ||
  <nowiki>$defs{$dev}{STATE} = ReplaceEventMap($dev, $defs{$dev}{STATE}, 1);</nowiki>  |   <nowiki>$defs{$dev}{STATE} = ReplaceEventMap($dev, $defs{$dev}{STATE}, 1);</nowiki>  | ||
| Zeile 89: | Zeile 89: | ||
   $r->{state}{VAL} = $defs{$dev}{STATE} if($r && $r->{state});</nowiki>  |    $r->{state}{VAL} = $defs{$dev}{STATE} if($r && $r->{state});</nowiki>  | ||
entfernt.  | entfernt.  | ||
== Global Attributes ==  | == Global Attributes ==  | ||
| Zeile 101: | Zeile 97: | ||
global userattr hinzufuegen.  | global userattr hinzufuegen.  | ||
[[Kategorie:Development]]  | [[Kategorie:Development (Archive)]]  | ||
Aktuelle Version vom 19. Oktober 2016, 13:14 Uhr
Developer's Introduction to FHEM
Introduction
This page is intended to give an introduction to the FHEM application from a developer's perspective. If you're interested in extending, modifying or reusing the FHEM code, then hopefully you will find this a useful document. Note that this document is a work in progress! I myself at the time of writing this have only a few hours of experience under my belt, but I'm documenting things I learn as I learn them.
Application Lifecycle
When you first launch the FHEM server, the following activities take place:
- Application variables are initialised
 - The valid application commands are loaded into a structure (%cmds) with the corresponding function name to call
 - Do the job, either act as client or server. One of the following applies:
- If the application has been called as a FHEM client (eg perl fhem.pl 127.0.0.1:7072 commandToExecute)
- Connect to the FHEM server
 - Execute the command
 - Exit the program
 
 - Otherwise (the application has been started as a server)
- Execute each of the commands listed in the configuration file to initialise the server (see the CommandInclude and then the AnalyzeCommandChain methods)
 - Execute each of the commands in the state file if configured to restore the devices to the last state recorded when the server last ran
 - Start the main application loop
 
 
 - If the application has been called as a FHEM client (eg perl fhem.pl 127.0.0.1:7072 commandToExecute)
 
Main Application Loop
The following code is repeated until the application ends:
- For each input device (eg FHZ1000 / FHZ1300 / CUL):
- Use that device module's Ready and Read functions to read data from the device
 - For CUL devices, the data is read and parsed at this point
 - For FHZ devices, the FHZ_CheckCRC method is used to validate the received data
 - Call the Dispatch method in FHEM.pl to pass the message onto the correct device and corresponding module (Parse function)
 
 
$server->fileno() is used to check for and accept new connections to the server For each connected client:
- Read data from the client using sysread
 - Pass the received input into the AnalyzeInput method to execute the command
 
Configuration and State Files
Note that these are just lists of commands to execute in a text file! So anything in these files will be interpreted by FHEM in the exact same way if a user keys the commands manually into a client application, eg a telnet connection.
Readings
The following mechanism is recommended for updating readings. It saves lines of codes and automatically makes your module honor the event-on-update-reading and event-on-change-reading attributes.
Before you start updating readings, write (in case $hash = $defs{<device>})
readingsBeginUpdate($hash);
For every reading you update, write
readingsBulkUpdate($hash,$reading,$value);
Terminate with
readingsEndUpdate($hash, $dotrigger);
The $dotrigger parameter should be 0 for updates initiated by fhem message dispatcher as the dispatcher already calls DoTrigger on its behalf. $dotrigger should be 1 for updates initiated by internal timers, e.g. for polling devices.
As a shorthand notation for updating just one reading write
readingsSingleUpdate($hash,$reading,$value,$dotrigger);
which is the same as
readingsBeginUpdate($hash); readingsBulkUpdate($hash,$reading,$value); readingsEndUpdate($hash, $dotrigger);
STATE
Vorschlag zur Umsetzung, diskutiert hier.
In den DevelopmentGuidelines, Kapselung, Standardisierung der Vorgehensweise.
Die Funktion readingsEndUpdate aktualisiert $hash->{STATE} grundsätzlich immer bei jedem Aufruf nach folgendem Algorithmus:
Falls $sr= $attr{$name}{stateReading} gesetzt ist:
Fall 1: wenn $sr =~ "^{.*}$" dann eval "\$hash->{STATE} = $sr";
  Fall 2: sonst $hash->{STATE}= $hash->{READINGS}{$sr}{VAL}
sonst
Falls es $hash->{READINGS}{state} gibt, $hash->{STATE}= $hash->{READINGS}{state}{VAL}
sonst
Tue nichts (das Modul hat sich gekuemmert).
Ausserdem wird
ReplaceEventMap()
losgelassen, um die EventMaps des Anwenders auch im STATE zur Anwendung zu bringen.
Aus DoTrigger werden
$defs{$dev}{STATE} = ReplaceEventMap($dev, $defs{$dev}{STATE}, 1);
und
# STATE && {READINGS}{state} should be the same
  my $r = $defs{$dev}{READINGS};
  $r->{state}{VAL} = $defs{$dev}{STATE} if($r && $r->{state});
entfernt.
Global Attributes
In fhem.pl existiert ein
my $AttrList = "room comment alias ...";
Weiterhin kann jedes Modul im Initialize mit addToAttrList eigene Attribute zu global userattr hinzufuegen.