mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-07 16:59:18 +00:00
MAX: automatically determine correct IODev
git-svn-id: https://svn.fhem.de/fhem/trunk@2303 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
362969a51f
commit
afe9716965
@ -150,6 +150,14 @@ MAXLAN_Connect($)
|
||||
#Read initial configuration data
|
||||
MAXLAN_ExpectAnswer($hash,"H:");
|
||||
MAXLAN_ExpectAnswer($hash,"M:");
|
||||
|
||||
#We first reset the IODev for all MAX devices using this MAXLAN as a backend.
|
||||
#Parsing the "C:" responses later on will set IODev correctly again.
|
||||
#This effectively removes IODev from all devices that are not longer paired to our Cube.
|
||||
foreach (%{$modules{MAX}{defptr}}) {
|
||||
$modules{MAX}{defptr}{$_}{IODev} = undef if($modules{MAX}{defptr}{$_}{IODev} == $hash);
|
||||
}
|
||||
|
||||
my $rmsg;
|
||||
do
|
||||
{
|
||||
@ -209,7 +217,7 @@ MAXLAN_Set($@)
|
||||
my $time = time()-946684774;
|
||||
my $rmsg = "v:".$timezones.",".sprintf("%08x",$time);
|
||||
my $ret = MAXLAN_Write($hash,$rmsg, "A:");
|
||||
Dispatch($hash, "MAX,CubeClockState,$hash->{rfaddr},1", {RAWMSG => $rmsg}) if(!$ret);
|
||||
Dispatch($hash, "MAX,1,CubeClockState,$hash->{rfaddr},1", {RAWMSG => $rmsg}) if(!$ret);
|
||||
return $ret;
|
||||
|
||||
}elsif($setting eq "factoryReset") {
|
||||
@ -435,9 +443,9 @@ MAXLAN_Parse($$)
|
||||
$hash->{cubeTimeDifference} = $difference;
|
||||
}
|
||||
|
||||
Dispatch($hash, "MAX,define,$hash->{rfaddr},Cube,$hash->{serial},0,1", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,CubeConnectionState,$hash->{rfaddr},1", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,CubeClockState,$hash->{rfaddr},$clockset", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,define,$hash->{rfaddr},Cube,$hash->{serial},0,1", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,CubeConnectionState,$hash->{rfaddr},1", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,CubeClockState,$hash->{rfaddr},$clockset", {RAWMSG => $rmsg});
|
||||
Log $ll5, "MAXLAN_Parse: Got hello, connection ip $args[4], duty cycle $dutycycle, freememory $freememory, clockset $clockset";
|
||||
|
||||
} elsif($cmd eq 'M') {
|
||||
@ -482,7 +490,6 @@ MAXLAN_Parse($$)
|
||||
$hash->{devices}[-1]->{serial} = $groupsdevices[$i+2];
|
||||
$hash->{devices}[-1]->{name} = $groupsdevices[$i+3];
|
||||
$hash->{devices}[-1]->{groupid} = $groupsdevices[$i+4];
|
||||
#Dispatch($hash, "MAX,define,$hash->{devices}[-1]->{addr},$device_types{$hash->{devices}[-1]->{type}},$hash->{devices}[-1]->{serial},$hash->{devices}[-1]->{groupid},1", {RAWMSG => $rmsg});
|
||||
}
|
||||
|
||||
#Log $ll5, "Got Metadata, hash: ".Dumper($hash);
|
||||
@ -502,10 +509,10 @@ MAXLAN_Parse($$)
|
||||
|
||||
$len = $len+1; #The len field itself was not counted
|
||||
|
||||
Dispatch($hash, "MAX,define,$addr,$device_types{$devicetype},$serial,$groupid,1", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,define,$addr,$device_types{$devicetype},$serial,$groupid,1", {RAWMSG => $rmsg});
|
||||
|
||||
if($len != length($bindata)) {
|
||||
Dispatch($hash, "MAX,Error,$addr,Parts of configuration are missing", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,Error,$addr,Parts of configuration are missing", {RAWMSG => $rmsg});
|
||||
return "Invalid C: response, len does not match";
|
||||
}
|
||||
|
||||
@ -527,7 +534,7 @@ MAXLAN_Parse($$)
|
||||
$windowopentemp=$windowopentemp/2.0;
|
||||
$windowopendur=$windowopendur*5;
|
||||
Log $ll5, "comfortemp $comforttemp, ecotemp $ecotemp, boostValve $boostValve, boostDuration $boostDuration, tempoffset $tempoffset, $minsetpointtemp minsetpointtemp, maxsetpointtemp $maxsetpointtemp, windowopentemp $windowopentemp, windowopendur $windowopendur";
|
||||
Dispatch($hash, "MAX,ThermostatConfig,$addr,$ecotemp,$comforttemp,$boostValve,$boostDuration,$tempoffset,$maxsetpointtemp,$minsetpointtemp,$windowopentemp,$windowopendur", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,ThermostatConfig,$addr,$ecotemp,$comforttemp,$boostValve,$boostDuration,$tempoffset,$maxsetpointtemp,$minsetpointtemp,$windowopentemp,$windowopendur", {RAWMSG => $rmsg});
|
||||
|
||||
}elsif($devicetype == 4){#ShutterContact
|
||||
Log 2, "ShutterContact send some configuration, but none was expected" if($len > 18);
|
||||
@ -536,7 +543,7 @@ MAXLAN_Parse($$)
|
||||
}
|
||||
|
||||
#Clear Error
|
||||
Dispatch($hash, "MAX,Error,$addr", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,Error,$addr", {RAWMSG => $rmsg});
|
||||
|
||||
#Check if it is already recorded in devices
|
||||
my $found = 0;
|
||||
@ -576,9 +583,9 @@ MAXLAN_Parse($$)
|
||||
if(!$shash) {
|
||||
Log 2, "Got List response for undefined device with addr $addr";
|
||||
}elsif($shash->{type} eq "HeatingThermostat" or $shash->{type} eq "WallMountedThermostat"){
|
||||
Dispatch($hash, "MAX,ThermostatState,$addr,$payload", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,ThermostatState,$addr,$payload", {RAWMSG => $rmsg});
|
||||
}elsif($shash->{type} eq "ShutterContact"){
|
||||
Dispatch($hash, "MAX,ShutterContactState,$addr,$payload", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,ShutterContactState,$addr,$payload", {RAWMSG => $rmsg});
|
||||
}else{
|
||||
Log 2, "Got status for unimplemented device type $shash->{type}";
|
||||
}
|
||||
@ -594,7 +601,7 @@ MAXLAN_Parse($$)
|
||||
}
|
||||
my ($type, $addr, $serial) = unpack("CH6a[10]", decode_base64($args[0]));
|
||||
Log 2, "Paired new device, type $device_types{$type}, addr $addr, serial $serial";
|
||||
Dispatch($hash, "MAX,define,$addr,$device_types{$type},$serial,0,1", {RAWMSG => $rmsg});
|
||||
Dispatch($hash, "MAX,1,define,$addr,$device_types{$type},$serial,0,1", {RAWMSG => $rmsg});
|
||||
|
||||
#After a device has been paired, it automatically appears in the "L" and "C" commands,
|
||||
MAXLAN_RequestConfiguration($hash,$addr);
|
||||
@ -726,7 +733,12 @@ MAXLAN_RemoveDevice($$)
|
||||
{
|
||||
my ($hash,$addr) = @_;
|
||||
#This does a factoryReset on the Device
|
||||
return MAXLAN_Write($hash,"t:1,1,".encode_base64(pack("H6",$addr),""), "A:");
|
||||
my $ret = MAXLAN_Write($hash,"t:1,1,".encode_base64(pack("H6",$addr),""), "A:");
|
||||
if(!defined($ret)) { #success
|
||||
#The device is not longer accessable by the Cube
|
||||
$modules{MAX}{defptr}{$addr}{IODev} = undef;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -95,7 +95,6 @@ MAX_Define($$)
|
||||
$hash->{type} = $type;
|
||||
$hash->{addr} = $addr;
|
||||
$hash->{STATE} = "waiting for data";
|
||||
$hash->{usingCube} = 0;
|
||||
$modules{MAX}{defptr}{$addr} = $hash;
|
||||
|
||||
$hash->{internals}{interfaces} = $interfaces{$type};
|
||||
@ -306,7 +305,9 @@ sub
|
||||
MAX_Parse($$)
|
||||
{
|
||||
my ($hash, $msg) = @_;
|
||||
my ($MAX,$msgtype,$addr,@args) = split(",",$msg);
|
||||
my ($MAX,$isToMe,$msgtype,$addr,@args) = split(",",$msg);
|
||||
#$isToMe is 1 if the message was direct at the device $hash, and 0
|
||||
#if we just snooped a message directed at a different device (by CUL_MAX).
|
||||
return if($MAX ne "MAX");
|
||||
|
||||
Log 5, "MAX_Parse $msg";
|
||||
@ -327,6 +328,9 @@ MAX_Parse($$)
|
||||
}
|
||||
}
|
||||
|
||||
#if $isToMe is true, then the message was directed at device $hash, thus we can also use it for sending
|
||||
$shash->{IODev} = $hash if($isToMe);
|
||||
|
||||
if($msgtype eq "define"){
|
||||
my $devicetype = $args[0];
|
||||
Log 1, "Device changed type from $shash->{type} to $devicetype" if($shash->{type} ne $devicetype);
|
||||
@ -336,7 +340,6 @@ MAX_Parse($$)
|
||||
$shash->{serial} = $serial;
|
||||
}
|
||||
$shash->{groupid} = $args[2];
|
||||
$shash->{usingCube} = $args[3];
|
||||
$shash->{IODev} = $hash;
|
||||
|
||||
} elsif($msgtype eq "ThermostatState") {
|
||||
@ -444,9 +447,9 @@ MAX_Parse($$)
|
||||
#with unknown meaning plus the data of a State broadcast from the same device
|
||||
#For HeatingThermostats, it does not contain the last three "until" bytes (or measured temperature)
|
||||
if($shash->{type} ~~ ["HeatingThermostat", "WallMountedThermostat"] ) {
|
||||
return MAX_Parse($hash, "MAX,ThermostatState,$addr,". substr($args[0],2));
|
||||
return MAX_Parse($hash, "MAX,$isToMe,ThermostatState,$addr,". substr($args[0],2));
|
||||
} elsif($shash->{type} eq "ShutterContact") {
|
||||
return MAX_Parse($hash, "MAX,ShutterContactState,$addr,". substr($args[0],2));
|
||||
return MAX_Parse($hash, "MAX,$isToMe,ShutterContactState,$addr,". substr($args[0],2));
|
||||
} elsif($shash->{type} eq "Cube") {
|
||||
; #Payload is always "00"
|
||||
} else {
|
||||
|
@ -138,9 +138,15 @@ CUL_MAX_Parse($$)
|
||||
$dst = lc($dst);
|
||||
my $msgType = exists($msgId2Cmd{$msgTypeRaw}) ? $msgId2Cmd{$msgTypeRaw} : $msgTypeRaw;
|
||||
Log 5, "CUL_MAX_Parse: len $len, msgcnt $msgcnt, msgflag $msgFlag, msgTypeRaw $msgType, src $src, dst $dst, groupid $groupid, payload $payload";
|
||||
my $isToMe = ($dst eq $shash->{addr}) ? 1 : 0; # $isToMe is true if that packet was directed at us
|
||||
|
||||
if(exists($msgId2Cmd{$msgTypeRaw})) {
|
||||
|
||||
if($msgType eq "Ack") {
|
||||
Dispatch($shash, "MAX,Ack,$src,$payload", {RAWMSG => $rmsg});
|
||||
Dispatch($shash, "MAX,$isToMe,Ack,$src,$payload", {RAWMSG => $rmsg});
|
||||
|
||||
return undef if(!$isToMe);
|
||||
|
||||
my $i = 0;
|
||||
while ($i < @waitForAck) {
|
||||
my $packet = $waitForAck[$i];
|
||||
@ -154,7 +160,7 @@ CUL_MAX_Parse($$)
|
||||
}
|
||||
|
||||
} elsif($msgType eq "TimeInformation") {
|
||||
if($dst eq $shash->{addr}) {
|
||||
if($isToMe) {
|
||||
#This is a request for TimeInformation send to us
|
||||
Log 5, "Got request for TimeInformation, sending it";
|
||||
CUL_MAX_SendTimeInformation($shash, $src);
|
||||
@ -188,16 +194,16 @@ CUL_MAX_Parse($$)
|
||||
Log 3, "CUL_MAX_Parse: Pairing device $src of type $device_types{$type} with serial $serial";
|
||||
CUL_MAX_Send($shash, "PairPong", $src, "00");
|
||||
#TODO: wait for Ack
|
||||
Dispatch($shash, "MAX,define,$src,$device_types{$type},$serial,0,0", {RAWMSG => $rmsg});
|
||||
Dispatch($shash, "MAX,$isToMe,define,$src,$device_types{$type},$serial,0,0", {RAWMSG => $rmsg});
|
||||
if($device_types{$type} eq "HeatingThermostat" or $device_types{$type} eq "WallMountedThermostat") {
|
||||
#This are the default values that a device has after factory reset or pairing
|
||||
Dispatch($shash, "MAX,ThermostatConfig,$src,17,21,80,5,0,30.5,4.5,12,15", {RAWMSG => $rmsg});
|
||||
Dispatch($shash, "MAX,$isToMe,ThermostatConfig,$src,17,21,80,5,0,30.5,4.5,12,15", {RAWMSG => $rmsg});
|
||||
}
|
||||
#TODO: send TimeInformation
|
||||
}
|
||||
|
||||
} elsif($msgType ~~ ["ShutterContactState", "WallThermostatState", "ThermostatState"]) {
|
||||
Dispatch($shash, "MAX,$msgType,$src,$payload", {RAWMSG => $rmsg});
|
||||
Dispatch($shash, "MAX,$isToMe,$msgType,$src,$payload", {RAWMSG => $rmsg});
|
||||
#Only ShutterContactState needs ack
|
||||
if($msgType eq "ShutterContactState" and $dst eq $shash->{addr}) {
|
||||
CUL_MAX_SendAck($shash,$msgcnt,$dst);
|
||||
|
Loading…
x
Reference in New Issue
Block a user