| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- ##############################################
- # $Id: 16_STACKABLE_CC.pm 12973 2017-01-06 10:01:25Z rudolfkoenig $
- package main;
- use strict;
- use warnings;
- #####################################
- sub
- STACKABLE_CC_Initialize($)
- {
- my ($hash) = @_;
- LoadModule("CUL");
- $hash->{Match} = "^\\*";
- $hash->{DefFn} = "STACKABLE_CC_Define";
- $hash->{UndefFn} = "STACKABLE_CC_Undef";
- $hash->{ParseFn} = "STACKABLE_CC_Parse";
- $hash->{NotifyFn} = "STACKABLE_CC_Notify";
- $hash->{AttrFn} = "CUL_Attr";
- $hash->{AttrList} = "IODev ignore:0,1 ".$modules{CUL}{AttrList};
- $hash->{WriteFn} = "STACKABLE_CC_Write";
- $hash->{GetFn} = "CUL_Get";
- $hash->{SetFn} = "CUL_Set";
- $hash->{AddPrefix} = "STACKABLE_CC_AddPrefix";
- $hash->{DelPrefix} = "STACKABLE_CC_DelPrefix";
- $hash->{noRawInform} = 1; # Our message was already sent as raw.
- $hash->{noAutocreatedFilelog} = 1;
- $hash->{IOOpenFn} = "STACKABLE_IOOpenFn";
- $hash->{IOReadFn} = "STACKABLE_IOReadFn";
- $hash->{IOWriteFn} = "STACKABLE_IOWriteFn";
- }
- #####################################
- sub
- STACKABLE_CC_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t][ \t]*", $def);
- $hash->{TCM} = pop @a if(int(@a) == 4 && $a[3] eq "TCM");
- return "wrong syntax: define <name> STACKABLE_CC [CUL|SCC] [TCM]"
- if(int(@a) != 3);
- my $io = $defs{$a[2]};
- return "$a[2] is not a CUL/STACKABLE_CC"
- if(!$io || $io->{TYPE} !~ m/^(CUL|TSCUL|STACKABLE_CC|TSSTACKED)$/);
- return "$io->{NAME} has alread a stacked device: $io->{STACKED}"
- if($io->{STACKED});
- $io->{STACKED} = $hash->{NAME};
- $hash->{IODev} = $io;
- delete($io->{".clientArray"}); # Force a recompute
- if(!$hash->{TCM}) {
- $hash->{initString} = $io->{initString};
- $hash->{CMDS} = "";
- $hash->{Clients} = $io->{Clients};
- $hash->{MatchList} = $io->{MatchList};
- CUL_DoInit($hash);
- }
- $hash->{StackLevel} = $io->{StackLevel} ? $io->{StackLevel}+1 : 1;
- $hash->{STATE} = "Defined";
- notifyRegexpChanged($hash, $a[2]);
- return undef;
- }
- sub
- STACKABLE_CC_DoNotify($)
- {
- my ($ntfy) = @_;
- DoTrigger($ntfy->{NAME}, $ntfy->{TriggerText});
- delete $ntfy->{TriggerText};
- }
- sub
- STACKABLE_CC_Notify($$)
- {
- my ($ntfy, $dev) = @_;
- my $events = deviceEvents($dev, 0);
- for(my $i = 0; $i < @{$events}; $i++) {
- if($events->[$i] eq "DISCONNECTED") {
- $ntfy->{STATE} = "disconnected";
- setReadingsVal($ntfy, "state", "disconnected", TimeNow());
- $ntfy->{TriggerText} = $events->[$i];
- InternalTimer(gettimeofday()+0.1, "STACKABLE_CC_DoNotify", $ntfy, 0);
- } elsif($events->[$i] eq "CONNECTED") {
- CUL_DoInit($ntfy);
- $ntfy->{TriggerText} = $events->[$i];
- InternalTimer(gettimeofday()+0.001, "STACKABLE_CC_DoNotify", $ntfy, 0);
- }
- }
- }
- #####################################
- sub
- STACKABLE_CC_Write($$)
- {
- my ($hash,$fn,$msg) = @_;
- ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg);
- return if(!defined($fn));
- IOWrite($hash, "", ($hash->{TCM} ? "%":"*")."$fn$msg"); # No more translations
- }
- #####################################
- sub
- STACKABLE_CC_Parse($$)
- {
- my ($iohash,$msg) = @_;
- $msg =~ s/^.//; # Cut off prefix *
- my $name = $iohash->{STACKED} ? $iohash->{STACKED} : "";
- my $id = $iohash->{StackLevel} ? $iohash->{StackLevel}+1 : 1;
- return "UNDEFINED STACKABLE_CC_$id STACKABLE_CC $iohash->{NAME}"
- if(!$name);
- return "" if(IsIgnored($name));
- my $sh = $defs{$name};
- if($sh && $sh->{TCM}) {
- my $th = $sh->{TCMHash};
- if($th) {
- delete $th->{IOReadFn};
- $th->{IODevRxBuffer} = pack("H*", $msg);
- CallFn($th->{NAME}, "ReadFn", $th);
- $th->{IOReadFn} = "STACKABLE_IOReadFn";
- } else {
- Log 1, "$name: no TCM device assigned";
- }
-
- } else {
- CUL_Parse($defs{$name}, $iohash, $name, $msg);
- }
- return "";
- }
- sub
- STACKABLE_CC_DelPrefix($$)
- {
- my ($hash, $msg) = @_;
- $msg =~ s/^[^A-Z0-9]//i;
- return $msg;
- }
- sub
- STACKABLE_CC_AddPrefix($$)
- {
- my ($hash, $msg) = @_;
- return "*$msg";
- }
- sub
- STACKABLE_CC_Undef($$)
- {
- my ($hash, $arg) = @_;
- CUL_SimpleWrite($hash, "X00");
- delete $hash->{IODev}{STACKED};
- return undef;
- }
- sub
- STACKABLE_IOOpenFn($)
- {
- my ($hash) = @_;
- $hash->{FD} = $hash->{IODev}{IODev}{FD}; # Lets fool the TCM
- $hash->{IODev}{TCMHash} = $hash;
- $hash->{IOReadFn} = "STACKABLE_IOReadFn";
- return 1;
- }
- sub
- STACKABLE_IOReadFn($)
- {
- my ($hash) = @_;
- my $me = $hash->{IODev};
- my $buf = "";
- while($buf !~ m/\n/) {
- $buf .= DevIo_SimpleRead($me->{IODev}); # may block
- }
- $buf =~ s/[\r\n]//g;
- $buf = STACKABLE_CC_DelPrefix($me, $buf);
- return pack("H*",$buf);
- }
- sub
- STACKABLE_IOWriteFn($$)
- {
- my ($hash, $msg) = @_;
- return IOWrite($hash, "", unpack("H*",$msg));
- }
- 1;
- =pod
- =item summary Busware Stackable CC (SCC) base module
- =item summary_DE Busware Stackabble CC (SCC) basis Modul
- =begin html
- <a name="STACKABLE_CC"></a>
- <h3>STACKABLE_CC</h3>
- <ul>
- This module handles the stackable CC1101 devices for the Raspberry PI from
- busware.de. You can attach a lot of CUL-Type devices to a single RPi this way.
- The first device is defined as a CUL, the rest of them as STACKABLE_CC.
- <br><br>
- <a name="STACKABLE_CCdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> STACKABLE_CC <Base-Device-Name></code> <br>
- <br>
- <Base-Device-Name> is the name of the device, which this device is
- attached on, the first one has to be defined as a CUL device<br>
- Example:
- <ul><code>
- define SCC0 CUL /dev/ttyAMA0@38400<br>
- attr SCC0 rfmode SlowRF<br>
- define SCC1 STACKABLE_CC SCC0<br>
- attr SCC1 rfmode HomeMatic<br>
- define SCC2 STACKABLE_CC SCC1<br>
- attr SCC2 rfmode Max<br>
- </code></ul>
- <b>Important:</b>
- <ul>
- <li>The rfmode has to be specified explicitely (valid for the STACKABLE_CC
- types only, not for the first, which is defined as a CUL).</li>
- <li>In case of SlowRF, the FHTID has to be specified explicitely with the
- command "set SCCX raw T01HHHH". Again, this is valid for the STACKABLE_CC
- types only.</li>
- <li>If you rename the base CUL or a STACKABLE_CC, which is a base for
- another one, the define of the next one has to be adjusted, and FHEM has to be
- restarted.</li>
- </ul>
- </ul>
- <a name="STACKABLE_CCset"></a>
- <b>Set</b> <ul>Same as for the <a href="#CULset">CUL</a>.</ul><br>
- <a name="STACKABLE_CCget"></a>
- <b>Get</b> <ul>Same as for the <a href="#CULget">CUL</a>.</ul><br>
- <a name="STACKABLE_CCattr"></a>
- <b>Attributes</b>
- <ul>
- <li><a href="#IODev">IODev</a></li><br>
- <li><a href="#ignore">ignore</a></li><br>
- The rest of the attributes is the same as for the <a href="#CULattr">CUL</a>.
- </ul>
- </ul>
- =end html
- =begin html_DE
- <a name="STACKABLE_CC"></a>
- <h3>STACKABLE_CC</h3>
- <ul>
- Mit Hilfe dieses Moduls kann man die "Stackable CC" Geräte von busware.de in
- FHEM integrieren. Diese Geräte ermöglichen eine Menge von CULs an einem RPi
- anzuschliessen.
- Das erste Gerät wird als CUL definiert, alle nachfolgenden als STACKABLE_CC.
- <br><br>
- <a name="STACKABLE_CCdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> STACKABLE_CC <Base-Device-Name></code> <br>
- <br>
- <Base-Device-Name> ist der Name des Gerätes, der als Basis für das
- aktuelle Gerät dient.<br>
- Beispiel:
- <ul><code>
- define SCC0 CUL /dev/ttyAMA0@38400<br>
- attr SCC0 rfmode SlowRF<br>
- define SCC1 STACKABLE_CC SCC0<br>
- attr SCC1 rfmode HomeMatic<br>
- define SCC2 STACKABLE_CC SCC1<br>
- attr SCC2 rfmode Max<br>
- </code></ul>
- <b>Wichtig:</b>
- <ul>
- <li>Das rfmode Attribut muss explizit spezifiziert werden. Das gilt nur
- für die STACKABLE_CC Definitionen, und nicht für die erste, die
- als CUL definiert wurde.</li>
- <li>Falls SlowRF spezifiziert wurde, dann muss das FHTID explizit gesetzt
- werden, mit folgendem Kommando: "set SCCX raw T01HHHH". Auch das ist nur
- für die STACKABLE_CC nötig.</li>
- <li>Falls ein Gerät umbenannt wird, was als Basis für ein STACKABLE_CC
- dient, dann muss es auch in der Definition des abhängigen Gerätes
- umbenannt werden, und FHEM muss neugestartet werden.</li>
- </ul>
- </ul>
- <a name="STACKABLE_CCset"></a>
- <b>Set</b> <ul>Die gleichen wie für das <a href="#CULset">CUL</a>.</ul><br>
- <a name="STACKABLE_CCget"></a>
- <b>Get</b> <ul>Die gleichen wie für das <a href="#CULget">CUL</a>.</ul><br>
- <a name="STACKABLE_CCattr"></a>
- <b>Attributes</b>
- <ul>
- <li><a href="#IODev">IODev</a></li><br>
- <li><a href="#ignore">ignore</a></li><br>
- Die anderen Attribute sind die gleichen wie für das <a href="#CULattr">CUL</a>.
- </ul>
- </ul>
- =end html_DE
- =cut
|