ch.eick: analyse payload
git-svn-id: https://svn.fhem.de/fhem/trunk@30293 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user