From 8ffbeacd763726560b0664799b2913acebb13a78 Mon Sep 17 00:00:00 2001 From: daniel2311 <> Date: Sat, 9 Dec 2017 11:44:57 +0000 Subject: [PATCH] 38_Broadlink.pm: Temperature on RMPro, Support for SP3S power consumption git-svn-id: https://svn.fhem.de/fhem/trunk@15578 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/38_Broadlink.pm | 206 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 198 insertions(+), 8 deletions(-) diff --git a/fhem/FHEM/38_Broadlink.pm b/fhem/FHEM/38_Broadlink.pm index 83930e5f9..faf11c095 100644 --- a/fhem/FHEM/38_Broadlink.pm +++ b/fhem/FHEM/38_Broadlink.pm @@ -4,7 +4,6 @@ package main; use strict; use warnings; -use integer; use Time::Local; use IO::Socket::INET; use IO::Select; @@ -66,7 +65,7 @@ sub Broadlink_Define($$) { $hash->{'.id'} = pack('C*', 0, 0, 0, 0); $hash->{counter} = 1; $hash->{isAuthenticated} = 0; - if ($hash->{devtype} eq 'sp3') { #steckdose + if ($hash->{devtype} eq 'sp3' or $hash->{devtype} eq 'sp3s') { #steckdose Broadlink_auth($hash); if ($hash->{isAuthenticated} != 0) { Broadlink_sp3_getStatus($hash, 1); @@ -93,7 +92,7 @@ sub Broadlink_Get($@) { sub Broadlink_Set(@) { my ($hash, $name, $cmd, @args) = @_; - if ($hash->{devtype} eq 'sp3') { #steckdose + if ($hash->{devtype} eq 'sp3' or $hash->{devtype} eq 'sp3s') { #steckdose if ($cmd eq 'on') { Broadlink_auth($hash); if ($hash->{isAuthenticated} != 0) { @@ -125,8 +124,18 @@ sub Broadlink_Set(@) { Broadlink_sp3_getStatus($hash); } return undef; + } elsif ($cmd eq 'getEnergy' and $hash->{devtype} eq 'sp3s') { + Broadlink_auth($hash); + if ($hash->{isAuthenticated} != 0) { + Broadlink_sp3s_getEnergy($hash); + } + return undef; } else { - return "Unknown argument $cmd, choose one of on off toggle getStatus"; + if ($hash->{devtype} eq 'sp3s') { + return "Unknown argument $cmd, choose one of on off toggle getStatus getEnergy"; + } else { + return "Unknown argument $cmd, choose one of on off toggle getStatus"; + } } return "$cmd. Try to get it."; } else { #rmpro rmmini etc. @@ -186,6 +195,12 @@ sub Broadlink_Set(@) { delete($hash->{commandList}{$cmdname}); Broadlink_Save($hash); return undef; + } elsif ($cmd eq 'getTemperature' and $hash->{devtype} eq 'rmpro') { + Broadlink_auth($hash); + if ($hash->{isAuthenticated} != 0) { + Broadlink_getTemperature($hash); + } + return undef; } else { #sort with ignore case my $commandList = join(",", sort { @@ -193,7 +208,11 @@ sub Broadlink_Set(@) { || $a cmp $b } keys %{$hash->{commandList}}); #return "Unknown argument $cmd, choose one of learnNewCommand sendCommand sendCommandBase64 sendCommandHex createCommandBase64 createCommandHex"; - return "Unknown argument $cmd, choose one of recordNewCommand rename remove:" . $commandList . " commandSend:". $commandList; + if ($hash->{devtype} eq 'rmpro') { + return "Unknown argument $cmd, choose one of recordNewCommand rename getTemperature remove:" . $commandList . " commandSend:". $commandList; + } else { + return "Unknown argument $cmd, choose one of recordNewCommand rename remove:" . $commandList . " commandSend:". $commandList; + } } return "$cmd. Try to get it."; } @@ -267,6 +286,41 @@ sub Broadlink_check_data(@) { } } +sub Broadlink_getTemperature(@) { + my ($hash) = @_; + my @broadlink_payload = ((0) x 16); + $broadlink_payload[0] = 1; + + my $msg = "sp3_energy request"; + Log3 $hash->{NAME}, 5, $hash->{NAME} . ": " . $msg; + my $data = Broadlink_send_packet($hash, 0x6a, @broadlink_payload); + #length must be bigger than 0x38, if not, cant get substring with data + if (length($data) > 0x38 && $data ne "xxx") { + my $err = unpack("C*", substr($data, 0x22, 1)) | (unpack("C*", substr($data, 0x23, 1)) << 8); + if ($err == 0) { + my $msg = "sp3 receiving temperature - data length: " . length($data); + Log3 $hash->{NAME}, 1, $hash->{NAME} . ": " . $msg; + my $enc_payload = substr($data, 0x38); + my $cipher = Broadlink_getCipher($hash); + my $decodedData = $cipher->decrypt($enc_payload); + my $temperature = 0.0; + if (unpack("C*", substr($decodedData, 4, 1)) =~ /^\d+?$/) { #isint + $temperature = (unpack("C*", substr($decodedData, 4, 1)) * 10 + unpack("C*", substr($decodedData, 5, 1))) / 10.0; + } else { + $temperature = (ord(unpack("C*", substr($decodedData, 4, 1))) * 10 + ord(unpack("C*", substr($decodedData, 5, 1)))) / 10.0; + } + readingsSingleUpdate ( $hash, "currentTemperature", $temperature, 1 ); + } else { + my $msg = "Error receiving temperature"; + Log3 $hash->{NAME}, 4, $hash->{NAME} . ": " . $msg; + readingsSingleUpdate ( $hash, "connectionErrorOn", "geTemperatureWithData", 1 ); + } + } else { + my $msg = "no new temperature data found - data length: " . length($data); + Log3 $hash->{NAME}, 4, $hash->{NAME} . ": " . $msg; + readingsSingleUpdate ( $hash, "connectionErrorOn", "getTemperature", 1 ); + } +} sub Broadlink_sp3_getStatus(@) { my ($hash) = @_; @@ -296,7 +350,7 @@ sub Broadlink_sp3_getStatus(@) { readingsSingleUpdate ( $hash, "connectionErrorOn", "geStatusWithData", 1 ); } } else { - my $msg = "no new command data found - data length: " . length($data); + my $msg = "no new status data found - data length: " . length($data); Log3 $hash->{NAME}, 4, $hash->{NAME} . ": " . $msg; $hash->{STATE} = "unknown"; readingsSingleUpdate ( $hash, "connectionErrorOn", "geStatus", 1 ); @@ -330,6 +384,42 @@ sub Broadlink_sp3_setPower(@) { } } +sub Broadlink_sp3s_getEnergy(@) { + my ($hash) = @_; + my @broadlink_payload = ((0) x 16); + $broadlink_payload[0] = 8; + $broadlink_payload[2] = 254; + $broadlink_payload[3] = 1; + $broadlink_payload[4] = 5; + $broadlink_payload[5] = 1; + $broadlink_payload[9] = 45; + #my @broadlink_payload = pack('C*', 8, 0, 254, 1, 5, 1, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0); + + my $msg = "sp3_energy request"; + Log3 $hash->{NAME}, 5, $hash->{NAME} . ": " . $msg; + my $data = Broadlink_send_packet($hash, 0x6a, @broadlink_payload); + #length must be bigger than 0x38, if not, cant get substring with data + if (length($data) > 0x38 && $data ne "xxx") { + my $err = unpack("C*", substr($data, 0x22, 1)) | (unpack("C*", substr($data, 0x23, 1)) << 8); + if ($err == 0) { + my $msg = "sp3 receiving energy - data length: " . length($data); + Log3 $hash->{NAME}, 1, $hash->{NAME} . ": " . $msg; + my $enc_payload = substr($data, 0x38); + my $cipher = Broadlink_getCipher($hash); + my $decodedData = $cipher->decrypt($enc_payload); + readingsSingleUpdate ( $hash, "currentPowerComsuption", sprintf("%.2f", (sprintf("%X", unpack("C*", substr($decodedData, 7, 1)) * 256 + unpack("C*", substr($decodedData, 6, 1))) + sprintf("%.2f", sprintf("%X", unpack("C*", substr($decodedData, 5, 1))) / 100.0))), 1 ); + } else { + my $msg = "Error receiving energy"; + Log3 $hash->{NAME}, 4, $hash->{NAME} . ": " . $msg; + readingsSingleUpdate ( $hash, "connectionErrorOn", "geEnergyWithData", 1 ); + } + } else { + my $msg = "no new ernergy data found - data length: " . length($data); + Log3 $hash->{NAME}, 4, $hash->{NAME} . ": " . $msg; + readingsSingleUpdate ( $hash, "connectionErrorOn", "getEnergy", 1 ); + } +} + sub Broadlink_enterLearning(@) { my ($hash, $cmdname) = @_; my @broadlink_payload = ((0) x 16); @@ -603,6 +693,7 @@ sub Broadlink_Load(@) {

Broadlink