2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 18:59:33 +00:00

Fehlerbehandlung verbessert, Netzwerkbyteorder gefixt und etliche Fehler beseitigt

git-svn-id: https://svn.fhem.de/fhem/trunk@1506 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
oskarfessel 2012-04-29 18:11:46 +00:00
parent e6c9a00dbc
commit f36d2174d7

View File

@ -3,6 +3,7 @@
# Copyright notice # Copyright notice
# #
# (c) 2012 Torsten Poitzsch (torsten.poitzsch@gmx.de) # (c) 2012 Torsten Poitzsch (torsten.poitzsch@gmx.de)
# (c) 2012 Jan-Hinrich Fessel (oskar@fessel.org)
# #
# This script is free software; you can redistribute it and/or modify # This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -30,6 +31,8 @@ use strict;
use warnings; use warnings;
use IO::Socket; use IO::Socket;
my $cc; # The Itmes Changed Counter
sub sub
LUXTRONIK2_Initialize($) LUXTRONIK2_Initialize($)
{ {
@ -56,6 +59,20 @@ LUXTRONIK2_Define($$)
return undef; return undef;
} }
sub
LUXTRONIK2_TempValueMerken($$$)
{
my ($hash, $param, $paramName) = @_;
$param /= 10;
if($hash->{READINGS}{$paramName}{VAL} != $param) {
$hash->{READINGS}{$paramName}{TIME} = TimeNow();
$hash->{READINGS}{$paramName}{VAL} = $param;
$hash->{READINGS}{$paramName}{UNIT} = "Degree Celsius";
$hash->{CHANGED}[$cc++] = $paramName .": ". $param;
}
}
##################################### #####################################
sub sub
@ -68,62 +85,102 @@ LUXTRONIK2_GetStatus($)
my $result=''; my $result='';
my $switch=0; my $switch=0;
my $value=''; my $value='';
my $i=0; my $count=0;
# my $i=0;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $host = $hash->{Host}; my $host = $hash->{Host};
my $sensor = ''; my $sensor = '';
my $state = ''; my $state = '';
$cc = 0; #initialize counter
InternalTimer(gettimeofday() + $hash->{INTERVAL}, "LUXTRONIK2_GetStatus", $hash, 0); InternalTimer(gettimeofday() + $hash->{INTERVAL}, "LUXTRONIK2_GetStatus", $hash, 0);
my $socket = new IO::Socket::INET ( PeerAddr => $host, my $socket = new IO::Socket::INET ( PeerAddr => $host,
PeerPort => 8888, PeerPort => 8888,
Type => SOCK_STREAM, # Type => SOCK_STREAM, # probably needed on some systems
Proto => 'tcp' Proto => 'tcp'
); );
$err_log .= "Fehler: $!\n" if (!$socket) {
unless defined $socket; $hash->{STATE} = "error opening device";
Log 1,"$name: Error opening Connection to $host";
return "Can't Connect to $host -> $@ ( $!)\n";
}
$socket->autoflush(1); $socket->autoflush(1);
#Read operational values #Read operational values
$socket->send(pack("l", 3004)); $socket->send(pack("N", 3004));
$socket->send(pack("l", 0)); $socket->send(pack("N", 0));
# read response, should be 3004, status, number of parameters, and the parameters...
$socket->recv($result,4);
$count = unpack("N", $result);
if($count != 3004) {
Log 2, "LUXTRONIK2_GetStatus: $name $host 3004 Status problem 1: ".length($result)." -> ".$count;
return "3004 != 3004";
}
$socket->recv($result,4); $socket->recv($result,4);
@heatpump_values = unpack("l", $result); $count = unpack("N", $result);
if($count != 0) {
$socket->recv($result,4); Log 2, "LUXTRONIK2_GetStatus: $name $host ".length($result)." -> ".$count;
@heatpump_values = unpack("l", $result); return "0 != 0";
}
$socket->recv($result,4); $socket->recv($result,4);
@heatpump_values = unpack("l", $result); $count = unpack("N", $result);
if($count == 0) {
$socket->recv($result,1024); Log 2, "LUXTRONIK2_GetStatus: $name $host 0 Paramters read".length($result)." -> ".$count;
@heatpump_values = unpack("l@heatpump_values", $result); return "0 Paramters read";
}
$socket->recv($result, $count*4+4);
if(length($result) != $count*4) {
Log 1, "LUXTRONIK2_GetStatus status report length check: $name $host ".length($result)." should have been ". $count * 4;
return "Value read mismatch Lux2 ( $!)\n";
}
@heatpump_values = unpack("N$count", $result);
if(scalar(@heatpump_values) != $count) {
Log 2, "LUXTRONIK2_GetStatus10: $name $host ".scalar(@heatpump_values)." -> ".$heatpump_values[10];
return "Value unpacking problem";
}
# Parametereinstellung lesen # Parametereinstellung lesen
$socket->send(pack("l", 3003)); $socket->send(pack("N", 3003));
$socket->send(pack("l", 0)); $socket->send(pack("N", 0));
$socket->recv($result,4); $socket->recv($result,4);
@heatpump_parameters = unpack("l", $result); $count = unpack("N", $result);
$count = unpack("N", $result);
$socket->recv($result,4); if($count != 3003) {
@heatpump_parameters = unpack("l", $result); Log 2, "LUXTRONIK2_GetStatus: $name $host 3003 Status problem 1: ".length($result)." -> ".$count;
return "3003 != 3003";
}
$socket->recv($result,1024); $socket->recv($result,4);
@heatpump_parameters = unpack("l@heatpump_parameters", $result); $count = unpack("N", $result);
$socket->close(); $socket->recv($result, $count*4+4);
if(length($result) != $count*4) {
Log 1, "LUXTRONIK2_GetStatus parameter settings length check: $name $host ".length($result)." should have been ". $count * 4;
# return "Value read mismatch Lux2 ( $!)\n";
}
@heatpump_parameters = unpack("N$count", $result);
if(scalar(@heatpump_parameters) != $count) {
Log 2, "LUXTRONIK2_GetStatus: $name $host pump parameter problem: received parameter count ("
. scalar(@heatpump_parameters) .
") is not equal to announced parameter count(" . $count . ")!";
}
$socket->close();
if($err_log ne "") if($err_log ne "")
{ {
Log GetLogLevel($name,2), "LUXTRONIK2 ".$err_log; Log GetLogLevel($name,2), "LUXTRONIK2 ".$err_log;
return(""); return("");
} }
# Build string arrays
my %wpOpStat1 = ( 0 => "Waermepumpe laeuft", my %wpOpStat1 = ( 0 => "Waermepumpe laeuft",
1 => "Waermepumpe steht", 1 => "Waermepumpe steht",
2 => "Waermepumpe kommt", 2 => "Waermepumpe kommt",
@ -150,34 +207,42 @@ LUXTRONIK2_GetStatus($)
2 => "Party", 2 => "Party",
3 => "Ferien", 3 => "Ferien",
4 => "Aus" ); 4 => "Aus" );
# Erst die operativen Stati und Parameterenstellungen # Erst die operativen Stati und Parameterenstellungen
$sensor = "currentOperatingStatus1"; $sensor = "currentOperatingStatus1";
$switch = $heatpump_values[117]; $switch = $heatpump_values[117];
$value = $wpOpStat1{$switch}; $value = $wpOpStat1{$switch};
$value = "unbekannt (".$switch.")" unless $value; $value = "unbekannt (".$switch.")" unless $value;
$hash->{READINGS}{$sensor}{TIME} = TimeNow(); if($hash->{READINGS}{$sensor}{VAL} != $value) {
$hash->{READINGS}{$sensor}{VAL} = $value; $hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$cc++] = $sensor.": ".$value;
}
$state = $value; $state = $value;
$sensor = "currentOperatingStatus2"; $sensor = "currentOperatingStatus2";
$switch = $heatpump_values[119]; $switch = $heatpump_values[119];
$value = $wpOpStat2{$switch}; $value = $wpOpStat2{$switch};
# Special cases # Sonderfaelle behandeln:
if ($switch==6) { $value = "Stufe ".$heatpump_values[121]." ".($heatpump_values[122] / 10)." °C "; } if ($switch==6) { $value = "Stufe ".$heatpump_values[121]." ".($heatpump_values[122] / 10)." °C "; }
elsif ($switch==7) { elsif ($switch==7) {
if ($heatpump_values[44]==1) {$value = "Abtauen (Kreisumkehr)";} if ($heatpump_values[44]==1) {$value = "Abtauen (Kreisumkehr)";}
else {$value = "Luftabtauen";} else {$value = "Luftabtauen";}
} }
$value = "unbekannt (".$switch.")" unless $value; $value = "unbekannt (".$switch.")" unless $value;
$hash->{READINGS}{$sensor}{TIME} = TimeNow(); if($hash->{READINGS}{$sensor}{VAL} != $value) {
$hash->{READINGS}{$sensor}{VAL} = $value; $hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$cc++] = $sensor.": ".$value;
}
#
# TODO: STATE ändern nach Developer-Wiki.
#
$state = $state." - ".$value; $state = $state." - ".$value;
$hash->{STATE} = $state; $hash->{STATE} = $state;
@ -186,78 +251,62 @@ LUXTRONIK2_GetStatus($)
$switch = $heatpump_parameters[4]; $switch = $heatpump_parameters[4];
$value = $wpMode{$switch}; $value = $wpMode{$switch};
if ($switch==0 && $heatpump_values[16]>=$heatpump_parameters[700] && $heatpump_parameters[699]==1) {$value = "Automatik - Sommerbetrieb (Aus)";}
$value = "unbekannt (".$switch.")" unless $value; $value = "unbekannt (".$switch.")" unless $value;
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
if($hash->{READINGS}{$sensor}{VAL} != $value) {
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$cc++] = $sensor.": ".$value;
}
$sensor = "heatingOperatingMode"; $sensor = "heatingOperatingMode";
$switch = $heatpump_parameters[3]; $switch = $heatpump_parameters[3];
$value = $wpMode{$switch}; $value = $wpMode{$switch};
$value = "unbekannt (".$switch.")" unless $value; $value = "unbekannt (" . $switch . ")" unless $value;
$hash->{READINGS}{$sensor}{TIME} = TimeNow(); if($hash->{READINGS}{$sensor}{VAL} != $value) {
$hash->{READINGS}{$sensor}{VAL} = $value; $hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$cc++] = $sensor.": ".$value;
}
##################### #####################
# Jetzt die aktuellen Betriebswerte auswerten. # Jetzt die aktuellen Betriebswerte auswerten.
##################### #####################
# is ambient temperature the correct wording for the outside temperature?
# Wikipedia:
# Ambient temperature simply means "the temperature of the surroundings" and will be the same as room temperature indoors.
LUXTRONIK2_TempValueMerken($hash,$heatpump_values[15],"ambientTemperature");
$sensor = "ambientTemperature"; LUXTRONIK2_TempValueMerken($hash,$heatpump_values[16],"averageAmbientTemperature");
$value = $heatpump_values[15] / 10;
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$i++] = "$sensor: $value";
$sensor = "averageAmbientTemperature";
$value = $heatpump_values[16] / 10;
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$i++] = "$sensor: $value";
Log GetLogLevel($name,4), $sensor.": ".$value; Log GetLogLevel($name,4), $sensor.": ".$value;
#Log 4, "LUXTRONIK2_GetStatus: $name $host ".$hash->{STATE}." -> ".$state; # Log 4, "LUXTRONIK2_GetStatus: $name $host ".$hash->{STATE}." -> ".$state;
$sensor = "hotWaterTemperature"; LUXTRONIK2_TempValueMerken($hash,$heatpump_values[17],"hotWaterTemperature");
$value = $heatpump_values[17] / 10;
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$i++] = "$sensor: $value";
$sensor = "flowTemperature";
$value = $heatpump_values[10] / 10;
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$i++] = "$sensor: $value";
$sensor = "returnTemperature"; # Wert 10 gibt die Vorlauftemperatur an, die
$value = $heatpump_values[11] / 10; # korrekte Übersetzung ist flow temperature.
$hash->{READINGS}{$sensor}{TIME} = TimeNow(); LUXTRONIK2_TempValueMerken($hash,$heatpump_values[10],"flowTemperature");
$hash->{READINGS}{$sensor}{VAL} = $value; # Rücklauftempereatur
$hash->{CHANGED}[$i++] = "$sensor: $value"; LUXTRONIK2_TempValueMerken($hash,$heatpump_values[11],"returnTemperature");
# Rücklauftemperatur Sollwert
$sensor = "returnTemperatureExtern"; LUXTRONIK2_TempValueMerken($hash,$heatpump_values[12],"returnTemperatureTarget");
$value = $heatpump_values[13] / 10; # Rücklauftemperatur am externen Sensor.
$hash->{READINGS}{$sensor}{TIME} = TimeNow(); LUXTRONIK2_TempValueMerken($hash,$heatpump_values[13],"returnTemperatureExtern");
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$i++] = "$sensor: $value";
$sensor = "returnTargetTemperature";
$value = $heatpump_values[12] / 10;
$hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{CHANGED}[$i++] = "$sensor: $value";
# Durchfluss Wärmemengenzähler
# Durchfluss Wärmemengenzähler # Durchfluss Wärmemengenzähler
$sensor = "flowRate"; $sensor = "flowRate";
$value = $heatpump_values[155]; $value = $heatpump_values[155];
$hash->{READINGS}{$sensor}{TIME} = TimeNow(); if($hash->{READINGS}{$sensor}{VAL} != $value) {
$hash->{READINGS}{$sensor}{VAL} = $value; $hash->{READINGS}{$sensor}{TIME} = TimeNow();
$hash->{CHANGED}[$i++] = "$sensor: $value"; $hash->{READINGS}{$sensor}{VAL} = $value;
$hash->{READINGS}{$sensor}{UNIT} = "l/h";
$hash->{CHANGED}[$cc++] = $sensor.": ".$value;
}
DoTrigger($name, undef) if($init_done); DoTrigger($name, undef) if($init_done);
} }