ch.eick : Update MHI_Heavy files
git-svn-id: https://svn.fhem.de/fhem/trunk@30432 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
203
fhem/contrib/ch.eick/Klimaanlage/99_MHI_Heavy.pm
Normal file
203
fhem/contrib/ch.eick/Klimaanlage/99_MHI_Heavy.pm
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
# === Initialize ===
|
||||||
|
sub MHI_Heavy_Initialize {
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enter your functions below _this_ line.
|
||||||
|
###################################################
|
||||||
|
|
||||||
|
package MHI_Heavy;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use MIME::Base64 qw(decode_base64 encode_base64);
|
||||||
|
use List::Util qw(first);
|
||||||
|
|
||||||
|
# === statische Tabellen ===
|
||||||
|
our @outdoorTempList = (-50.0, -50.0, -50.0, -50.0, -50.0, -48.9, -46.0, -44.0, -42.0, -41.0, -39.0, -38.0, -37.0, -36.0, -35.0, -34.0, -33.0, -32.0, -31.0, -30.0, -29.0, -28.5, -28.0, -27.0, -26.0, -25.5, -25.0, -24.0, -23.5, -23.0, -22.5, -22.0, -21.5, -21.0, -20.5, -20.0, -19.5, -19.0, -18.5, -18.0, -17.5, -17.0, -16.5, -16.0, -15.5, -15.0, -14.6, -14.3, -14.0, -13.5, -13.0, -12.6, -12.3, -12.0, -11.5, -11.0, -10.6, -10.3, -10.0, -9.6, -9.3, -9.0, -8.6, -8.3, -8.0, -7.6, -7.3, -7.0, -6.6, -6.3, -6.0, -5.6, -5.3, -5.0, -4.6, -4.3, -4.0, -3.7, -3.5, -3.2, -3.0, -2.6, -2.3, -2.0, -1.7, -1.5, -1.2, -1.0, -0.6, -0.3, 0.0, 0.2, 0.5, 0.7, 1.0, 1.3, 1.6, 2.0, 2.2, 2.5, 2.7, 3.0, 3.2, 3.5, 3.7, 4.0, 4.2, 4.5, 4.7, 5.0, 5.2, 5.5, 5.7, 6.0, 6.2, 6.5, 6.7, 7.0, 7.2, 7.5, 7.7, 8.0, 8.2, 8.5, 8.7, 9.0, 9.2, 9.5, 9.7, 10.0, 10.2, 10.5, 10.7, 11.0, 11.2, 11.5, 11.7, 12.0, 12.2, 12.5, 12.7, 13.0, 13.2, 13.5, 13.7, 14.0, 14.2, 14.4, 14.6, 14.8, 15.0, 15.2, 15.5, 15.7, 16.0, 16.2, 16.5, 16.7, 17.0, 17.2, 17.5, 17.7, 18.0, 18.2, 18.5, 18.7, 19.0, 19.2, 19.4, 19.6, 19.8, 20.0, 20.2, 20.5, 20.7, 21.0, 21.2, 21.5, 21.7, 22.0, 22.2, 22.5, 22.7, 23.0, 23.2, 23.5, 23.7, 24.0, 24.2, 24.5, 24.7, 25.0, 25.2, 25.5, 25.7, 26.0, 26.2, 26.5, 26.7, 27.0, 27.2, 27.5, 27.7, 28.0, 28.2, 28.5, 28.7, 29.0, 29.2, 29.5, 29.7, 30.0, 30.2, 30.5, 30.7, 31.0, 31.3, 31.6, 32.0, 32.2, 32.5, 32.7, 33.0, 33.2, 33.5, 33.7, 34.0, 34.3, 34.6, 35.0, 35.2, 35.5, 35.7, 36.0, 36.3, 36.6, 37.0, 37.2, 37.5, 37.7, 38.0, 38.3, 38.6, 39.0, 39.3, 39.6, 40.0, 40.3, 40.6, 41.0, 41.3, 41.6, 42.0, 42.3, 42.6, 43.0);
|
||||||
|
|
||||||
|
our @indoorTempList = (-30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -30.0, -29.0, -28.0, -27.0, -26.0, -25.0, -24.0, -23.0, -22.5, -22.0, -21.0, -20.0, -19.5, -19.0, -18.0, -17.5, -17.0, -16.5, -16.0, -15.0, -14.5, -14.0, -13.5, -13.0, -12.5, -12.0, -11.5, -11.0, -10.5, -10.0, -9.5, -9.0, -8.6, -8.3, -8.0, -7.5, -7.0, -6.5, -6.0, -5.6, -5.3, -5.0, -4.5, -4.0, -3.6, -3.3, -3.0, -2.6, -2.3, -2.0, -1.6, -1.3, -1.0, -0.5, 0.0, 0.3, 0.6, 1.0, 1.3, 1.6, 2.0, 2.3, 2.6, 3.0, 3.2, 3.5, 3.7, 4.0, 4.3, 4.6, 5.0, 5.3, 5.6, 6.0, 6.3, 6.6, 7.0, 7.2, 7.5, 7.7, 8.0, 8.3, 8.6, 9.0, 9.2, 9.5, 9.7, 10.0, 10.3, 10.6, 11.0, 11.2, 11.5, 11.7, 12.0, 12.3, 12.6, 13.0, 13.2, 13.5, 13.7, 14.0, 14.2, 14.5, 14.7, 15.0, 15.3, 15.6, 16.0, 16.2, 16.5, 16.7, 17.0, 17.2, 17.5, 17.7, 18.0, 18.2, 18.5, 18.7, 19.0, 19.2, 19.5, 19.7, 20.0, 20.2, 20.5, 20.7, 21.0, 21.2, 21.5, 21.7, 22.0, 22.2, 22.5, 22.7, 23.0, 23.2, 23.5, 23.7, 24.0, 24.2, 24.5, 24.7, 25.0, 25.2, 25.5, 25.7, 26.0, 26.2, 26.5, 26.7, 27.0, 27.2, 27.5, 27.7, 28.0, 28.2, 28.5, 28.7, 29.0, 29.2, 29.5, 29.7, 30.0, 30.2, 30.5, 30.7, 31.0, 31.3, 31.6, 32.0, 32.2, 32.5, 32.7, 33.0, 33.2, 33.5, 33.7, 34.0, 34.2, 34.5, 34.7, 35.0, 35.3, 35.6, 36.0, 36.2, 36.5, 36.7, 37.0, 37.2, 37.5, 37.7, 38.0, 38.3, 38.6, 39.0, 39.2, 39.5, 39.7, 40.0, 40.3, 40.6, 41.0, 41.2, 41.5, 41.7, 42.0, 42.3, 42.6, 43.0, 43.2, 43.5, 43.7, 44.0, 44.3, 44.6, 45.0, 45.3, 45.6, 46.0, 46.2, 46.5, 46.7, 47.0, 47.3, 47.6, 48.0, 48.3, 48.6, 49.0, 49.3, 49.6, 50.0, 50.3, 50.6, 51.0, 51.3, 51.6, 52.0);
|
||||||
|
|
||||||
|
# === Mappings für die Ausgabe ===
|
||||||
|
our %POWER_MODES = (
|
||||||
|
0 => 'on',
|
||||||
|
1 => 'off');
|
||||||
|
|
||||||
|
our %OPERATION_MODES = (
|
||||||
|
0 => 'auto',
|
||||||
|
1 => 'cool',
|
||||||
|
2 => 'heat',
|
||||||
|
3 => 'fan',
|
||||||
|
4 => 'dry'
|
||||||
|
);
|
||||||
|
|
||||||
|
# Betriebsmodus
|
||||||
|
our %COOLHOTJUDGE_MODES = (
|
||||||
|
0 => 'auto',
|
||||||
|
1 => 'cooling',
|
||||||
|
2 => 'haeting');
|
||||||
|
|
||||||
|
our %AIRFLOW = (
|
||||||
|
0 => 'auto',
|
||||||
|
1 => 'lowest',
|
||||||
|
2 => 'low',
|
||||||
|
3 => 'high',
|
||||||
|
4 => 'highest'
|
||||||
|
);
|
||||||
|
|
||||||
|
our %HORIZONTAL_POSITIONS = (
|
||||||
|
0 => 'auto',
|
||||||
|
1 => 'left-left',
|
||||||
|
2 => 'left-center',
|
||||||
|
3 => 'center-center',
|
||||||
|
4 => 'center-right',
|
||||||
|
5 => 'right-right',
|
||||||
|
6 => 'left-right',
|
||||||
|
7 => 'right-left'
|
||||||
|
);
|
||||||
|
|
||||||
|
our %VERTICAL_POSITIONS = (
|
||||||
|
0 => 'auto',
|
||||||
|
1 => 'highest',
|
||||||
|
2 => 'middle',
|
||||||
|
3 => 'normal',
|
||||||
|
4 => 'lowest'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
# === Konstruktor ===
|
||||||
|
sub new {
|
||||||
|
my ($class) = @_;
|
||||||
|
my $self = {
|
||||||
|
airFlow => -1,
|
||||||
|
coolHotJudge => 0,
|
||||||
|
electric => 0,
|
||||||
|
entrust => 0,
|
||||||
|
errorCode => '',
|
||||||
|
indoorTemp => undef,
|
||||||
|
isAutoHeating => 0,
|
||||||
|
isSelfCleanOperation=> 0,
|
||||||
|
isSelfCleanReset => 0,
|
||||||
|
isVacantProperty => 0,
|
||||||
|
modelNo => 0,
|
||||||
|
operation => 0,
|
||||||
|
operationMode => undef,
|
||||||
|
outdoorTemp => undef,
|
||||||
|
presetTemp => undef,
|
||||||
|
windDirectionLR => -1,
|
||||||
|
windDirectionUD => -1
|
||||||
|
};
|
||||||
|
bless $self, $class;
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
# === Hilfsfunktionen ===
|
||||||
|
sub zeroPad {
|
||||||
|
my ($num, $places) = @_;
|
||||||
|
return sprintf("%0${places}d", $num);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub wosoFindMatch {
|
||||||
|
my ($value, $posVals, $p) = @_;
|
||||||
|
$p //= 0;
|
||||||
|
for (my $i = 0; $i < @$posVals; $i++) {
|
||||||
|
return $i + $p if $posVals->[$i] == $value;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# === CRC16-CCITT ===
|
||||||
|
sub crc16ccitt {
|
||||||
|
my ($data_ref) = @_;
|
||||||
|
my $crc = 0xFFFF;
|
||||||
|
foreach my $b (@$data_ref) {
|
||||||
|
$b += 256 if $b < 0;
|
||||||
|
for my $bit (0 .. 7) {
|
||||||
|
my $z = (($crc >> 15) & 1) == 1;
|
||||||
|
my $z2 = (($b >> (7 - $bit)) & 1) == 1;
|
||||||
|
$crc <<= 1;
|
||||||
|
$crc &= 0xFFFF;
|
||||||
|
$crc ^= 0x1021 if ($z != $z2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $crc & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
# === Base64 → Objekt ===
|
||||||
|
sub fromBase64 {
|
||||||
|
my ($class, $base64) = @_;
|
||||||
|
$base64 =~ s/\n//g;
|
||||||
|
my $binary = decode_base64($base64);
|
||||||
|
my @bytes = map {
|
||||||
|
my $h = ord($_);
|
||||||
|
($h > 127) ? -1 * (256 - $h) : $h;
|
||||||
|
} split //, $binary;
|
||||||
|
|
||||||
|
my $self = $class->new();
|
||||||
|
|
||||||
|
my $r3 = 18;
|
||||||
|
my $dataStart = $bytes[$r3] * 4 + 21;
|
||||||
|
my $dataLength = scalar(@bytes) - 2;
|
||||||
|
my @data = @bytes[$dataStart .. $dataLength - 1];
|
||||||
|
my $code = $data[6] & 127;
|
||||||
|
|
||||||
|
$self->{operation} = $POWER_MODES{((3 & $data[2]) == 1) ? 1 : 0};
|
||||||
|
$self->{presetTemp} = $data[4] / 2.0;
|
||||||
|
$self->{operationMode} = $OPERATION_MODES{wosoFindMatch((60 & $data[2]), [8,16,12,4], 1)};
|
||||||
|
$self->{airFlow} = $AIRFLOW{wosoFindMatch((15 & $data[3]), [7,0,1,2,6])};
|
||||||
|
$self->{windDirectionUD}= $VERTICAL_POSITIONS{((192 & $data[2]) == 64) ? 0 :
|
||||||
|
wosoFindMatch((240 & $data[3]), [0,16,32,48], 1)};
|
||||||
|
$self->{windDirectionLR}= $HORIZONTAL_POSITIONS{((3 & $data[12]) == 1) ? 0 :
|
||||||
|
wosoFindMatch((31 & $data[11]), [0,1,2,3,4,5,6], 1)};
|
||||||
|
$self->{entrust} = ((12 & $data[12]) == 4) ? 1 : 0;
|
||||||
|
$self->{coolHotJudge} = $COOLHOTJUDGE_MODES{((8 & $data[8]) <= 0) ? 1 : 0};
|
||||||
|
$self->{modelNo} = wosoFindMatch((127 & $data[0]), [0,1,2]);
|
||||||
|
$self->{isVacantProperty}= (1 & $data[10]);
|
||||||
|
|
||||||
|
if ($code == 0) {
|
||||||
|
$self->{errorCode} = "00";
|
||||||
|
} elsif (($data[6] & -128) <= 0) {
|
||||||
|
$self->{errorCode} = "M" . zeroPad($code, 2);
|
||||||
|
} else {
|
||||||
|
$self->{errorCode} = "E" . $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
# … hier folgt noch die Temperatur- und Electric-Verarbeitung aus JS …
|
||||||
|
my $c = 0;
|
||||||
|
my @vals;
|
||||||
|
|
||||||
|
# Kopiere Werte aus bytes in vals (wie im JS-Code)
|
||||||
|
for (my $i = $dataStart + 19; $i < scalar(@bytes) - 2; $i++) {
|
||||||
|
$vals[$c] = $bytes[$i];
|
||||||
|
# print "Value $c : $vals[$c]\n";
|
||||||
|
$c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (my $i = 0; $i < scalar(@vals); $i += 4) {
|
||||||
|
|
||||||
|
# Outdoor-Temperatur
|
||||||
|
if ($vals[$i] == -128 && $vals[$i + 1] == 16) {
|
||||||
|
my $index = $vals[$i + 2] & 0xFF;
|
||||||
|
# print "Index outdoorTemp : $index\n";
|
||||||
|
$self->{outdoorTemp} = $outdoorTempList[$index];
|
||||||
|
}
|
||||||
|
|
||||||
|
# Indoor-Temperatur
|
||||||
|
if ($vals[$i] == -128 && $vals[$i + 1] == 32) {
|
||||||
|
my $index = $vals[$i + 2] & 0xFF;
|
||||||
|
# print "Index indoorTemp : $index\n";
|
||||||
|
$self->{indoorTemp} = $indoorTempList[$index];
|
||||||
|
}
|
||||||
|
|
||||||
|
# Elektrizität (Watt oder ähnlicher Messwert)
|
||||||
|
if ($vals[$i] == -108 && $vals[$i + 1] == 16) {
|
||||||
|
my @bytes = ($vals[$i + 2], $vals[$i + 3], 0, 0);
|
||||||
|
# Bytes in eine 32-Bit-Zahl umwandeln (Little Endian)
|
||||||
|
my $uint = unpack('L', pack('C4', @bytes));
|
||||||
|
$self->{electric} = $uint * 0.25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Beende das Modul und kehre zum globalen Paket zurück
|
||||||
|
1; # Dies ist notwendig, damit das Modul korrekt geladen wird
|
||||||
263
fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy_old.txt
Normal file
263
fhem/contrib/ch.eick/Klimaanlage/MHI_Heavy_old.txt
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
defmod MHI_Heavy HTTPMOD none 0
|
||||||
|
attr MHI_Heavy DbLogExclude .*
|
||||||
|
attr MHI_Heavy disable 0
|
||||||
|
attr MHI_Heavy enableControlSet 0
|
||||||
|
attr MHI_Heavy get01-1Name info_apiVer
|
||||||
|
attr MHI_Heavy get01-2Name info_command
|
||||||
|
attr MHI_Heavy get01-3Name info_deviceId
|
||||||
|
attr MHI_Heavy get01-4Name info_result
|
||||||
|
attr MHI_Heavy get01-5Name contents_airconId
|
||||||
|
attr MHI_Heavy get01-6Name contents_macAddress
|
||||||
|
attr MHI_Heavy get01-7Name info_operatorId
|
||||||
|
attr MHI_Heavy get01-8Name contents_apMode
|
||||||
|
attr MHI_Heavy get01-9Name info_timestamp
|
||||||
|
attr MHI_Heavy get01CheckAllReadings 1
|
||||||
|
attr MHI_Heavy get01Data {"apiVer":"1.0","command":"getDeviceInfo","deviceId":"%deviceId%","operatorId":"%operatorId%","timestamp":%TIME%}
|
||||||
|
attr MHI_Heavy get01JSON .
|
||||||
|
attr MHI_Heavy get01Name 01_getDeviceInfo
|
||||||
|
attr MHI_Heavy get01URL http://%IP-MHI_Heavy%:51443/beaver/command
|
||||||
|
attr MHI_Heavy get02-10Name contents_logStat
|
||||||
|
attr MHI_Heavy get02-11Name contents_lowTemp
|
||||||
|
attr MHI_Heavy get02-12Name contents_wireless_firmVer
|
||||||
|
attr MHI_Heavy get02-13Name contents_numOfAccount
|
||||||
|
attr MHI_Heavy get02-14Name contents_remoteList_0
|
||||||
|
attr MHI_Heavy get02-15Name contents_remoteList_1
|
||||||
|
attr MHI_Heavy get02-16Name contents_remoteList_2
|
||||||
|
attr MHI_Heavy get02-17Name contents_remoteList_3
|
||||||
|
attr MHI_Heavy get02-18Name contents_timezone
|
||||||
|
attr MHI_Heavy get02-19Name contents_updatedBy
|
||||||
|
attr MHI_Heavy get02-1Name info_apiVer
|
||||||
|
attr MHI_Heavy get02-20Name contents_mcu_firmVer
|
||||||
|
attr MHI_Heavy get02-21Name contents_airconId
|
||||||
|
attr MHI_Heavy get02-22Name info_operatorId
|
||||||
|
attr MHI_Heavy get02-23Name contents_ledStat
|
||||||
|
attr MHI_Heavy get02-24Name info_timestamp
|
||||||
|
attr MHI_Heavy get02-2Name info_command
|
||||||
|
attr MHI_Heavy get02-3Name info_deviceId
|
||||||
|
attr MHI_Heavy get02-4Name contents_airconStat
|
||||||
|
attr MHI_Heavy get02-5Name contents_autoHeating
|
||||||
|
attr MHI_Heavy get02-6Name contents_expires
|
||||||
|
attr MHI_Heavy get02-7Name contents_firmType
|
||||||
|
attr MHI_Heavy get02-8Name contents_highTemp
|
||||||
|
attr MHI_Heavy get02-9Name info_result
|
||||||
|
attr MHI_Heavy get02CheckAllReadings 1
|
||||||
|
attr MHI_Heavy get02Data {"apiVer":"1.0","command":"getAirconStat","deviceId":"%deviceId%","operatorId":"%operatorId%","timestamp":%TIME%}
|
||||||
|
attr MHI_Heavy get02JSON .
|
||||||
|
attr MHI_Heavy get02Name 02_getAirconStat
|
||||||
|
attr MHI_Heavy get02URL http://%IP-MHI_Heavy%:51443/beaver/command
|
||||||
|
attr MHI_Heavy get03CheckAllReadings 1
|
||||||
|
attr MHI_Heavy get03Data {"apiVer":"1.0","command":"getAccountInfo","deviceId":"%deviceId%","operatorId":"%operatorId%","timestamp":%TIME%}
|
||||||
|
attr MHI_Heavy get03JSON .
|
||||||
|
attr MHI_Heavy get03Name 03_getAccountInfo
|
||||||
|
attr MHI_Heavy get03URL http://%IP-MHI_Heavy%:51443/beaver/command
|
||||||
|
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 replacement02Mode text
|
||||||
|
attr MHI_Heavy replacement02Regex %deviceId%
|
||||||
|
attr MHI_Heavy replacement02Value <deviceId>
|
||||||
|
attr MHI_Heavy replacement03Mode text
|
||||||
|
attr MHI_Heavy replacement03Regex %operatorId%
|
||||||
|
attr MHI_Heavy replacement03Value <operatorId>
|
||||||
|
attr MHI_Heavy replacement04Mode expression
|
||||||
|
attr MHI_Heavy replacement04Regex %TIME%
|
||||||
|
attr MHI_Heavy replacement04Value {round(time(),0)}
|
||||||
|
attr MHI_Heavy replacement05Mode reading
|
||||||
|
attr MHI_Heavy replacement05Regex %AIRCONSTAT%
|
||||||
|
attr MHI_Heavy replacement05Value contents_airconStat
|
||||||
|
attr MHI_Heavy room Neu
|
||||||
|
attr MHI_Heavy set02-10Name contents_logStat
|
||||||
|
attr MHI_Heavy set02-11Name contents_lowTemp
|
||||||
|
attr MHI_Heavy set02-12Name contents_wireless_firmVer
|
||||||
|
attr MHI_Heavy set02-13Name contents_numOfAccount
|
||||||
|
attr MHI_Heavy set02-14Name contents_remoteList_0
|
||||||
|
attr MHI_Heavy set02-15Name contents_remoteList_1
|
||||||
|
attr MHI_Heavy set02-16Name contents_remoteList_2
|
||||||
|
attr MHI_Heavy set02-17Name contents_remoteList_3
|
||||||
|
attr MHI_Heavy set02-18Name contents_timezone
|
||||||
|
attr MHI_Heavy set02-19Name contents_updatedBy
|
||||||
|
attr MHI_Heavy set02-1Name info_apiVer
|
||||||
|
attr MHI_Heavy set02-20Name contents_mcu_firmVer
|
||||||
|
attr MHI_Heavy set02-21Name contents_airconId
|
||||||
|
attr MHI_Heavy set02-22Name info_operatorId
|
||||||
|
attr MHI_Heavy set02-23Name contents_ledStat
|
||||||
|
attr MHI_Heavy set02-24Name info_timestamp
|
||||||
|
attr MHI_Heavy set02-2Name info_command
|
||||||
|
attr MHI_Heavy set02-3Name info_deviceId
|
||||||
|
attr MHI_Heavy set02-4Name contents_airconStat
|
||||||
|
attr MHI_Heavy set02-5Name contents_autoHeating
|
||||||
|
attr MHI_Heavy set02-6Name contents_expires
|
||||||
|
attr MHI_Heavy set02-7Name contents_firmType
|
||||||
|
attr MHI_Heavy set02-8Name contents_highTemp
|
||||||
|
attr MHI_Heavy set02-9Name info_result
|
||||||
|
attr MHI_Heavy set02CheckAllReadings 1
|
||||||
|
attr MHI_Heavy set02Data {"apiVer":"1.0","command":"setAirconStat","operatorId":"%operatorId%","deviceId":"%deviceId%","timestamp":%TIME%,"contents":{"airconId":"%operatorId%","airconStat":"%AIRCONSTAT%"}}
|
||||||
|
attr MHI_Heavy set02JSON .
|
||||||
|
attr MHI_Heavy set02Name 02_setAirconStat
|
||||||
|
attr MHI_Heavy set02NoArg 1
|
||||||
|
attr MHI_Heavy set02ParseResponse 1
|
||||||
|
attr MHI_Heavy set02URL http://%IP-MHI_Heavy%:51443/beaver/command
|
||||||
|
attr MHI_Heavy set03-1Name info_apiVer
|
||||||
|
attr MHI_Heavy set03-2Name info_command
|
||||||
|
attr MHI_Heavy set03-3Name info_deviceId
|
||||||
|
attr MHI_Heavy set03-4Name info_operatorId
|
||||||
|
attr MHI_Heavy set03-5Name info_result
|
||||||
|
attr MHI_Heavy set03-6Name info_timestamp
|
||||||
|
attr MHI_Heavy set03CheckAllReadings 1
|
||||||
|
attr MHI_Heavy set03Data {"apiVer":"1.0","command":"updateAccountInfo","deviceId":"%deviceId%","operatorId":"%operatorId%","timestamp":%TIME%}
|
||||||
|
attr MHI_Heavy set03JSON .
|
||||||
|
attr MHI_Heavy set03Method PUT
|
||||||
|
attr MHI_Heavy set03Name 03_updateAccountInfo
|
||||||
|
attr MHI_Heavy set03NoArg 1
|
||||||
|
attr MHI_Heavy set03ParseResponse 1
|
||||||
|
attr MHI_Heavy set03URL http://%IP-MHI_Heavy%:51443/beaver/command
|
||||||
|
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_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