diff --git a/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt b/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt index 078d0f3dc..8d2bfc542 100644 --- a/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt +++ b/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt @@ -117,5 +117,147 @@ attr MHI_Heavy showBody 1 attr MHI_Heavy showError 1 attr MHI_Heavy sortby 212 attr MHI_Heavy timeout 7 -attr MHI_Heavy userReadings contents_airconStat_test:contents_airconStat.* { my $airconStat = encode_base64(ReadingsVal("$NAME","contents_airconStat","")) ;; $airconStat =~ s/\n//g ;; $airconStat } +attr MHI_Heavy userReadings contents_airconStat_Status:contents_airconStat:.* {\ + use MIME::Base64;;\ +\ + my $dev = "MHI_Heavy";;\ + my $hash = $defs{$dev};;\ +\ + # Rohdaten aus Reading holen\ + my $raw = ReadingsVal($dev,"contents_airconStat","");;\ + return if($raw eq "");;\ +\ + # Base64 decodieren\ + my $bytes = decode_base64($raw);;\ + my @b = unpack("C*", $bytes);;\ +\ + # --- Debug: Alle Bytes anzeigen ---\ + my $hex = join " ", map { sprintf "%02X", $_ } @b;;\ + Log 1, "Aircon Debug Bytes: $hex";;\ +\ + # --- Power: Byte 2, Bit 0 ---\ + my $power = ($b[2] & 0x01) ? "On" : "Off";;\ +\ + # --- Mode ---\ + # Mode aus Byte 26\ + my ($index) = grep { $b[$_] == 0x81 && $b[$_+1] == 0x04 } 0..$#b-1;;\ + my $modeByte = $b[$index+2];;\ + my %modeMap = (\ + 0x01 => "Auto",\ + 0x09 => "Cool",\ + 0x11 => "Heat",\ + 0x0D => "Fan",\ + 0x05 => "Dry",\ +);;\ +my $mode = exists $modeMap{$modeByte} ? $modeMap{$modeByte} : "Unknown";;\ +\ + # === Temperaturen ===\ + my $setTemp = $b[29] / 2;; # Solltemperatur\ +\ +\ + # === RoomTemp (Bytes 45+46 Little Endian) ===\ + my $roomTemp = (($b[46] << 8) + $b[45]) / 1585;; # Skalierung passend für App-Werte\ +\ + # === Außentemperatur (Bytes 30,31) ===\ + my $outTemp = (($b[31] << 8) + $b[33]) / 10;; # Zehntelgrad °C\ +\ + # --- Fan ---\ + my $fanbyte = $b[3] & 0x0F;;\ + my %fanmap = (\ + 0x0F => "Auto",\ + 0x08 => "1",\ + 0x09 => "2",\ + 0x0A => "3",\ + 0x0E => "4"\ +);;\ +my $fan = $fanmap{$fanbyte} // "Unknown";;\ +\ + # --- Swing / Lamellen ---\ + #-------- Vertikal------\ + my $b2 = $b[2];;\ + my $b3 = $b[3];;\ +\ +my %vertical_map = (\ + 0 => 'auto',\ + 1 => 'highest',\ + 2 => 'middle',\ + 3 => 'normal',\ + 4 => 'lowest',\ +);;\ +\ +my $vert;;\ +\ +# Erkennen anhand von Byte 2 & 3\ +if ( ($b2 & 0xC0) == 0xC0 && ($b3 & 0x80) == 0x80 ) {\ + $vert = $vertical_map{0};;\ +} else {\ + my $pos;;\ + if ( ($b3 & 0xB0) == 0x80 ) { $pos = 1;; } # highest\ + elsif ( ($b3 & 0xB0) == 0x90 ) { $pos = 2;; } # middle\ + elsif ( ($b3 & 0xB0) == 0xA0 ) { $pos = 3;; } # normal\ + elsif ( ($b3 & 0xB0) == 0xB0 ) { $pos = 4;; } # lowest\ + else { $pos = -1;; }\ +\ + $vert = defined $vertical_map{$pos} ? $vertical_map{$pos} : "unknown";;\ +}\ +\ +# ----- Horizontal ---------\ +\ +#Horizontale Lamellenstellung aus Bytes dekodieren\ +# Byte 11 und 12 enthalten die horizontale Windrichtung\ +my $b11 = $b[11];;\ +my $b12 = $b[12];;\ +\ +my %horizontal_map = (\ + 0 => 'auto',\ + 1 => 'left-left',\ + 2 => 'left-center',\ + 3 => 'center-center',\ + 4 => 'center-right',\ + 5 => 'right-right',\ + 6 => 'left-right',\ + 7 => 'right-left',\ +);;\ +\ +my $hor;;\ +\ +# Prüfen, ob Auto/Swing aktiv ist\ +if ( ($b12 & 0x03) == 0x03 ) {\ + $hor = $horizontal_map{0};; # auto\ +} else {\ + # untere 4 Bits von Byte 11 enthalten Positionscode (0x10–0x16)\ + my $pos = ($b11 & 0x0F);;\ + # 0x10 -> 0, 0x11 -> 1, ..., 0x16 -> 6\ + $hor = $horizontal_map{$pos} // "unknown";;\ +}\ + \ +# ab hier muss noch weiteres Reverseenginnering betrieben werden.\ + \ +\ + # --- Humidity ---\ + my $humidity = $b[5];; # direktes Byte, %\ +\ + # --- LED ---\ + my $led = $b[6];;\ +\ + # --- Energie kWh ---\ + my $energy = ($b[10]<<8 | $b[11])/10;; # Beispielberechnung\ +\ + # --- Readings setzen ---\ + readingsBeginUpdate($hash);;\ + readingsBulkUpdate($hash,"contents_airconStat_Power",$power);;\ + readingsBulkUpdate($hash,"contents_airconStat_Mode",$mode);;\ + readingsBulkUpdate($hash,"contents_airconStat_Fan",$fan);;\ + readingsBulkUpdate($hash,"contents_airconStat_LamelleVert",$vert);;\ + readingsBulkUpdate($hash,"contents_airconStat_LamelleHor",$hor);;\ + readingsBulkUpdate($hash,"contents_airconStat_TempRoom",sprintf("%.1f",$roomTemp));;\ + readingsBulkUpdate($hash,"contents_airconStat_TempOut",sprintf("%.1f",$outTemp));;\ + readingsBulkUpdate($hash,"contents_airconStat_TempSet",sprintf("%.1f",$setTemp));;\ + readingsBulkUpdate($hash,"contents_airconStat_Humidity",$humidity);;\ + readingsBulkUpdate($hash,"contents_airconStat_LED",$led);;\ + readingsBulkUpdate($hash,"contents_airconStat_Energy_kWh",sprintf("%.1f",$energy));;\ + readingsEndUpdate($hash,1);;\ +\ + return 1;;\ +} attr MHI_Heavy verbose 5 \ No newline at end of file