diff --git a/fhem/FHEM/00_MAXLAN.pm b/fhem/FHEM/00_MAXLAN.pm index 6ec9e1660..2d6da5bd5 100755 --- a/fhem/FHEM/00_MAXLAN.pm +++ b/fhem/FHEM/00_MAXLAN.pm @@ -219,6 +219,10 @@ MAXLAN_Set($@) }elsif($setting eq "reconnect") { MAXLAN_Disconnect($hash); MAXLAN_Connect($hash) if($hash->{persistent}); + + }elsif($setting eq "inject") { + MAXLAN_Parse($hash,$args[0]); + }else{ return "Unknown argument $setting, choose one of pairmode raw clock factoryReset reconnect"; } @@ -476,8 +480,9 @@ MAXLAN_Parse($$) #Seems that ShutterContact does not have any configdata if($devicetype == 0){#Cube #TODO: there is a lot of data left to interpret - }elsif($devicetype == 1){#HeatingThermostat - my ($comforttemp,$ecotemp,$maxsetpointtemp,$minsetpointtemp,$tempoffset,$windowopentemp,$windowopendur,$boost,$decalcifiction,$maxvalvesetting,$valveoffset) = unpack("CCCCCCCCCCC",substr($bindata,18)); + }elsif($devicetype == 1 or $devicetype == 3){#HeatingThermostat or #WallMountedThermostat + my ($comforttemp,$ecotemp,$maxsetpointtemp,$minsetpointtemp,$tempoffset,$windowopentemp,$windowopendur,$boost,$decalcifiction,$maxvalvesetting,$valveoffset,$weekprofile) = unpack("CCCCCCCCCCCa*",substr($bindata,18)); + #TODO: parse week profile my $boostValve = ($boost & 0x1F) * 5; my $boostDuration = $boost_durations[$boost >> 5]; #in minutes #There is some trailing data missing, which maps to the weekly program @@ -489,8 +494,9 @@ 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,HeatingThermostatConfig,$addr,$ecotemp,$comforttemp,$boostValve,$boostDuration,$tempoffset,$maxsetpointtemp,$minsetpointtemp,$windowopentemp,$windowopendur", {RAWMSG => $rmsg}); - }elsif($devicetype == 4){#ShutterContact TODO + Dispatch($hash, "MAX,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); }else{ #TODO Log 2, "Got configdata for unimplemented devicetype $devicetype"; @@ -536,8 +542,8 @@ MAXLAN_Parse($$) if(!$shash) { Log 2, "Got List response for undefined device with addr $addr"; - }elsif($shash->{type} eq "HeatingThermostat"){ - Dispatch($hash, "MAX,HeatingThermostatState,$addr,$payload", {RAWMSG => $rmsg}); + }elsif($shash->{type} eq "HeatingThermostat" or $shash->{type} eq "WallMountedThermostat"){ + Dispatch($hash, "MAX,ThermostatState,$addr,$payload", {RAWMSG => $rmsg}); }elsif($shash->{type} eq "ShutterContact"){ Dispatch($hash, "MAX,ShutterContactState,$addr,$payload", {RAWMSG => $rmsg}); }else{ diff --git a/fhem/FHEM/10_MAX.pm b/fhem/FHEM/10_MAX.pm index b4bc2d0cc..b78e51c51 100755 --- a/fhem/FHEM/10_MAX.pm +++ b/fhem/FHEM/10_MAX.pm @@ -84,9 +84,8 @@ MAX_Set($@) my ($hash, $devname, @a) = @_; my ($setting, @args) = @a; - if($setting eq "desiredTemperature"){ + if($setting eq "desiredTemperature" and ($hash->{type} eq "HeatingThermostat" or $hash->{type} eq "WallMountedThermostat")) { return "Cannot set without IODev" if(!defined($hash->{IODev})); - return "can only set desiredTemperature for HeatingThermostat" if($hash->{type} ne "HeatingThermostat"); return "missing a value" if(@args == 0); my $temperature; @@ -138,9 +137,8 @@ MAX_Set($@) return ($hash->{IODev}{SendDeviceCmd})->($hash->{IODev},pack("CCCCCCH6CC",0x00,0x00,34,0x00,0x00,0x00,$hash->{addr},0x00,$args[0])); - }elsif( $setting ~~ ["ecoTemperature", "comfortTemperature", "measurementOffset", "maximumTemperature", "minimumTemperature", "windowOpenTemperature", "windowOpenDuration" ]) { + }elsif( $setting ~~ ["ecoTemperature", "comfortTemperature", "measurementOffset", "maximumTemperature", "minimumTemperature", "windowOpenTemperature", "windowOpenDuration" ] and ($hash->{type} eq "HeatingThermostat" or $hash->{type} eq "WallMountedThermostat")) { return "Cannot set without IODev" if(!exists($hash->{IODev})); - return "can only set configuration for HeatingThermostat" if($hash->{type} ne "HeatingThermostat"); readingsSingleUpdate($hash, $setting, $args[0], 0); @@ -180,14 +178,25 @@ MAX_Set($@) return "IODev does not need removeDevice"; } + } elsif($setting eq "displayActualTemperature" and $hash->{type} eq "WallMountedThermostat") { + return "Cannot set without IODev" if(!exists($hash->{IODev})); + return "Invalid arg" if($args[0] ne "0" and $args[0] ne "1"); + + readingsSingleUpdate($hash, $setting, $args[0], 0); + my $payload = pack("CCCCCCH6CC",0x00,0x00,0x82,0x00,0x00,0x00,$hash->{addr},0x00, $args[0] ? 4 : 0); + return ($hash->{IODev}{SendDeviceCmd})->($hash->{IODev},$payload); + }else{ my $removeDevice = exists($hash->{IODev}{RemoveDevice}) ? " removeDevice" : ""; + my $templist = join(",",map { sprintf("%2.1f",$_/2) } (9..61)); if($hash->{type} eq "HeatingThermostat") { #Create numbers from 4.5 to 30.5 - my $templist = join(",",map { sprintf("%2.1f",$_/2) } (9..61)); my $templistOffset = join(",",map { sprintf("%2.1f",($_-7)/2) } (0..14)); return "Unknown argument $setting, choose one of desiredTemperature:eco,comfort,boost,auto,$templist ecoTemperature:$templist comfortTemperature:$templist measurementOffset:$templistOffset maximumTemperature:$templist minimumTemperature:$templist windowOpenTemperature:$templist windowOpenDuration groupid$removeDevice"; + + } elsif($hash->{type} eq "WallMountedThermostat") { + return "Unknown argument $setting, choose one of displayActualTemperature:0,1 desiredTemperature:eco,comfort,boost,auto,$templist groupid$removeDevice"; } else { return "Unknown argument $setting, choose one of groupid$removeDevice"; } @@ -229,7 +238,6 @@ MAX_Parse($$) $devicetype = $args[0] if($msgtype eq "define"); $devicetype = "ShutterContact" if($msgtype eq "ShutterContactState"); $devicetype = "Cube" if($msgtype eq "CubeClockState" or $msgtype eq "CubeConnectionState"); - $devicetype = "HeatingThermostat" if($msgtype eq "HeatingThermostatConfig" or $msgtype eq "HeatingThermostatState"); if($devicetype) { return "UNDEFINED MAX_$addr MAX $devicetype $addr"; } else { @@ -250,7 +258,7 @@ MAX_Parse($$) $shash->{usingCube} = $args[3]; $shash->{IODev} = $hash; - } elsif($msgtype eq "HeatingThermostatState") { + } elsif($msgtype eq "ThermostatState") { my ($bits2,$valveposition,$temperaturesetpoint,$until1,$until2,$until3) = unpack("aCCCCC",pack("H*",$args[0])); my $mode = vec($bits2, 0, 2); # @@ -294,7 +302,12 @@ MAX_Parse($$) readingsBulkUpdate($shash, "battery", $batterylow ? "low" : "ok"); #This formatting must match with in MAX_Set:$templist readingsBulkUpdate($shash, "desiredTemperature", sprintf("%2.1f",$temperaturesetpoint)); - readingsBulkUpdate($shash, "valveposition", $valveposition); + if($shash->{type} eq "HeatingThermostat") { + readingsBulkUpdate($shash, "valveposition", $valveposition); + } else { + #This is a WallMountedThermostat + readingsBulkUpdate($shash, "displayActualTemperature", $valveposition ? 1 : 0); + } if($measuredTemperature ne "") { readingsBulkUpdate($shash, "temperature", $measuredTemperature); } @@ -324,7 +337,7 @@ MAX_Parse($$) readingsSingleUpdate($shash,"connection",$connected, 0); - } elsif($msgtype eq "HeatingThermostatConfig") { + } elsif($msgtype eq "ThermostatConfig") { readingsBeginUpdate($shash); readingsBulkUpdate($shash, "ecoTemperature", $args[0]); readingsBulkUpdate($shash, "comfortTemperature", $args[1]); @@ -334,7 +347,7 @@ MAX_Parse($$) readingsBulkUpdate($shash, "maximumTemperature", $args[5]); readingsBulkUpdate($shash, "minimumTemperature", $args[6]); readingsBulkUpdate($shash, "windowOpenTemperature", $args[7]); - readingsBulkUpdate($shash, "windowOpenDuration", $args[8]); + readingsBulkUpdate($shash, "windowOpenDuration", $args[8]) if($shash->{type} eq "HeatingThermostat"); readingsEndUpdate($shash, 0); } elsif($msgtype eq "Error") { diff --git a/fhem/FHEM/14_CUL_MAX.pm b/fhem/FHEM/14_CUL_MAX.pm index e2043c87a..0a4dd96fc 100644 --- a/fhem/FHEM/14_CUL_MAX.pm +++ b/fhem/FHEM/14_CUL_MAX.pm @@ -114,7 +114,8 @@ my %msgTypes = ( #Receiving: "02" => "Ack", "03" => "TimeInformation", "30" => "ShutterContactState", - "60" => "HeatingThermostatState" + "42" => "WallThermostatState", #by WallMountedThermostat + "60" => "ThermostatState", #by HeatingThermostat ); my %sendTypes = (#Sending: "PairPong" => "01", @@ -151,7 +152,7 @@ CUL_MAX_Parse($$) if(exists($msgTypes{$msgTypeRaw})) { my $msgType = $msgTypes{$msgTypeRaw}; if($msgType eq "Ack") { - #The Ack payload for HeatingThermostats is 01HHHHHH where HHHHHH are the first 3 bytes of the HeatingThermostatState payload + #TODO: The Ack payload for HeatingThermostats is 01HHHHHH where HHHHHH are the first 3 bytes of the HeatingThermostatState payload Log 5, "Got Ack"; } elsif($msgType eq "TimeInformation") { @@ -170,15 +171,20 @@ CUL_MAX_Parse($$) my $unk2 = $f4 >> 6; my $unk3 = $f5 >> 6; #I guess the unk1,2,3 encode if we are in DST? - Log 5, "Got TimeInformation: (in GMT) year $year, mon $month, day $day, hour $hour, min $min, sec $sec, unk ($unk1, $unk2, $unk3)"; + Log 5, "CUL_MAX_Parse: Got TimeInformation: (in GMT) year $year, mon $month, day $day, hour $hour, min $min, sec $sec, unk ($unk1, $unk2, $unk3)"; } } elsif($msgType eq "PairPing") { my ($unk1,$type,$unk2,$serial) = unpack("CCCa*",pack("H*",$payload)); - Log 5, "Got PairPing (pairmode $shash->{pairmode}), unk1 $unk1, type $type, unk2 $unk2, serial $serial"; + Log 5, "CUL_MAX_Parse: Got PairPing (pairmode $shash->{pairmode}), unk1 $unk1, type $type, unk2 $unk2, serial $serial"; if($shash->{pairmode}) { + Log 3, "CUL_MAX_Parse: Pairing device $src of type $device_types{$type} with serial $serial"; CUL_MAX_Send($shash, "PairPong", $src, "00", "00000000"); #TODO: wait for Ack Dispatch($shash, "MAX,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($hash, "MAX,ThermostatConfig,$src,17,21,80,5,0,30.5,4.5,12,15", {RAWMSG => $rmsg}); + } #TODO: send TimeInformation } @@ -186,7 +192,7 @@ CUL_MAX_Parse($$) Dispatch($shash, "MAX,$msgType,$src,$payload", {RAWMSG => $rmsg}); } } else { - Log 2, "Got unhandled message type $msgTypeRaw"; + Log 2, "CUL_MAX_Parse: Got unhandled message type $msgTypeRaw"; } return undef; }