From 55981ec95f2d4fb6cf7497479c931151097aeb50 Mon Sep 17 00:00:00 2001 From: "ch.eick" Date: Wed, 22 Oct 2025 11:01:45 +0000 Subject: [PATCH] ch.eick: New MHI_Heavy connection git-svn-id: https://svn.fhem.de/fhem/trunk@30431 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- .../contrib/ch.eick/Klimaanlage/MHI_Heavy.txt | 172 ++++-------------- 1 file changed, 33 insertions(+), 139 deletions(-) diff --git a/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt b/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt index 16a2c0779..f0c287760 100644 --- a/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt +++ b/fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy.txt @@ -54,13 +54,13 @@ attr MHI_Heavy group PV Eigenverbrauch attr MHI_Heavy icon sani_solar attr MHI_Heavy replacement01Mode text attr MHI_Heavy replacement01Regex %IP-MHI_Heavy% -attr MHI_Heavy replacement01Value < MHI_Heavy IP-Address > +attr MHI_Heavy replacement01Value 192.168.178.32 attr MHI_Heavy replacement02Mode text attr MHI_Heavy replacement02Regex %deviceId% -attr MHI_Heavy replacement02Value +attr MHI_Heavy replacement02Value e81656185d42 attr MHI_Heavy replacement03Mode text attr MHI_Heavy replacement03Regex %operatorId% -attr MHI_Heavy replacement03Value +attr MHI_Heavy replacement03Value b4220891-e32a-4252-b448-cf3ab2172944 attr MHI_Heavy replacement04Mode expression attr MHI_Heavy replacement04Regex %TIME% attr MHI_Heavy replacement04Value {round(time(),0)} @@ -118,146 +118,40 @@ attr MHI_Heavy showError 1 attr MHI_Heavy sortby 212 attr MHI_Heavy timeout 7 attr MHI_Heavy userReadings contents_airconStat_Status:contents_airconStat:.* {\ - use MIME::Base64;;\ + my $hash = $defs{$name};;\ \ - 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\ + # Rohdaten aus Reading holen\ + my $base64_string = ReadingsVal($name,"contents_airconStat","");;\ + return if($base64_string eq "");;\ + my $status = $name->fromBase64($base64_string);;\ \ # --- 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);;\ + readingsBulkUpdate($hash,"contents_airconStat_Operation",$status->{operation});;\ + readingsBulkUpdate($hash,"contents_airconStat_OperationMode",$status->{operationMode});;\ + readingsBulkUpdate($hash,"contents_airconStat_CoolHotJudge",$status->{coolHotJudge});;\ +\ + readingsBulkUpdate($hash,"contents_airconStat_ErrorCode",$status->{errorCode});;\ +\ + readingsBulkUpdate($hash,"contents_airconStat_AirFlow",$status->{airFlow});;\ + readingsBulkUpdate($hash,"contents_airconStat_WindDirectionUD",$status->{windDirectionUD});;\ + readingsBulkUpdate($hash,"contents_airconStat_WindDirectionLR",$status->{windDirectionLR});;\ +\ + readingsBulkUpdate($hash,"contents_airconStat_TempIndoor",$status->{indoorTemp} -3);;\ + readingsBulkUpdate($hash,"contents_airconStat_TempOutdoor",$status->{outdoorTemp});;\ + readingsBulkUpdate($hash,"contents_airconStat_TempPreset",$status->{presetTemp});;\ +\ + readingsBulkUpdate($hash,"contents_airconStat_Energy_kWh",$status->{electric});;\ +\ + readingsBulkUpdate($hash,"contents_airconStat_ModelNo",$status->{modelNo});;\ + readingsBulkUpdate($hash,"contents_airconStat_IsVacantProperty",$status->{isVacantProperty});;\ + readingsBulkUpdate($hash,"contents_airconStat_Entrust",$status->{entrust});;\ +\ +# readingsBulkUpdate($hash,"contents_airconStat_Humidity",$humidity);;\ +# readingsBulkUpdate($hash,"contents_airconStat_LED",$led);;\ +\ +# readingsEndUpdate($hash,1);;\ \ return 1;;\ } -attr MHI_Heavy verbose 5 \ No newline at end of file +attr MHI_Heavy verbose 3 \ No newline at end of file