From 46feea8680653f556673b8a1afb0ac2739fec128 Mon Sep 17 00:00:00 2001
From: telekatz <>
Date: Mon, 14 Nov 2016 21:11:32 +0000
Subject: [PATCH] 30_DUOFERN: add thermostat, motion detector and wall
controller 230V/BAT
git-svn-id: https://svn.fhem.de/fhem/trunk@12577 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/30_DUOFERN.pm | 369 ++++++++++++++++++++++++++--------------
1 file changed, 237 insertions(+), 132 deletions(-)
diff --git a/fhem/FHEM/30_DUOFERN.pm b/fhem/FHEM/30_DUOFERN.pm
index ed8a4ec9a..3374e949d 100644
--- a/fhem/FHEM/30_DUOFERN.pm
+++ b/fhem/FHEM/30_DUOFERN.pm
@@ -25,6 +25,8 @@ my %devices = (
"69" => "Umweltsensor",
"70" => "Troll Comfort DuoFern",
"71" => "Troll Comfort DuoFern (Lichtmodus)",
+ "73" => "Raumthermostat",
+ "74" => "Wandtaster 6fach 230V",
"A0" => "Handsender (6 Gruppen-48 Geraete)",
"A1" => "Handsender (1 Gruppe-48 Geraete)",
"A2" => "Handsender (6 Gruppen-1 Geraet)",
@@ -35,6 +37,7 @@ my %devices = (
"A8" => "HomeTimer",
"AA" => "Markisenwaechter",
"AB" => "Rauchmelder",
+ "AD" => "Wandtaster 6fach Bat",
);
my %sensorMsg = (
@@ -58,6 +61,8 @@ my %sensorMsg = (
"071F" => {"name" => "endSmoke", "chan" => 5, "state" => "off"},
"0720" => {"name" => "startMotion", "chan" => 5, "state" => "on"},
"0721" => {"name" => "endMotion", "chan" => 5, "state" => "off"},
+ "0723" => {"name" => "closeEnd", "chan" => 5, "state" => "off"},
+ "0724" => {"name" => "closeStart", "chan" => 5, "state" => "on"},
"0E01" => {"name" => "off", "chan" => 6, "state" => "Btn01"},
"0E02" => {"name" => "off", "chan" => 6, "state" => "Btn02"},
"0E03" => {"name" => "on", "chan" => 6, "state" => "Btn03"},
@@ -97,93 +102,104 @@ my %openSpeeds = (
);
my %commands = (
- "remotePair" => {"noArg" => "06010000000000"},
- "remoteUnpair" => {"noArg" => "06020000000000"},
- "up" => {"noArg" => "0701tt00000000"},
- "stop" => {"noArg" => "07020000000000"},
- "down" => {"noArg" => "0703tt00000000"},
- "position" => {"value" => "0707ttnn000000"},
- "level" => {"value" => "0707ttnn000000"},
- "sunMode" => {"on" => "070801FF000000",
- "off" => "070A0100000000"},
- "dusk" => {"noArg" => "070901FF000000"},
- "reversal" => {"noArg" => "070C0000000000"},
- "modeChange" => {"noArg" => "070C0000000000"},
- "windMode" => {"on" => "070D01FF000000",
- "off" => "070E0100000000"},
- "rainMode" => {"on" => "071101FF000000",
- "off" => "07120100000000"},
- "dawn" => {"noArg" => "071301FF000000"},
- "rainDirection" => {"down" => "071400FD000000",
- "up" => "071400FE000000"},
- "windDirection" => {"down" => "071500FD000000",
- "up" => "071500FE000000"},
- "toggle" => {"noArg" => "071A0000000000"},
- "slatPosition" => {"value" => "071B00000000nn"},
- "sunAutomatic" => {"on" => "080100FD000000",
- "off" => "080100FE000000"},
- "sunPosition" => {"value" => "080100nn000000"},
- "ventilatingMode" => {"on" => "080200FD000000",
- "off" => "080200FE000000"},
- "ventilatingPosition" => {"value" => "080200nn000000"},
- "intermediateMode" => {"on" => "080200FD000000",
- "off" => "080200FE000000"},
- "intermediateValue" => {"value" => "080200nn000000"},
- "saveIntermediateOnStop"=>{"on" => "080200FB000000",
- "off" => "080200FC000000"},
- "runningTime" => {"value3" => "0803nn00000000"},
- "timeAutomatic" => {"on" => "080400FD000000",
- "off" => "080400FE000000"},
- "duskAutomatic" => {"on" => "080500FD000000",
- "off" => "080500FE000000"},
- "manualMode" => {"on" => "080600FD000000",
- "off" => "080600FE000000"},
- "windAutomatic" => {"on" => "080700FD000000",
- "off" => "080700FE000000"},
- "rainAutomatic" => {"on" => "080800FD000000",
- "off" => "080800FE000000"},
- "dawnAutomatic" => {"on" => "080900FD000000",
- "off" => "080900FE000000"},
- "tiltInSunPos" => {"on" => "080C00FD000000",
- "off" => "080C00FE000000"},
- "tiltInVentPos" => {"on" => "080D00FD000000",
- "off" => "080D00FE000000"},
- "tiltAfterMoveLevel" => {"on" => "080E00FD000000",
- "off" => "080E00FE000000"},
- "tiltAfterStopDown" => {"on" => "080F00FD000000",
- "off" => "080F00FE000000"},
- "defaultSlatPos" => {"value" => "0810nn00000000"},
- "blindsMode" => {"on" => "081100FD000000",
- "off" => "081100FE000000"},
- "slatRunTime" => {"value4" => "0812nn00000000"},
- "motorDeadTime" => {"off" => "08130000000000",
- "short" => "08130100000000",
- "long" => "08130200000000"},
- "stairwellFunction" => {"on" => "081400FD000000",
- "off" => "081400FE000000"},
- "stairwellTime" => {"value2" => "08140000wwww00"},
- "reset" => {"settings" => "0815CB00000000",
- "full" => "0815CC00000000"},
- "10minuteAlarm" => {"on" => "081700FD000000",
- "off" => "081700FE000000"},
- "automaticClosing" => {"off" => "08180000000000",
- "30" => "08180001000000",
- "60" => "08180002000000",
- "90" => "08180003000000",
- "120" => "08180004000000",
- "150" => "08180005000000",
- "180" => "08180006000000",
- "210" => "08180007000000",
- "240" => "08180008000000"},
- "2000cycleAlarm" => {"on" => "081900FD000000",
- "off" => "081900FE000000"},
- "openSpeed" => {"11" => "081A0001000000",
- "15" => "081A0002000000",
- "19" => "081A0003000000"},
- "backJump" => {"on" => "081B00FD000000",
- "off" => "081B00FE000000"},
- "on" => {"noArg" => "0E03tt00000000"},
- "off" => {"noArg" => "0E02tt00000000"},
+ "remotePair" => {"noArg" => "06010000000000000000"},
+ "remoteUnpair" => {"noArg" => "06020000000000000000"},
+ "up" => {"noArg" => "0701tt00000000000000"},
+ "stop" => {"noArg" => "07020000000000000000"},
+ "down" => {"noArg" => "0703tt00000000000000"},
+ "position" => {"value" => "0707ttnn000000000000"},
+ "level" => {"value" => "0707ttnn000000000000"},
+ "sunMode" => {"on" => "070801FF000000000000",
+ "off" => "070A0100000000000000"},
+ "dusk" => {"noArg" => "070901FF000000000000"},
+ "reversal" => {"noArg" => "070C0000000000000000"},
+ "modeChange" => {"noArg" => "070C0000000000000000"},
+ "windMode" => {"on" => "070D01FF000000000000",
+ "off" => "070E0100000000000000"},
+ "rainMode" => {"on" => "071101FF000000000000",
+ "off" => "07120100000000000000"},
+ "dawn" => {"noArg" => "071301FF000000000000"},
+ "rainDirection" => {"down" => "071400FD000000000000",
+ "up" => "071400FE000000000000"},
+ "windDirection" => {"down" => "071500FD000000000000",
+ "up" => "071500FE000000000000"},
+ "tempUp" => {"noArg" => "0718tt00000000000000"},
+ "tempDown" => {"noArg" => "0719tt00000000000000"},
+ "toggle" => {"noArg" => "071A0000000000000000"},
+ "slatPosition" => {"value" => "071B00000000nn000000"},
+ "desired-temp" => {"temp1" => "0722tt0000wwww000000"},
+ "sunAutomatic" => {"on" => "080100FD000000000000",
+ "off" => "080100FE000000000000"},
+ "sunPosition" => {"value" => "080100nn000000000000"},
+ "ventilatingMode" => {"on" => "080200FD000000000000",
+ "off" => "080200FE000000000000"},
+ "ventilatingPosition" => {"value" => "080200nn000000000000"},
+ "intermediateMode" => {"on" => "080200FD000000000000",
+ "off" => "080200FE000000000000"},
+ "intermediateValue" => {"value" => "080200nn000000000000"},
+ "saveIntermediateOnStop"=>{"on" => "080200FB000000000000",
+ "off" => "080200FC000000000000"},
+ "runningTime" => {"value3" => "0803nn00000000000000"},
+ "timeAutomatic" => {"on" => "080400FD000000000000",
+ "off" => "080400FE000000000000"},
+ "duskAutomatic" => {"on" => "080500FD000000000000",
+ "off" => "080500FE000000000000"},
+ "manualMode" => {"on" => "080600FD000000000000",
+ "off" => "080600FE000000000000"},
+ "windAutomatic" => {"on" => "080700FD000000000000",
+ "off" => "080700FE000000000000"},
+ "rainAutomatic" => {"on" => "080800FD000000000000",
+ "off" => "080800FE000000000000"},
+ "dawnAutomatic" => {"on" => "080900FD000000000000",
+ "off" => "080900FE000000000000"},
+ "tiltInSunPos" => {"on" => "080C00FD000000000000",
+ "off" => "080C00FE000000000000"},
+ "tiltInVentPos" => {"on" => "080D00FD000000000000",
+ "off" => "080D00FE000000000000"},
+ "tiltAfterMoveLevel" => {"on" => "080E00FD000000000000",
+ "off" => "080E00FE000000000000"},
+ "tiltAfterStopDown" => {"on" => "080F00FD000000000000",
+ "off" => "080F00FE000000000000"},
+ "defaultSlatPos" => {"value" => "0810nn00000000000000"},
+ "blindsMode" => {"on" => "081100FD000000000000",
+ "off" => "081100FE000000000000"},
+ "slatRunTime" => {"value4" => "0812nn00000000000000"},
+ "motorDeadTime" => {"off" => "08130000000000000000",
+ "short" => "08130100000000000000",
+ "long" => "08130200000000000000"},
+ "stairwellFunction" => {"on" => "081400FD000000000000",
+ "off" => "081400FE000000000000"},
+ "stairwellTime" => {"value2" => "08140000wwww00000000"},
+ "reset" => {"settings" => "0815CB00000000000000",
+ "full" => "0815CC00000000000000"},
+ "10minuteAlarm" => {"on" => "081700FD000000000000",
+ "off" => "081700FE000000000000"},
+ "automaticClosing" => {"off" => "08180000000000000000",
+ "30" => "08180001000000000000",
+ "60" => "08180002000000000000",
+ "90" => "08180003000000000000",
+ "120" => "08180004000000000000",
+ "150" => "08180005000000000000",
+ "180" => "08180006000000000000",
+ "210" => "08180007000000000000",
+ "240" => "08180008000000000000"},
+ "2000cycleAlarm" => {"on" => "081900FD000000000000",
+ "off" => "081900FE000000000000"},
+ "openSpeed" => {"11" => "081A0001000000000000",
+ "15" => "081A0002000000000000",
+ "19" => "081A0003000000000000"},
+ "backJump" => {"on" => "081B00FD000000000000",
+ "off" => "081B00FE000000000000"},
+ "temperatureThreshold1"=> {"temp2" => "081E00000001nn000000"},
+ "temperatureThreshold2"=> {"temp2" => "081E0000000200nn0000"},
+ "temperatureThreshold3"=> {"temp2" => "081E000000040000nn00"},
+ "temperatureThreshold4"=> {"temp2" => "081E00000008000000nn"},
+ "actTempLimit" => {"1" => "081Ett00001000000000",
+ "2" => "081Ett00003000000000",
+ "3" => "081Ett00005000000000",
+ "4" => "081Ett00007000000000"},
+ "on" => {"noArg" => "0E03tt00000000000000"},
+ "off" => {"noArg" => "0E02tt00000000000000"},
);
my %wCmds = (
@@ -234,9 +250,14 @@ my %commandsStatus = (
"getTime" => "10",
);
+my %setsBasic = (
+ "reset:settings,full" => "",
+ "remotePair:noArg" => "",
+ "remoteUnpair:noArg" => "",
+);
+
my %setsDefaultRollerShutter = (
"getStatus:noArg" => "",
- "reset:settings,full" => "",
"up:noArg" => "",
"down:noArg" => "",
"stop:noArg" => "",
@@ -253,8 +274,6 @@ my %setsDefaultRollerShutter = (
"sunAutomatic:on,off" => "",
"timeAutomatic:on,off" => "",
"ventilatingMode:on,off" => "",
- "remotePair:noArg" => "",
- "remoteUnpair:noArg" => "",
);
my %setsRolloTube = (
@@ -291,7 +310,6 @@ my %setsBlinds = (
my %setsSwitchActor = (
"getStatus:noArg" => "",
- "reset:settings,full" => "",
"dawnAutomatic:on,off" => "",
"duskAutomatic:on,off" => "",
"manualMode:on,off" => "",
@@ -303,15 +321,12 @@ my %setsSwitchActor = (
"stairwellTime:slider,0,10,3200" => "",
"on:noArg" => "",
"off:noArg" => "",
- "remotePair:noArg" => "",
- "remoteUnpair:noArg" => "",
"dusk:noArg" => "",
"dawn:noArg" => "",
);
my %setsUmweltsensor = (
"getStatus:noArg" => "",
- "reset:settings,full" => "",
"getWeather:noArg" => "",
"getTime:noArg" => "",
);
@@ -350,7 +365,6 @@ my %setsUmweltsensor01 = (
my %setsSX5 = (
"getStatus:noArg" => "",
- "reset:settings,full" => "",
"up:noArg" => "",
"down:noArg" => "",
"stop:noArg" => "",
@@ -364,13 +378,10 @@ my %setsSX5 = (
"2000cycleAlarm:on,off" => "",
"openSpeed:11,15,19" => "",
"backJump:on,off" => "",
- "remotePair:noArg" => "",
- "remoteUnpair:noArg" => "",
);
my %setsDimmer = (
"getStatus:noArg" => "",
- "reset:settings,full" => "",
"level:slider,0,1,100" => "",
"on:noArg" => "",
"off:noArg" => "",
@@ -387,14 +398,28 @@ my %setsDimmer = (
"intermediateMode:on,off" => "",
"intermediateValue:slider,0,1,100" => "",
"saveIntermediateOnStop:on,off" => "",
- "remotePair:noArg" => "",
- "remoteUnpair:noArg" => "",
"dusk:noArg" => "",
"dawn:noArg" => "",
);
+
+my $tempSetList = "4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0,15.5,16.0,16.5,17.0,17.5,18.0,18.5,19.0,19.5,20.0,20.5,21.0,21.5,22.0,22.5,23.0,23.5,24.0,24.5,25.0,25.5,26.0,26.5,27.0,27.5,28.0,28.5,29.0,29.5,30.0";
+
+my %setsThermostat = (
+ "getStatus:noArg" => "",
+ "tempUp:noArg" => "",
+ "tempDown:noArg" => "",
+ "manualMode:on,off" => "",
+ "timeAutomatic:on,off" => "",
+ "temperatureThreshold1:$tempSetList" => "",
+ "temperatureThreshold2:$tempSetList" => "",
+ "temperatureThreshold3:$tempSetList" => "",
+ "temperatureThreshold4:$tempSetList" => "",
+ "actTempLimit:0,1,2,3" => "",
+ "desired-temp:$tempSetList" => "",
+);
my $duoStatusRequest = "0DFFnn400000000000000000000000000000yyyyyy01";
-my $duoCommand = "0Dccnnnnnnnnnnnnnn000000000000zzzzzzyyyyyy00";
+my $duoCommand = "0Dccnnnnnnnnnnnnnnnnnnnn000000zzzzzzyyyyyy00";
my $duoWeatherConfig = "0D001B400000000000000000000000000000yyyyyy00";
my $duoWeatherWriteConfig = "0DFF1Brrnnnnnnnnnnnnnnnnnnnn00000000yyyyyy00";
my $duoSetTime = "0D0110800001mmmmmmmmnnnnnn0000000000yyyyyy00";
@@ -435,18 +460,20 @@ DUOFERN_Set($@)
my %sets;
- %sets = (%setsDefaultRollerShutter, %setsRolloTube) if ($hash->{CODE} =~ /^49..../);
- %sets = (%setsDefaultRollerShutter, %setsTroll, ("blindsMode:on,off"=> "")) if ($hash->{CODE} =~ /^(42|4B|4C|70)..../);
- %sets = (%setsDefaultRollerShutter, %setsTroll) if ($hash->{CODE} =~ /^47..../);
- %sets = (%setsDefaultRollerShutter) if ($hash->{CODE} =~ /^(40|41|61|65)..../);
- %sets = (%setsUmweltsensor) if ($hash->{CODE} =~ /^69....$/);
+ %sets = (%setsBasic, %setsDefaultRollerShutter, %setsRolloTube) if ($hash->{CODE} =~ /^49..../);
+ %sets = (%setsBasic, %setsDefaultRollerShutter, %setsTroll, ("blindsMode:on,off"=> "")) if ($hash->{CODE} =~ /^(42|4B|4C|70)..../);
+ %sets = (%setsBasic, %setsDefaultRollerShutter, %setsTroll) if ($hash->{CODE} =~ /^47..../);
+ %sets = (%setsBasic, %setsDefaultRollerShutter) if ($hash->{CODE} =~ /^(40|41|61)..../);
+ %sets = (%setsBasic, %setsUmweltsensor) if ($hash->{CODE} =~ /^69....$/);
%sets = (%setsUmweltsensor00) if ($hash->{CODE} =~ /^69....00/);
%sets = (%setsDefaultRollerShutter, %setsUmweltsensor01) if ($hash->{CODE} =~ /^69....01/);
%sets = (%setsSwitchActor) if ($hash->{CODE} =~ /^43....(01|02)/);
- %sets = ("getStatus:noArg"=> "") if ($hash->{CODE} =~ /^43....$/);
- %sets = (%setsSwitchActor) if ($hash->{CODE} =~ /^(46|71)..../);
- %sets = (%setsSX5) if ($hash->{CODE} =~ /^4E..../);
- %sets = (%setsDimmer) if ($hash->{CODE} =~ /^48..../);
+ %sets = (%setsBasic, "getStatus:noArg"=> "") if ($hash->{CODE} =~ /^(43|65|74)....$/);
+ %sets = (%setsBasic, %setsSwitchActor) if ($hash->{CODE} =~ /^(46|71)..../);
+ %sets = (%setsBasic, %setsSX5) if ($hash->{CODE} =~ /^4E..../);
+ %sets = (%setsBasic, %setsDimmer) if ($hash->{CODE} =~ /^48..../);
+ %sets = (%setsBasic, %setsThermostat) if ($hash->{CODE} =~ /^73..../);
+ %sets = (%setsSwitchActor) if ($hash->{CODE} =~ /^(65|74)....01/);
my $blindsMode=ReadingsVal($name, "blindsMode", "off");
%sets = (%sets, %setsBlinds) if ($blindsMode eq "on");
@@ -677,9 +704,22 @@ DUOFERN_Set($@)
$arg = $arg/100;
$subCmd = "value4";
$argV = sprintf "%02x", $arg ;
-
- } else {
+
+ } elsif (exists $commands{$cmd}{temp1}) {
return "Missing argument" if (!defined($arg));
+ return "Wrong argument $arg" if ($arg !~ m/^\d+(\.\d+|)$/ || $arg < -40 || $arg > 80);
+ $subCmd = "temp1";
+ $argW = sprintf "%04x", ($arg * 10) + 400;
+
+ } elsif (exists $commands{$cmd}{temp2}) {
+ return "Missing argument" if (!defined($arg));
+ return "Wrong argument $arg" if ($arg !~ m/^\d+(\.\d+|)$/ || $arg < -40 || $arg > 80);
+ $subCmd = "temp2";
+ $argV = sprintf "%02x", ($arg * 2) + 80;
+
+ } else {
+ return "Missing argument" if (!defined($arg));
+ $timer= "01" if ($arg2 && ($arg2 eq "timer"));
$subCmd = $arg;
$argV = "00";
}
@@ -699,13 +739,13 @@ DUOFERN_Set($@)
}
}
- readingsSingleUpdate($hash, "moving", "moving", 1) if (($cmd eq "toggle"));
+ readingsSingleUpdate($hash, "moving", "moving", 1) if (($cmd eq "toggle") && ($position > -1));
readingsSingleUpdate($hash, "moving", "up", 1) if (($cmd eq "dawn") && ($dawnAutomatic eq "on") && ($position > 0));
- readingsSingleUpdate($hash, "moving", "down", 1) if (($cmd eq "dusk") && ($duskAutomatic eq "on") && ($position < 100));
+ readingsSingleUpdate($hash, "moving", "down", 1) if (($cmd eq "dusk") && ($duskAutomatic eq "on") && ($position < 100) && ($position > -1));
if ($timer eq "00" || $timeAutomatic eq "on") {
readingsSingleUpdate($hash, "moving", "up", 1) if (($cmd eq "up") && ($position > 0));
- readingsSingleUpdate($hash, "moving", "down", 1) if (($cmd eq "down") && ($position < 100));
+ readingsSingleUpdate($hash, "moving", "down", 1) if (($cmd eq "down") && ($position < 100) && ($position > -1));
}
if ($cmd eq "position") {
@@ -721,7 +761,7 @@ DUOFERN_Set($@)
$command = $commands{$cmd}{$subCmd};
$buf =~ s/yyyyyy/$code/;
- $buf =~ s/nnnnnnnnnnnnnn/$command/;
+ $buf =~ s/nnnnnnnnnnnnnnnnnnnn/$command/;
$buf =~ s/nn/$argV/;
$buf =~ s/tt/$timer/;
$buf =~ s/wwww/$argW/;
@@ -783,7 +823,7 @@ DUOFERN_Define($$)
return undef if (AttrVal($name,"ignore",0) != 0);
- if ($hash->{CODE} =~ m/^(40|41|42|43|46|47|48|49|4B|4C|4E|61|62|65|69|70|71)....$/) {
+ if ($hash->{CODE} =~ m/^(40|41|42|43|46|47|48|49|4B|4C|4E|61|62|65|69|70|71|73|74)....$/) {
$hash->{helper}{timeout}{t} = 30;
InternalTimer(gettimeofday()+$hash->{helper}{timeout}{t}, "DUOFERN_StatusTimeout", $hash, 0);
$hash->{helper}{timeout}{count} = 2;
@@ -900,14 +940,16 @@ DUOFERN_Parse($$)
RemoveInternalTimer($hash);
delete $hash->{helper}{timeout};
- if ($code =~ m/^69..../) {
+ #Bewegungsmelder, Wettersensor, Mehrfachwandtaster
+ if ($code =~ m/^(65|69|74)..../) {
readingsSingleUpdate($hash, "state", "OK", 1);
$def01 = $modules{DUOFERN}{defptr}{$code."01"};
if(!$def01) {
DoTrigger("global","UNDEFINED DUOFERN_$code"."_actor DUOFERN $code"."01");
$def01 = $modules{DUOFERN}{defptr}{$code."01"};
}
-
+
+ #Universalaktor
} elsif ($code =~ m/^43..../) {
readingsSingleUpdate($hash, "state", "OK", 1);
$def01 = $modules{DUOFERN}{defptr}{$code."01"};
@@ -920,8 +962,8 @@ DUOFERN_Parse($$)
DoTrigger("global","UNDEFINED DUOFERN_$code"."_02 DUOFERN $code"."02");
$def02 = $modules{DUOFERN}{defptr}{$code."02"};
}
- }
-
+ }
+
$hash = $def01 if ($def01);
#RolloTron
@@ -1206,7 +1248,41 @@ DUOFERN_Parse($$)
readingsBulkUpdate($hash, "modeChange", $modeChange , 1);
readingsBulkUpdate($hash, "state", $state , 1);
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
+
+ #Thermostat
+ } elsif ($format eq "27") {
+ my $temperature1 = sprintf("%0.1f", ((hex(substr($msg, 8, 4)) & 0x07FF)-400)/10);
+ my $temperature2 = sprintf("%0.1f", ((hex(substr($msg, 12, 4)) & 0x07FF)-400)/10);
+ my $tempThreshold1 = sprintf("%0.1f", (hex(substr($msg, 16, 2))-80)/2);
+ my $tempThreshold2 = sprintf("%0.1f", (hex(substr($msg, 18, 2))-80)/2);
+ my $tempThreshold3 = sprintf("%0.1f", (hex(substr($msg, 20, 2))-80)/2);
+ my $tempThreshold4 = sprintf("%0.1f", (hex(substr($msg, 22, 2))-80)/2);
+ my $desiredTemp = sprintf("%0.1f", (hex(substr($msg, 26, 2))-80)/2);
+ my $output = (hex(substr($msg, 8, 2)) & 0x08 ? "on" : "off");
+ my $manualOverride = (hex(substr($msg, 8, 2)) & 0x10 ? "on" : "off");
+ my $actTempLimit = (hex(substr($msg, 8, 2)) & 0x60)>>5;
+ my $timerAuto = (hex(substr($msg, 12, 2)) & 0x08 ? "on" : "off");
+ my $manualMode = (hex(substr($msg, 12, 2)) & 0x10 ? "on" : "off");
+ $state = "T: $temperature1 desired: $desiredTemp";
+
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash, "measured-temp", $temperature1, 1);
+ readingsBulkUpdate($hash, "measured-temp2", $temperature2, 1);
+ readingsBulkUpdate($hash, "temperatureThreshold1", $tempThreshold1, 1);
+ readingsBulkUpdate($hash, "temperatureThreshold2", $tempThreshold2, 1);
+ readingsBulkUpdate($hash, "temperatureThreshold3", $tempThreshold3, 1);
+ readingsBulkUpdate($hash, "temperatureThreshold4", $tempThreshold4, 1);
+ readingsBulkUpdate($hash, "desired-temp", $desiredTemp, 1);
+ readingsBulkUpdate($hash, "output", $output, 1);
+ readingsBulkUpdate($hash, "manualOverride", $manualOverride, 1);
+ readingsBulkUpdate($hash, "actTempLimit", $actTempLimit, 1);
+ readingsBulkUpdate($hash, "timeAutomatic", $timerAuto, 1);
+ readingsBulkUpdate($hash, "manualMode", $manualMode, 1);
+
+ readingsBulkUpdate($hash, "state", $state, 1);
+ readingsEndUpdate($hash, 1); # Notify is done by Dispatch
+
} else {
Log3 $hash, 2, "DUOFERN unknown msg: $msg";
}
@@ -1224,7 +1300,9 @@ DUOFERN_Parse($$)
my @chans;
if ($sensorMsg{$id}{chan} == 5) {
- for(my $x=0; $x<5; $x++) {
+ my $chanCount = 5;
+ $chanCount = 4 if ($code =~ m/^(73)..../);
+ for(my $x=0; $x<$chanCount; $x++) {
if((0x01<<$x) & hex($chan)) {
push(@chans, $x+1);
}
@@ -1233,6 +1311,15 @@ DUOFERN_Parse($$)
push(@chans, $chan);
}
+ if($code =~ m/^(65|69|74).*/) {
+ $def01 = $modules{DUOFERN}{defptr}{$code."00"};
+ if(!$def01) {
+ DoTrigger("global","UNDEFINED DUOFERN_$code"."_sensor DUOFERN $code"."00");
+ $def01 = $modules{DUOFERN}{defptr}{$code."00"};
+ }
+ $hash = $def01 if ($def01);
+ }
+
foreach (@chans) {
$chan = $_;
if($id =~ m/..(1A|18|19|01|02|03)/) {
@@ -1243,18 +1330,10 @@ DUOFERN_Parse($$)
}
readingsSingleUpdate($hash, "channel$chan", $sensorMsg{$id}{name}, 1);
} else {
- if($code =~ m/^69.*/) {
- $def01 = $modules{DUOFERN}{defptr}{$code."00"};
- if(!$def01) {
- DoTrigger("global","UNDEFINED DUOFERN_$code"."_sensor DUOFERN $code"."00");
- $def01 = $modules{DUOFERN}{defptr}{$code."00"};
- }
- $hash = $def01;
- }
- if(($code !~ m/^69.*/) || ($id =~ m/..(11|12)/)) {
+ if(($code !~ m/^(69|73).*/) || ($id =~ m/..(11|12)/)) {
$chan="";
}
- if($code =~ m/^(A5|AA|AB)..../) {
+ if($code =~ m/^(65|A5|AA|AB)..../) {
readingsSingleUpdate($hash, "state", $sensorMsg{$id}{state}, 1);
}
@@ -1706,6 +1785,32 @@ DUOFERN_StatusTimeout($)
Tilt slat after stopping blind while moving down.
+
+ Thermostat commands:
+