mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 10:46:53 +00:00
FHEM2FHEM and associated changes
git-svn-id: https://svn.fhem.de/fhem/trunk@732 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
b580c66189
commit
9dc00abe35
@ -2,6 +2,8 @@
|
||||
- feature: smallscreen optimizations for iPhone
|
||||
- feature: FHT8V rewrite (and moved from contrib into the FHEM directory).
|
||||
- feature: PID rewrite (and moved from contrib into the FHEM directory).
|
||||
- feature: FHEM2FHEM module
|
||||
- bugfix: CUL get should not digest foreign events (fhtsoftbuffer)
|
||||
|
||||
- 2010-08-15 (5.0)
|
||||
- **NOTE*: The default installation path is changed to satisfy lintian
|
||||
|
@ -25,6 +25,7 @@ CUL_RFR_Initialize($)
|
||||
$hash->{WriteFn} = "CUL_RFR_Write";
|
||||
$hash->{GetFn} = "CUL_Get";
|
||||
$hash->{SetFn} = "CUL_Set";
|
||||
$hash->{noRawInform} = 1; # Our message was already sent as raw.
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,8 +4,6 @@ package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub addToAttrList($);
|
||||
|
||||
#####################################
|
||||
sub
|
||||
structure_Initialize($)
|
||||
@ -199,20 +197,4 @@ structure_Attr($@)
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
addToAttrList($)
|
||||
{
|
||||
my $arg = shift;
|
||||
|
||||
my $ua = "";
|
||||
$ua = $attr{global}{userattr} if($attr{global}{userattr});
|
||||
my @al = split(" ", $ua);
|
||||
my %hash;
|
||||
foreach my $a (@al) {
|
||||
$hash{$a} = 1;
|
||||
}
|
||||
$hash{$arg} = 1;
|
||||
$attr{global}{userattr} = join(" ", sort keys %hash);
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -121,6 +121,7 @@
|
||||
<b>Helper modules</b>
|
||||
<ul>
|
||||
<a href="#DbLog">DbLog</a>
|
||||
<a href="#FHEM2FHEM">FHEM2FHEM</a>
|
||||
<a href="#FHEMRENDERER">FHEMRENDERER</a>
|
||||
<a href="#FHEMWEB">FHEMWEB</a>
|
||||
<a href="#FileLog">FileLog</a>
|
||||
@ -506,7 +507,7 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
<a name="inform"></a>
|
||||
<h3>inform</h3>
|
||||
<ul>
|
||||
<code>inform [on|off|timer]</code> <br>
|
||||
<code>inform [on|off|timer|raw]</code> <br>
|
||||
<br>
|
||||
If set to on, and a device state changes, send a notification to the current
|
||||
client. This command can be used by other programs/modules to receive a
|
||||
@ -4694,6 +4695,66 @@ Terminating
|
||||
|
||||
</ul>
|
||||
|
||||
<a name="FHEM2FHEM"></a>
|
||||
<h3>FHEM2FHEM</h3>
|
||||
<ul>
|
||||
FHEM2FHEM is a helper module to connect separate fhem installations.
|
||||
|
||||
<a name="FHEM2FHEMdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> FHEM2FHEM <host:portnr> [LOG:regexp|RAW:devicename]
|
||||
</code>
|
||||
</ul>
|
||||
<br>
|
||||
Conect to the <i>remote</i> fhem on host. portnr is the global port
|
||||
attribute of the remote fhem. The next parameter specifies the connection
|
||||
type:
|
||||
<ul>
|
||||
<li>LOG<br>
|
||||
Using this type you will receive all events generated by the remote fhem,
|
||||
just like when using the <a href="#inform">inform on</a> command, and you
|
||||
can use these events just like any local event for <a
|
||||
href="#FileLog">FileLog </a> or <a href="#notify">notify</a>.
|
||||
The regexp will prefilter the events distributed locally, for the syntax
|
||||
see the notify definition.<br>
|
||||
Drawbacks: the remote devices wont be created locally, so list wont
|
||||
show them and it is not possible to manipulate them from the local
|
||||
fhem. It is possible to create a device with the same name on both fhem
|
||||
instances, but if both of them receive the same event (e.g. because both
|
||||
of them have a CUL attached), then all associated FileLogs/notifys will be
|
||||
triggered twice. </li>
|
||||
|
||||
<li>RAW<br>
|
||||
By using this type the local fhem will receive raw events from the remote
|
||||
fhem device <i>devicename</i>, just like if it would be attached to the
|
||||
local fhem.
|
||||
Drawback: only devices using the Dispatch function (CUL, FHZ, CM11,
|
||||
SISPM, RFXCOM) generate raw messages.
|
||||
</ul>
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define ds1 FHEM2FHEM 192.168.0.1:7072 LOG:.*</code><br>
|
||||
<code>define ds2 FHEM2FHEM 192.168.0.1:7072 RAW:CUL</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="FHEM2FHEMset"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="FHEM2FHEMget"></a>
|
||||
<b>Get</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="FHEM2FHEMattr"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#dummy">dummy</a></li>
|
||||
<li><a href="#loglevel">loglevel</a></li>
|
||||
</ul>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="FHEMWEB"></a>
|
||||
<h3>FHEMWEB</h3>
|
||||
<ul>
|
||||
|
81
fhem/fhem.pl
81
fhem/fhem.pl
@ -44,6 +44,7 @@ sub AnalyzeCommand($$);
|
||||
sub AnalyzeCommandChain($$);
|
||||
sub AnalyzeInput($);
|
||||
sub AssignIoPort($);
|
||||
sub addToAttrList($);
|
||||
sub CallFn(@);
|
||||
sub CommandChain($$);
|
||||
sub CheckDuplicate($$);
|
||||
@ -87,6 +88,7 @@ sub CommandGet($$);
|
||||
sub CommandHelp($$);
|
||||
sub CommandInclude($$);
|
||||
sub CommandInform($$);
|
||||
sub CommandIOWrite($$);
|
||||
sub CommandList($$);
|
||||
sub CommandModify($$);
|
||||
sub CommandReload($$);
|
||||
@ -142,6 +144,7 @@ use vars qw($internal_data); #
|
||||
use vars qw(%cmds); # Global command name hash. To be expanded
|
||||
use vars qw(%data); # Hash for user data
|
||||
use vars qw($devcount); # To sort the devices
|
||||
use vars qw(%defaultattr); # Default attributes, used by FHEM2FHEM
|
||||
|
||||
use vars qw($reread_active);
|
||||
|
||||
@ -154,13 +157,12 @@ my %client; # Client array
|
||||
my $rcvdquit; # Used for quit handling in init files
|
||||
my $sig_term = 0; # if set to 1, terminate (saving the state)
|
||||
my $modpath_set; # Check if modpath was used, and report if not.
|
||||
my %defaultattr; # Default attributes
|
||||
my %intAt; # Internal at timer hash.
|
||||
my $nextat; # Time when next timer will be triggered.
|
||||
my $intAtCnt=0;
|
||||
my %duplicate; # Pool of received msg for multi-fhz/cul setups
|
||||
my $duplidx=0; # helper for the above pool
|
||||
my $cvsid = '$Id: fhem.pl,v 1.113 2010-10-10 08:23:29 rudolfkoenig Exp $';
|
||||
my $cvsid = '$Id: fhem.pl,v 1.114 2010-10-24 16:08:48 rudolfkoenig Exp $';
|
||||
my $namedef =
|
||||
"where <name> is either:\n" .
|
||||
"- a single device name\n" .
|
||||
@ -201,7 +203,9 @@ $modules{_internal_}{AttrFn} = "GlobalAttr";
|
||||
"include" => { Fn=>"CommandInclude",
|
||||
Hlp=>"<filename>,read the commands from <filenname>" },
|
||||
"inform" => { Fn=>"CommandInform",
|
||||
Hlp=>"{on|timer|off},echo all commands and events to this client" },
|
||||
Hlp=>"{on|timer|raw|off},echo all events to this client" },
|
||||
"iowrite" => { Fn=>"CommandIOWrite",
|
||||
Hlp=>"<iodev> <data>,write raw data with iodev" },
|
||||
"list" => { Fn=>"CommandList",
|
||||
Hlp=>"[devspec],list definitions and status info" },
|
||||
"modify" => { Fn=>"CommandModify",
|
||||
@ -533,6 +537,33 @@ IOWrite($@)
|
||||
return $ret;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
CommandIOWrite($$)
|
||||
{
|
||||
my ($cl, $param) = @_;
|
||||
my @a = split(" ", $param);
|
||||
|
||||
return "Usage: iowrite <iodev> <param> ..." if(int(@a) <= 2);
|
||||
|
||||
my $name = shift(@a);
|
||||
my $hash = $defs{$name};
|
||||
return "$name not found" if(!$hash);
|
||||
return undef if(IsDummy($name) || IsIgnored($name));
|
||||
if(!$hash->{TYPE} ||
|
||||
!$modules{$hash->{TYPE}} ||
|
||||
!$modules{$hash->{TYPE}}{WriteFn}) {
|
||||
Log 1, "No IO device or WriteFn found for $name";
|
||||
return;
|
||||
}
|
||||
unshift(@a, "") if(int(@a) == 1);
|
||||
no strict "refs";
|
||||
my $ret = &{$modules{$hash->{TYPE}}{WriteFn}}($hash, @a);
|
||||
use strict "refs";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
AnalyzeInput($)
|
||||
@ -1135,10 +1166,12 @@ AssignIoPort($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
# Set the I/O device
|
||||
# Set the I/O device, search for the last compatible one.
|
||||
for my $p (sort { $defs{$b}{NR} <=> $defs{$a}{NR} } keys %defs) {
|
||||
my $cl = $modules{$defs{$p}{TYPE}}{Clients};
|
||||
if(defined($cl) && $cl =~ m/:$hash->{TYPE}:/ &&
|
||||
my $re = $modules{$defs{$p}{TYPE}}{regexpClients};
|
||||
if(((defined($cl) && $cl =~ m/:$hash->{TYPE}:/) ||
|
||||
(defined($re) && $hash->{TYPE} =~ m/$re/)) &&
|
||||
$defs{$p}{NAME} ne $hash->{NAME}) { # e.g. RFR
|
||||
$hash->{IODev} = $defs{$p};
|
||||
last;
|
||||
@ -1675,7 +1708,8 @@ CommandInform($$)
|
||||
|
||||
$param = lc($param);
|
||||
|
||||
return "Usage: inform {on|off|timer}" if($param !~ m/^(on|off|timer)$/);
|
||||
return "Usage: inform {on|timer|raw|off}"
|
||||
if($param !~ m/^(on|off|raw|timer)$/);
|
||||
if($param =~ m/off/) {
|
||||
delete($client{$cl}{inform});
|
||||
} else {
|
||||
@ -1922,7 +1956,7 @@ DoTrigger($$)
|
||||
################
|
||||
# Inform
|
||||
foreach my $c (keys %client) { # Do client loop first, is cheaper
|
||||
next if(!$client{$c}{inform});
|
||||
next if(!$client{$c}{inform} || $client{$c}{inform} eq "raw");
|
||||
my $tn = TimeNow();
|
||||
if($attr{global}{mseclog}) {
|
||||
my ($seconds, $microseconds) = gettimeofday();
|
||||
@ -1930,7 +1964,6 @@ DoTrigger($$)
|
||||
}
|
||||
for(my $i = 0; $i < $max; $i++) {
|
||||
my $state = $defs{$dev}{CHANGED}[$i];
|
||||
my $fe = "$dev:$state";
|
||||
syswrite($client{$c}{fd},
|
||||
($client{$c}{inform} eq "timer" ? "$tn " : "") .
|
||||
"$defs{$dev}{TYPE} $dev $state\n");
|
||||
@ -2125,7 +2158,11 @@ Dispatch($$$)
|
||||
my @found;
|
||||
foreach my $m (sort { $modules{$a}{ORDER} cmp $modules{$b}{ORDER} }
|
||||
grep {defined($modules{$_}{ORDER})} keys %modules) {
|
||||
next if($iohash->{Clients} !~ m/:$m:/);
|
||||
|
||||
my $cl = $iohash->{Clients};
|
||||
my $re = $iohash->{regexpClients};
|
||||
next if(!(defined($cl) && $cl =~ m/:$m:/) ||
|
||||
(defined($re) && $m =~ m/$re/));
|
||||
|
||||
# Module is not loaded or the message is not for this module
|
||||
next if(!$modules{$m}{Match} || $dmsg !~ m/$modules{$m}{Match}/i);
|
||||
@ -2170,6 +2207,15 @@ Dispatch($$$)
|
||||
}
|
||||
}
|
||||
|
||||
################
|
||||
# Inform raw
|
||||
if(!$iohash->{noRawInform}) {
|
||||
foreach my $c (keys %client) {
|
||||
next if(!$client{$c}{inform} || $client{$c}{inform} ne "raw");
|
||||
syswrite($client{$c}{fd}, "$hash->{TYPE} $name $dmsg\n");
|
||||
}
|
||||
}
|
||||
|
||||
return undef if($found[0] eq ""); # Special return: Do not notify
|
||||
|
||||
foreach my $found (@found) {
|
||||
@ -2270,3 +2316,20 @@ ReadingsVal($$$)
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
sub
|
||||
addToAttrList($)
|
||||
{
|
||||
my $arg = shift;
|
||||
|
||||
my $ua = "";
|
||||
$ua = $attr{global}{userattr} if($attr{global}{userattr});
|
||||
my @al = split(" ", $ua);
|
||||
my %hash;
|
||||
foreach my $a (@al) {
|
||||
$hash{$a} = 1;
|
||||
}
|
||||
$hash{$arg} = 1;
|
||||
$attr{global}{userattr} = join(" ", sort keys %hash);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user