some changes and fixes

close #16
close #15
close #14
close #13

-change: the sensors now align themselves with their real gateway (iodev)
-change: the ne aqara cube is supportet but the firmware has an bug
-change batteryreadings changed to FHEM standard
This commit is contained in:
2018-06-22 13:50:57 +02:00
parent e4b1f0cb0c
commit ad1fa232ca
3 changed files with 135 additions and 113 deletions

View File

@@ -42,7 +42,6 @@ eval "use Net::Ping";
return "\nERROR: Please install Net::Ping" if($@); return "\nERROR: Please install Net::Ping" if($@);
use Color; use Color;
use SetExtensions; use SetExtensions;
@@ -52,7 +51,7 @@ sub XiaomiSmartHome_Notify($$);
sub XiaomiSmartHome_updateSingleReading($$); sub XiaomiSmartHome_updateSingleReading($$);
my $iv="\x17\x99\x6d\x09\x3d\x28\xdd\xb3\xba\x69\x5a\x2e\x6f\x58\x56\x2e"; my $iv="\x17\x99\x6d\x09\x3d\x28\xdd\xb3\xba\x69\x5a\x2e\x6f\x58\x56\x2e";
my $version = "1.21"; my $version = "1.30";
my %XiaomiSmartHome_gets = ( my %XiaomiSmartHome_gets = (
"getDevices" => ["get_id_list", '^.+get_id_list_ack' ], "getDevices" => ["get_id_list", '^.+get_id_list_ack' ],
@@ -76,7 +75,7 @@ my %sets = (
sub XiaomiSmartHome_Initialize($) { sub XiaomiSmartHome_Initialize($) {
my ($hash) = @_; my ($hash) = @_;
$hash->{Clients} = "XiaomiSmartHome_Device"; $hash->{Clients} = "XiaomiSmartHome_Device";
$hash->{DefFn} = 'XiaomiSmartHome_Define'; $hash->{DefFn} = 'XiaomiSmartHome_Define';
$hash->{UndefFn} = 'XiaomiSmartHome_Undef'; $hash->{UndefFn} = 'XiaomiSmartHome_Undef';
@@ -88,12 +87,12 @@ sub XiaomiSmartHome_Initialize($) {
$hash->{WriteFn} = "XiaomiSmartHome_Write"; $hash->{WriteFn} = "XiaomiSmartHome_Write";
$hash->{AttrList} = "disable:1,0 " . $hash->{AttrList} = "disable:1,0 " .
$readingFnAttributes; $readingFnAttributes;
$hash->{MatchList} = { "1:XiaomiSmartHome_Device" => ".*magnet.*", $hash->{MatchList} = { "1:XiaomiSmartHome_Device" => ".*magnet.*",
"2:XiaomiSmartHome_Device" => ".*motion.*", "2:XiaomiSmartHome_Device" => ".*motion.*",
"3:XiaomiSmartHome_Device" => "^.+sensor_ht", "3:XiaomiSmartHome_Device" => "^.+sensor_ht",
"4:XiaomiSmartHome_Device" => ".*switch.*", "4:XiaomiSmartHome_Device" => ".*switch.*",
"5:XiaomiSmartHome_Device" => "^.+cube", "5:XiaomiSmartHome_Device" => ".*cube.*",
"6:XiaomiSmartHome_Device" => "^.+plug", "6:XiaomiSmartHome_Device" => "^.+plug",
"7:XiaomiSmartHome_Device" => "^.+86sw1", "7:XiaomiSmartHome_Device" => "^.+86sw1",
"8:XiaomiSmartHome_Device" => "^.+86sw2", "8:XiaomiSmartHome_Device" => "^.+86sw2",
@@ -108,7 +107,7 @@ sub XiaomiSmartHome_Initialize($) {
"17:XiaomiSmartHome_Device" => "^.+smoke", "17:XiaomiSmartHome_Device" => "^.+smoke",
"18:XiaomiSmartHome_Device" => "^.+weather.v1", "18:XiaomiSmartHome_Device" => "^.+weather.v1",
"19:XiaomiSmartHome_Device" => "^.+sensor_motion.aq2", "19:XiaomiSmartHome_Device" => "^.+sensor_motion.aq2",
"20:XiaomiSmartHome_Device" => "^.+sensor_wleak.aq1"}; "20:XiaomiSmartHome_Device" => "^.+sensor_wleak.aq1"};
FHEM_colorpickerInit(); FHEM_colorpickerInit();
} }
##################################### #####################################
@@ -116,7 +115,7 @@ sub XiaomiSmartHome_Read($) {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $self = {}; # my new hash my $self = {}; # my new hash
Log3 $name, 5, "$name: Read> Read start"; Log3 $name, 5, "$name: Read> Read start";
if ( ! $hash->{SID} ){ if ( ! $hash->{SID} ){
Log3 $name, 3, "$name: Read> No SID, Stop Read"; Log3 $name, 3, "$name: Read> No SID, Stop Read";
@@ -143,20 +142,37 @@ sub XiaomiSmartHome_Read($) {
} }
if ($json) if ($json)
{ {
Log3 $name, 5, "$name: Read> " . $buf; Log3 $name, 5, "$name: Read> [PLAIN] " . $buf;
my $rsid = $decoded->{'sid'}; my $rsid = $decoded->{'sid'};
if ($decoded->{'cmd'} eq 'read_ack' || $decoded->{'cmd'} eq 'report' && $decoded->{'model'} ne 'gateway'|| $decoded->{'cmd'} eq 'heartbeat' && $decoded->{'model'} ne 'gateway' || $decoded->{'cmd'} eq 'write_ack' && $decoded->{'model'} ne 'gateway') { if ($decoded->{'cmd'} eq 'read_ack' || $decoded->{'cmd'} eq 'report' && $decoded->{'model'} ne 'gateway'|| $decoded->{'cmd'} eq 'heartbeat' && $decoded->{'model'} ne 'gateway' || $decoded->{'cmd'} eq 'write_ack' && $decoded->{'model'} ne 'gateway') {
if ( $modules{XiaomiSmartHome_Device}{defptr}{$rsid}->{SID} = $rsid ){ if (!$modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME}){
Log3 $name, 5, "$name: Read> Dispatch " . $buf; Log3 $name, 5, "$name: Read> XiaomiSmartHome_Device unknown trying autocreate" ;
my $devhash = $modules{XiaomiSmartHome_Device}{defptr}{$rsid}->{IODev}; my $def=$modules{XiaomiSmartHome}{defptr};
Dispatch($devhash, $buf, undef); while(my ($key, $value) =each(%$def)){
XiaomiSmartHome_Write($value, 'get_id_list');
Log3 $value->{NAME}, 5, "$value->{NAME}: Push to get all Sensors for Gateway $value->{NAME} " . $key;
if ($value->{helper}{sensors} =~ m/$rsid/ ) {
Log3 $value->{NAME}, 5, "$value->{NAME}: $rsid is sensor from $value->{NAME}";
Dispatch($value, $buf, undef);
return;
}
}
} }
else { if ($modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} eq $hash->{NAME}) {
Log3 $name, 5, "$name: Read> Dispatch " . $buf; Log3 $name, 5, "$name: Read> XiaomiSmartHome_Device known! " . "SID: " . $rsid . " " . $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} . " " . $hash->{NAME};
Dispatch($hash, $buf, undef); }
elsif ($modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} ne $hash->{NAME}) {
Log3 $name, 5, "$name: Read> Wrong Modul HASH Trying to find the right one " . $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} . " <> " . $hash->{NAME} ;
$hash = $modules{XiaomiSmartHome_Device}{defptr}{$rsid}->{IODev};
Log3 $name, 5, "$name: Read> Using this GW " . $hash->{NAME};
}
Log3 $name, 5, "$name: Read> Dispatching " . $buf . " " . $hash->{NAME};
Dispatch($hash, $buf, undef);
}
elsif (!$modules{XiaomiSmartHome}{defptr}{$rsid}){
Log3 $name, 1, "$name: Read> GW not defined " . $buf;
return;
} }
}
elsif ( $modules{XiaomiSmartHome}{defptr}{$rsid}->{SID} ne $hash->{SID} ){ elsif ( $modules{XiaomiSmartHome}{defptr}{$rsid}->{SID} ne $hash->{SID} ){
$self = $modules{XiaomiSmartHome}{defptr}{$rsid}; $self = $modules{XiaomiSmartHome}{defptr}{$rsid};
Log3 $name, 5, "$name: Read> Change HASH Ref to $self->{NAME}"; Log3 $name, 5, "$name: Read> Change HASH Ref to $self->{NAME}";
@@ -216,7 +232,7 @@ sub XiaomiSmartHome_Reading ($@) {
#$hash->{SID} = $decoded->{'sid'}; #$hash->{SID} = $decoded->{'sid'};
} }
else { else {
Log3 $name, 4, "$name: Reading> IP-Heartbeat Data didnt match! $data->{ip} " . $hash->{GATEWAY_IP} ; Log3 $name, 5, "$name: Reading> IP-Heartbeat Data didnt match! $data->{ip} " . $hash->{GATEWAY_IP} ;
} }
} }
} }
@@ -232,10 +248,10 @@ sub XiaomiSmartHome_Reading ($@) {
return; return;
} }
if ($data->{error}){ if ($data->{error}){
readingsBulkUpdate($hash, 'heartbeat', $data->{error}, 1 ); readingsBulkUpdate($hash, 'heartbeat', $data->{error}, 1 );
} }
else { else {
readingsBulkUpdate($hash, 'heartbeat', "Write_OK", 1 ); readingsBulkUpdate($hash, 'heartbeat', "Write_OK", 1 );
readingsBulkUpdate($hash, "proto_version", $data->{proto_version} , 1 ); readingsBulkUpdate($hash, "proto_version", $data->{proto_version} , 1 );
} }
} }
@@ -253,7 +269,7 @@ sub XiaomiSmartHome_Reading ($@) {
return; return;
} }
my $all_sensors = ""; my $all_sensors = "";
foreach my $sensor (@sensors) foreach my $sensor (@sensors)
{ {
Log3 $name, 4, "$name: Reading> PushRead:" . $sensor; Log3 $name, 4, "$name: Reading> PushRead:" . $sensor;
XiaomiSmartHome_Write($hash, 'read', $sensor ); XiaomiSmartHome_Write($hash, 'read', $sensor );
@@ -306,16 +322,16 @@ sub XiaomiSmartHome_getGatewaySID($){
} }
if ($json) { if ($json) {
if ($decoded->{'ip'} eq $ip){ if ($decoded->{'ip'} eq $ip){
Log3 $name, 4, "$name: getGatewaySID> Find SID for Gateway: $decoded->{sid}"; Log3 $name, 3, "$name: getGatewaySID> Find SID for Gateway: $decoded->{sid}";
$sidsock->close(); $sidsock->close();
$hash->{SID} = $decoded->{sid}; $hash->{SID} = $decoded->{sid};
$modules{XiaomiSmartHome}{defptr}{$decoded->{sid}} = $hash; $modules{XiaomiSmartHome}{defptr}{$decoded->{sid}} = $hash;
return $decoded->{sid}; return $decoded->{sid};
} }
else { else {
Log3 $name, 4, "$name: getGatewaySID> whois Data didnt match! $decoded->{sid} $decoded->{'ip'} ". $ip ; Log3 $name, 5, "$name: getGatewaySID> whois Data didnt match! $decoded->{sid} $decoded->{'ip'} ". $ip ;
} }
} }
}; };
if ($@) { if ($@) {
Log3 $name, 1, "$name: getGatewaySID> Error no response from whois!! STOP!!"; Log3 $name, 1, "$name: getGatewaySID> Error no response from whois!! STOP!!";
@@ -346,8 +362,8 @@ sub XiaomiSmartHome_Define($$) {
if ( ! $p->ping($param[2])){ if ( ! $p->ping($param[2])){
$hash->{STATE} = "Disconnected"; $hash->{STATE} = "Disconnected";
XiaomiSmartHome_disconnect($hash); XiaomiSmartHome_disconnect($hash);
Log3 $name, 5, "$name: Define> Ping ERROR Gateway disconnecting"; Log3 $name, 1, "$name: Define> Ping ERROR Gateway disconnecting";
$p->close(); $p->close();
} }
my $GATEWAY_IP = $param[2]; my $GATEWAY_IP = $param[2];
my $definition = $param[2]; my $definition = $param[2];
@@ -359,7 +375,7 @@ sub XiaomiSmartHome_Define($$) {
$hash->{helper}{JSON} = JSON->new->utf8(); $hash->{helper}{JSON} = JSON->new->utf8();
$hash->{FHEMIP} = XiaomiSmartHome_getLocalIP(); $hash->{FHEMIP} = XiaomiSmartHome_getLocalIP();
$hash->{STATE} = "initialized"; $hash->{STATE} = "initialized";
$hash->{helper}{host} = $definition; $hash->{helper}{host} = $definition;
if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){
eval { eval {
$GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ; $GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ;
@@ -374,24 +390,24 @@ sub XiaomiSmartHome_Define($$) {
} }
} }
$hash->{GATEWAY_IP} = $GATEWAY_IP; $hash->{GATEWAY_IP} = $GATEWAY_IP;
$modules{XiaomiSmartHome}{defptr}{$GATEWAY_IP} = $hash; #$modules{XiaomiSmartHome}{defptr}{$GATEWAY_IP} = $hash;
#$hash->{SID} = XiaomiSmartHome_getGatewaySID($hash); #$hash->{SID} = XiaomiSmartHome_getGatewaySID($hash);
Log3 $name, 5, "$name: Define> $definition"; Log3 $name, 5, "$name: Define> $definition";
# Define devStateIcon # Define devStateIcon
$attr{$hash->{NAME}}{devStateIcon} = '{Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}' if(!defined($attr{$hash->{NAME}}{devStateIcon})); $attr{$hash->{NAME}}{devStateIcon} = '{Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}' if(!defined($attr{$hash->{NAME}}{devStateIcon}));
$attr{$hash->{NAME}}{room} = "MiSmartHome" if( !defined( $attr{$hash->{NAME}}{room} ) ); $attr{$hash->{NAME}}{room} = "MiSmartHome" if( !defined( $attr{$hash->{NAME}}{room} ) );
InternalTimer(gettimeofday() + 5, "XiaomiSmartHome_connect", $hash, 0); InternalTimer(gettimeofday() + 5, "XiaomiSmartHome_connect", $hash, 0);
return undef; return undef;
} }
##################################### #####################################
sub XiaomiSmartHome_Undef($$) { sub XiaomiSmartHome_Undef($$) {
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
XiaomiSmartHome_disconnect($hash); XiaomiSmartHome_disconnect($hash);
# nothing to do # nothing to do
return undef; return undef;
@@ -402,7 +418,7 @@ sub XiaomiSmartHome_Write($@)
{ {
my ($hash,$cmd,$val,$iohash) = @_; my ($hash,$cmd,$val,$iohash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if ( $hash->{helper}{ConnectionState} eq 'Disconnected') { if ( $hash->{helper}{ConnectionState} eq 'Disconnected') {
Log3 $name, 1, "$name: Write> Cannot write iam disconnected"; Log3 $name, 1, "$name: Write> Cannot write iam disconnected";
return undef; return undef;
} }
@@ -413,7 +429,7 @@ sub XiaomiSmartHome_Write($@)
Log3 $name, 1, "$name: Write> Ping to $hash->{helper}{host} failed"; Log3 $name, 1, "$name: Write> Ping to $hash->{helper}{host} failed";
$hash->{STATE} = "Disconnected"; $hash->{STATE} = "Disconnected";
XiaomiSmartHome_disconnect($hash); XiaomiSmartHome_disconnect($hash);
$p->close(); $p->close();
return undef; return undef;
} }
} }
@@ -507,7 +523,7 @@ sub XiaomiSmartHome_Write($@)
my $sock = $hash->{CD}; my $sock = $hash->{CD};
my $MAXLEN = 1024; my $MAXLEN = 1024;
$sock->mcast_send($msg,$GATEWAY .':9898') or die "send: $!"; $sock->mcast_send($msg,$GATEWAY .':9898') or die "send: $!";
Log3 $name, 5, "$name: Write> End " . $GATEWAY; Log3 $name, 4, "$name: Write> End " . $GATEWAY;
return undef; return undef;
} }
##################################### #####################################
@@ -518,9 +534,9 @@ sub XiaomiSmartHome_EncryptKey($)
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if ( $hash->{READINGS}{password}{VAL} =~ /^[a-zA-Z0-9]{16}$/ ) { if ( $hash->{READINGS}{password}{VAL} =~ /^[a-zA-Z0-9]{16}$/ ) {
my $key = $hash->{READINGS}{password}{VAL}; my $key = $hash->{READINGS}{password}{VAL};
my $cipher = Crypt::CBC->new(-key => $key, -cipher => 'Cipher::AES',-iv => $iv, -literal_key => 1, -header => "none", -keysize => 16 ); my $cipher = Crypt::CBC->new(-key => $key, -cipher => 'Cipher::AES',-iv => $iv, -literal_key => 1, -header => "none", -keysize => 16 );
my $encryptkey = $cipher->encrypt_hex($hash->{READINGS}{token}{VAL}); my $encryptkey = $cipher->encrypt_hex($hash->{READINGS}{token}{VAL});
$encryptkey = substr($encryptkey, 0, 32); $encryptkey = substr($encryptkey, 0, 32);
return $encryptkey; return $encryptkey;
} }
else else
@@ -534,16 +550,18 @@ sub XiaomiSmartHome_EncryptKey($)
sub XiaomiSmartHome_Get($@) sub XiaomiSmartHome_Get($@)
{ {
my ($hash , $name, $opt, $args ) = @_; my ($hash , $name, $opt, $args ) = @_;
if ($opt eq "UpdateAll") if ($opt eq "UpdateAll")
{ {
XiaomiSmartHome_updateAllReadings($hash); XiaomiSmartHome_updateAllReadings($hash);
Log3 $name, 5, "$name: Get> UpdateALLReadings Started"; Log3 $name, 3, "$name: Get> UpdateALLReadings Started";
return "UpdateALLReadings Started";
} }
elsif($opt eq "UpdateSingle") elsif($opt eq "UpdateSingle")
{ {
XiaomiSmartHome_updateSingleReading($hash,$args); XiaomiSmartHome_updateSingleReading($hash,$args);
Log3 $name, 5, "$name: Get> UpdateSingel Started"; Log3 $name, 3, "$name: Get> UpdateSingel Started";
return "UpdateSingel " . $args . " Started";
} }
else else
{ {
@@ -559,9 +577,9 @@ sub XiaomiSmartHome_Notify($$)
Log3 $ownName, 5, "$ownName: Notify> NotifyStart"; Log3 $ownName, 5, "$ownName: Notify> NotifyStart";
return "" if(IsDisabled($ownName)); # Return without any further action if the module is disabled return "" if(IsDisabled($ownName)); # Return without any further action if the module is disabled
$attr{$hash->{NAME}}{webCmd} = "pct:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:on:off" if ( ! $attr{$hash->{NAME}}{webCmd} || $attr{$hash->{NAME}}{webCmd} eq "rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:on:off" ); $attr{$hash->{NAME}}{webCmd} = "pct:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:on:off" if ( ! $attr{$hash->{NAME}}{webCmd} || $attr{$hash->{NAME}}{webCmd} eq "rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:on:off" );
readingsSingleUpdate($hash, "pct", 100, 1) if ( ! $hash->{READINGS}{pct}{VAL}); readingsSingleUpdate($hash, "pct", 100, 1) if ( ! $hash->{READINGS}{pct}{VAL});
readingsSingleUpdate($hash, "ringtone", 21, 1) if ( ! $hash->{READINGS}{ringtone}{VAL}); readingsSingleUpdate($hash, "ringtone", 21, 1) if ( ! $hash->{READINGS}{ringtone}{VAL});
readingsSingleUpdate($hash, "volume", 10, 1) if ( ! $hash->{READINGS}{volume}{VAL}); readingsSingleUpdate($hash, "volume", 10, 1) if ( ! $hash->{READINGS}{volume}{VAL});
my $devName = $dev_hash->{NAME}; # Device that created the events my $devName = $dev_hash->{NAME}; # Device that created the events
my $events = deviceEvents($dev_hash, 1); my $events = deviceEvents($dev_hash, 1);
if($devName eq "global" && grep(m/^INITIALIZED|REREADCFG$/, @{$events})) if($devName eq "global" && grep(m/^INITIALIZED|REREADCFG$/, @{$events}))
@@ -573,7 +591,7 @@ sub XiaomiSmartHome_Notify($$)
} }
##################################### #####################################
sub XiaomiSmartHome_Set($@) sub XiaomiSmartHome_Set($@)
{ {
my ( $hash, $name, $cmd, @args ) = @_; my ( $hash, $name, $cmd, @args ) = @_;
my $dec_num; my $dec_num;
@@ -582,14 +600,14 @@ sub XiaomiSmartHome_Set($@)
#-- check argument #-- check argument
return SetExtensions($hash, join(" ", keys %sets), $name, $cmd, @args) unless @match == 1; return SetExtensions($hash, join(" ", keys %sets), $name, $cmd, @args) unless @match == 1;
return "$cmd expects $sets{$match[0]} parameters" unless (@args eq $sets{$match[0]}); return "$cmd expects $sets{$match[0]} parameters" unless (@args eq $sets{$match[0]});
return "\"set $name\" needs at least one argument" unless(defined($cmd)); return "\"set $name\" needs at least one argument" unless(defined($cmd));
if (!defined $hash->{READINGS}{pct}) { if (!defined $hash->{READINGS}{pct}) {
$MIpct = $hash->{READINGS}{pct}{VAL}; $MIpct = $hash->{READINGS}{pct}{VAL};
} }
else { else {
$MIpct = 64; $MIpct = 64;
} }
if($cmd eq "password") if($cmd eq "password")
{ {
#if($args[0] =~ /^[a-zA-Z0-9_.-]*$/) #if($args[0] =~ /^[a-zA-Z0-9_.-]*$/)
@@ -601,7 +619,7 @@ sub XiaomiSmartHome_Set($@)
else else
{ {
return "Unknown value $args[0] for $cmd, wrong password, it must be hex and 16 characters"; return "Unknown value $args[0] for $cmd, wrong password, it must be hex and 16 characters";
} }
} }
if ( $hash->{READINGS}{password}{VAL} !~ /^[a-zA-Z0-9]{16}$/) if ( $hash->{READINGS}{password}{VAL} !~ /^[a-zA-Z0-9]{16}$/)
{ {
@@ -612,7 +630,7 @@ sub XiaomiSmartHome_Set($@)
elsif($cmd eq "rgb") elsif($cmd eq "rgb")
{ {
my $ownName = $hash->{NAME}; my $ownName = $hash->{NAME};
Log3 $ownName, 4, "$ownName: Set> $cmd, $args[0]"; Log3 $ownName, 4, "$ownName: Set> $cmd, $args[0]";
$dec_num = sprintf("%d", hex($MIpct . $args[0])); $dec_num = sprintf("%d", hex($MIpct . $args[0]));
Log3 $ownName, 4, "$ownName: Set> $cmd, $dec_num"; Log3 $ownName, 4, "$ownName: Set> $cmd, $dec_num";
@@ -638,7 +656,7 @@ sub XiaomiSmartHome_Set($@)
readingsBulkUpdate( $hash, 'rgb', $hash->{helper}{prevrgbvalue}, 1 ); readingsBulkUpdate( $hash, 'rgb', $hash->{helper}{prevrgbvalue}, 1 );
XiaomiSmartHome_Write($hash,'rgb', $dec_num); XiaomiSmartHome_Write($hash,'rgb', $dec_num);
} }
else else
{ {
readingsBulkUpdate( $hash, 'rgb', "00ff00", 1 ); readingsBulkUpdate( $hash, 'rgb', "00ff00", 1 );
XiaomiSmartHome_Write($hash,'rgb', 1677786880); XiaomiSmartHome_Write($hash,'rgb', 1677786880);
@@ -692,7 +710,7 @@ sub XiaomiSmartHome_Set($@)
sub XiaomiSmartHome_Attr(@) { sub XiaomiSmartHome_Attr(@) {
my ($cmd,$NAME,$name, $val) = @_; my ($cmd,$NAME,$name, $val) = @_;
if ($cmd eq "delete"){ if ($cmd eq "delete"){
delete $attr{$NAME}{$name}; delete $attr{$NAME}{$name};
CommandDeleteAttr(undef, "$NAME $name"); CommandDeleteAttr(undef, "$NAME $name");
Log3 $name, 1, "$name: Attr> delete $name"; Log3 $name, 1, "$name: Attr> delete $name";
} }
@@ -710,21 +728,19 @@ sub XiaomiSmartHome_connect($)
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $GATEWAY_IP; my $GATEWAY_IP;
Log3 $name, 5, "$name: connect> ConnectStart"; Log3 $name, 5, "$name: connect> ConnectStart";
Log3 $name, 4, "$name: connecting";
my $p = Net::Ping->new(); my $p = Net::Ping->new();
if ( ! $p->ping($hash->{GATEWAY})){ if ( ! $p->ping($hash->{GATEWAY})){
Log3 $name, 1, "$name: connect> Ping to $hash->{helper}{host} failed"; Log3 $name, 1, "$name: connect> Ping to $hash->{helper}{host} failed";
$hash->{STATE} = "Disconnected"; $hash->{STATE} = "Disconnected";
XiaomiSmartHome_disconnect($hash); XiaomiSmartHome_disconnect($hash);
$p->close(); $p->close();
return undef; return undef;
} }
if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){
eval { eval {
$GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ; $GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ;
$hash->{GATEWAY_IP} = $GATEWAY_IP; $hash->{GATEWAY_IP} = $GATEWAY_IP;
Log3 $name, 4, "$name: Connect> Set GATEWAYs IP: " . $GATEWAY_IP; Log3 $name, 5, "$name: Connect> Set GATEWAYs IP: " . $GATEWAY_IP;
}; };
if ($@) { if ($@) {
Log3 $name, 1, "$name: Connect> Error $@\n"; Log3 $name, 1, "$name: Connect> Error $@\n";
@@ -735,12 +751,12 @@ sub XiaomiSmartHome_connect($)
} }
XiaomiSmartHome_getGatewaySID($hash); XiaomiSmartHome_getGatewaySID($hash);
my $timeout = $hash->{TIMEOUT} ? $hash->{TIMEOUT} : 3; my $timeout = $hash->{TIMEOUT} ? $hash->{TIMEOUT} : 3;
my $sock = IO::Socket::Multicast->new( Proto => 'udp', LocalPort =>'9898', ReuseAddr => 1, Timeout => $timeout) or die "Creating socket: $!\n"; my $sock = IO::Socket::Multicast->new( Proto => 'udp', LocalPort =>'9898', ReusePort => 1, ReuseAddr => 1, Timeout => $timeout) or die "Creating socket: $!\n";
$sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 30, 0)) or die "setsockopt: $!"; $sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 30, 0)) or die "setsockopt: $!";
if ($sock) if ($sock)
{ {
Log3 $name, 4, "$name: connect> Connected"; Log3 $name, 3, "$name: connect> Connected";
$sock->mcast_add('224.0.0.50', $hash->{fhemIP} ) || die "Couldn't set group: $!\n"; #$hash->{fhemIP} $sock->mcast_add('224.0.0.50', $hash->{FHEMIP} ) || die "Couldn't set group: $!\n"; #$hash->{FHEMIP}
$sock->mcast_ttl(32); $sock->mcast_ttl(32);
$sock->mcast_loopback(1); $sock->mcast_loopback(1);
$hash->{helper}{ConnectionState} = "Connected"; $hash->{helper}{ConnectionState} = "Connected";
@@ -778,12 +794,12 @@ sub XiaomiSmartHome_disconnect($)
return if (!$hash->{CD}); return if (!$hash->{CD});
Log3 $name, 1, "$name: disconnect> disconnecting"; Log3 $name, 1, "$name: disconnect> disconnecting";
close($hash->{CD}) if($hash->{CD}); close($hash->{CD}) if($hash->{CD});
delete($hash->{FD}); delete($hash->{FD});
delete($hash->{CD}); delete($hash->{CD});
delete($selectlist{$name}); delete($selectlist{$name});
return undef; return undef;
} }
@@ -796,10 +812,10 @@ sub XiaomiSmartHome_updateSingleReading($$)
my $GATEWAY = $hash->{GATEWAY}; my $GATEWAY = $hash->{GATEWAY};
my $sock = $hash->{CD}; my $sock = $hash->{CD};
my $MAXLEN = 1024; my $MAXLEN = 1024;
Log3 $name, 4, "$name: updateSingleReading> PushSingelRead:" . $sensor; Log3 $name, 4, "$name: updateSingleReading> PushSingelRead:" . $sensor;
XiaomiSmartHome_Write($hash, 'read', $sensor); XiaomiSmartHome_Write($hash, 'read', $sensor);
} }
##################################### #####################################
@@ -811,10 +827,10 @@ sub XiaomiSmartHome_updateAllReadings($)
my $GATEWAY; my $GATEWAY;
my $p = Net::Ping->new(); my $p = Net::Ping->new();
if ( ! $p->ping($hash->{GATEWAY})){ if ( ! $p->ping($hash->{GATEWAY})){
Log3 $name, 4, "$name: updateAllReadings> Ping to $hash->{helper}{host} failed"; Log3 $name, 1, "$name: updateAllReadings> Ping to $hash->{helper}{host} failed";
$hash->{STATE} = "Disconnected"; $hash->{STATE} = "Disconnected";
XiaomiSmartHome_disconnect($hash); XiaomiSmartHome_disconnect($hash);
$p->close(); $p->close();
return undef; return undef;
} }
if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){
@@ -834,13 +850,13 @@ sub XiaomiSmartHome_updateAllReadings($)
$GATEWAY = $hash->{GATEWAY}; $GATEWAY = $hash->{GATEWAY};
} }
if ( $hash->{helper}{ConnectionState} eq 'Disconnected') if ( $hash->{helper}{ConnectionState} eq 'Disconnected')
{ {
Log3 $name, 1, "$name: updateAllReadings> Gateway is $hash->{STATE} trying to reconnect to $hash->{GATEWAY}"; Log3 $name, 1, "$name: updateAllReadings> Gateway is $hash->{STATE} trying to reconnect to $hash->{GATEWAY}";
XiaomiSmartHome_connect($hash); XiaomiSmartHome_connect($hash);
return undef; return undef;
} }
XiaomiSmartHome_Write($hash, 'get_id_list'); XiaomiSmartHome_Write($hash, 'get_id_list');
} }
@@ -858,7 +874,7 @@ sub XiaomiSmartHome_updateAllReadings($)
<a name="XiaomiSmartHome"></a> <a name="XiaomiSmartHome"></a>
<h3>XiaomiSmartHome</h3> <h3>XiaomiSmartHome</h3>
<ul> <ul>
<i>XiaomiSmartHome</i> implements the XiaomiSmartHome Gateway and Sensors. <i>XiaomiSmartHome</i> implements the XiaomiSmartHome Gateway and Sensors.
<a name="XiaomiSmartHome"></a> <a name="XiaomiSmartHome"></a>
<br/> <br/>
<b>Prerequisite</b> <b>Prerequisite</b>
@@ -960,7 +976,7 @@ sub XiaomiSmartHome_updateAllReadings($)
<a name="XiaomiSmartHome"></a> <a name="XiaomiSmartHome"></a>
<h3>XiaomiSmartHome</h3> <h3>XiaomiSmartHome</h3>
<ul> <ul>
<i>XiaomiSmartHome</i> Steuern des XiaomiSmartHome Gateway und deren verbundener Sensoren. <i>XiaomiSmartHome</i> Steuern des XiaomiSmartHome Gateway und deren verbundener Sensoren.
<a name="XiaomiSmartHome"></a> <a name="XiaomiSmartHome"></a>
<br/> <br/>
<b>Vorraussetzungen</b> <b>Vorraussetzungen</b>
@@ -980,7 +996,7 @@ sub XiaomiSmartHome_updateAllReadings($)
<b>Entwicklermodus am Gatway setzen!</b> <b>Entwicklermodus am Gatway setzen!</b>
<ul> <ul>
<p>Ohne Entwicklermodus ist keine Komunikation mit dem Gateway m&oumlglich. <p>Ohne Entwicklermodus ist keine Komunikation mit dem Gateway m&oumlglich.
<br/>Zum setzen des Entwicklermoduses braucht man ein android oder ios Ger&aumlt mit installierter MI APP. <br/>Zum setzen des Entwicklermoduses braucht man ein android oder ios Ger&aumlt mit installierter MI APP.
<br/>Um das versteckte Men&uuml zu &oumlffnen muss man mehrmals auf die Versionsnummer der MI APP klicken. <br/>Um das versteckte Men&uuml zu &oumlffnen muss man mehrmals auf die Versionsnummer der MI APP klicken.
<br/>Hier finden Sie eine Anleitung mit Bildern. <br/>Hier finden Sie eine Anleitung mit Bildern.
<br/>Android -> https://louiszl.gitbooks.io/lumi-gateway-local-api/content/device_discover.html <br/>Android -> https://louiszl.gitbooks.io/lumi-gateway-local-api/content/device_discover.html
@@ -1058,6 +1074,3 @@ sub XiaomiSmartHome_updateAllReadings($)
=cut =cut

View File

@@ -27,7 +27,7 @@ use warnings;
my $version = "1.21"; my $version = "1.30";
sub XiaomiSmartHome_Device_updateSReading($); sub XiaomiSmartHome_Device_updateSReading($);
@@ -37,8 +37,8 @@ sub XiaomiSmartHome_Device_updateSReading($);
sub XiaomiSmartHome_Device_Initialize($) sub XiaomiSmartHome_Device_Initialize($)
{ {
my ($hash) = @_; my ($hash) = @_;
$hash->{Match} = ".*magnet.*|.*motion.*|sensor_ht|.*switch.*|plug|cube|86sw1|86sw2|ctrl_neutral1|ctrl_neutral2|rgbw_light|curtain|ctrl_ln1|ctrl_ln2|86plug|natgas|smoke|weather.v1|sensor_wleak.aq1"; $hash->{Match} = ".*magnet.*|.*motion.*|sensor_ht|.*switch.*|plug|.*cube.*|86sw1|86sw2|ctrl_neutral1|ctrl_neutral2|rgbw_light|curtain|ctrl_ln1|ctrl_ln2|86plug|natgas|smoke|weather.v1|sensor_wleak.aq1";
$hash->{DefFn} = "XiaomiSmartHome_Device_Define"; $hash->{DefFn} = "XiaomiSmartHome_Device_Define";
$hash->{SetFn} = "XiaomiSmartHome_Device_Set"; $hash->{SetFn} = "XiaomiSmartHome_Device_Set";
$hash->{UndefFn} = "XiaomiSmartHome_Device_Undef"; $hash->{UndefFn} = "XiaomiSmartHome_Device_Undef";
@@ -50,7 +50,7 @@ sub XiaomiSmartHome_Device_Initialize($)
"rnd_hum:0,1,2,3 ". "rnd_hum:0,1,2,3 ".
"rnd_bat:0,1,2,3 ". "rnd_bat:0,1,2,3 ".
"rnd_pres:0,1,2,3 ". "rnd_pres:0,1,2,3 ".
$readingFnAttributes ; $readingFnAttributes ;
} }
##################################### #####################################
@@ -68,7 +68,7 @@ sub XiaomiSmartHome_Device_Set($@)
my ( $hash, $name, $cmd, @args ) = @_; my ( $hash, $name, $cmd, @args ) = @_;
return "\"set $name\" needs at least one argument" unless(defined($cmd)); return "\"set $name\" needs at least one argument" unless(defined($cmd));
my $setlist = ""; my $setlist = "";
$setlist .= "motionOffTimer:1,5,10 " if ($hash->{MODEL} =~ /motion/); $setlist .= "motionOffTimer:1,5,10 " if ($hash->{MODEL} =~ /motion/);
#$setlist = "open:noArg close:noArg " if ($hash->{MODEL} =~ /magnet/); #$setlist = "open:noArg close:noArg " if ($hash->{MODEL} =~ /magnet/);
@@ -79,7 +79,7 @@ sub XiaomiSmartHome_Device_Set($@)
$setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_neutral2'); $setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_neutral2');
$setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_ln2'); $setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_ln2');
$setlist .= "status:open,close,stop,auto level:slider,1,1,100 " if ($hash->{MODEL} eq 'curtain'); $setlist .= "status:open,close,stop,auto level:slider,1,1,100 " if ($hash->{MODEL} eq 'curtain');
if($cmd eq "power") if($cmd eq "power")
{ {
if($args[0] eq "on") if($args[0] eq "on")
@@ -151,22 +151,22 @@ sub XiaomiSmartHome_Device_Set($@)
{ {
IOWrite($hash,"status","close",$hash) ; IOWrite($hash,"status","close",$hash) ;
return; return;
} }
elsif($args[0] eq "stop") elsif($args[0] eq "stop")
{ {
IOWrite($hash,"status","stop",$hash) ; IOWrite($hash,"status","stop",$hash) ;
return; return;
} }
elsif($args[0] eq "auto") elsif($args[0] eq "auto")
{ {
IOWrite($hash,"status","auto",$hash) ; IOWrite($hash,"status","auto",$hash) ;
return; return;
} }
} }
if($cmd eq "level") if($cmd eq "level")
{ {
IOWrite($hash,"level", $args[0] ,$hash) ; IOWrite($hash,"level", $args[0] ,$hash) ;
return; return;
} }
# if($cmd eq "open") # if($cmd eq "open")
# { # {
@@ -178,7 +178,7 @@ sub XiaomiSmartHome_Device_Set($@)
readingsSingleUpdate($hash, "motionOffTimer", "$args[0]", 1 );; readingsSingleUpdate($hash, "motionOffTimer", "$args[0]", 1 );;
return; return;
} }
return "Unknown argument $cmd, choose one of $setlist"; return "Unknown argument $cmd, choose one of $setlist";
} }
@@ -200,7 +200,7 @@ sub XiaomiSmartHome_Device_Read($$$){
my $XMIround_tmp = AttrVal( $hash->{NAME}, "rnd_tmp", "2" ); my $XMIround_tmp = AttrVal( $hash->{NAME}, "rnd_tmp", "2" );
my $XMIround_hum = AttrVal( $hash->{NAME}, "rnd_hum", "2" ); my $XMIround_hum = AttrVal( $hash->{NAME}, "rnd_hum", "2" );
my $XMIround_bat = AttrVal( $hash->{NAME}, "rnd_bat", "1" ); my $XMIround_bat = AttrVal( $hash->{NAME}, "rnd_bat", "1" );
my $XMIround_pres = AttrVal( $hash->{NAME}, "rnd_pres", "2" ); my $XMIround_pres = AttrVal( $hash->{NAME}, "rnd_pres", "2" );
my $decoded = eval{decode_json($msg)}; my $decoded = eval{decode_json($msg)};
@@ -223,7 +223,7 @@ sub XiaomiSmartHome_Device_Read($$$){
readingsBulkUpdate($hash, "state", "$data->{status}", 1 ); readingsBulkUpdate($hash, "state", "$data->{status}", 1 );
if ($data->{status} eq 'motion' && $hash->{MODEL} =~ /motion/){ if ($data->{status} eq 'motion' && $hash->{MODEL} =~ /motion/){
readingsBulkUpdate($hash, "no_motion", "0", 1 ); readingsBulkUpdate($hash, "no_motion", "0", 1 );
} }
if ($data->{status} eq 'close' && $hash->{MODEL} =~ /magnet/){ if ($data->{status} eq 'close' && $hash->{MODEL} =~ /magnet/){
readingsBulkUpdate($hash, "no_close", "0", 1 ); readingsBulkUpdate($hash, "no_close", "0", 1 );
} }
@@ -241,13 +241,13 @@ sub XiaomiSmartHome_Device_Read($$$){
my $bat = ($data->{voltage}/1000); my $bat = ($data->{voltage}/1000);
Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " Voltage: " . $data->{voltage}; Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " Voltage: " . $data->{voltage};
if ($bat < 2.2) { if ($bat < 2.2) {
readingsBulkUpdate($hash, "battery", "low", 1 ); readingsBulkUpdate($hash, "batteryState", "low", 1 );
} }
else { else {
readingsBulkUpdate($hash, "battery", "ok", 1 ) readingsBulkUpdate($hash, "batteryState", "ok", 1 )
} }
$bat = XiaomiSmartHome_round($bat, $XMIround_bat, $name ); $bat = XiaomiSmartHome_round($bat, $XMIround_bat, $name );
readingsBulkUpdate($hash, "batteryLevel", $bat, 1 ); readingsBulkUpdate($hash, "batteryVoltage", $bat, 1 );
} }
if (defined $data->{temperature}){ if (defined $data->{temperature}){
if ($data->{temperature} ne "10000"){ if ($data->{temperature} ne "10000"){
@@ -345,7 +345,7 @@ sub XiaomiSmartHome_Device_Read($$$){
readingsBulkUpdate($hash, "rotate", "$data->{rotate}", 1 ); readingsBulkUpdate($hash, "rotate", "$data->{rotate}", 1 );
readingsBulkUpdate($hash, "state", "rotate", 1 ); readingsBulkUpdate($hash, "state", "rotate", 1 );
} }
#cube end #cube end
#smoke & natgast start #smoke & natgast start
if (defined $data->{alarm}){ if (defined $data->{alarm}){
Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " Alarm: " . $data->{alarm}; Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " Alarm: " . $data->{alarm};
@@ -384,15 +384,17 @@ sub XiaomiSmartHome_Device_Parse($$) {
} }
my $sid = $decoded->{'sid'}; my $sid = $decoded->{'sid'};
my $model = $decoded->{'model'}; my $model = $decoded->{'model'};
if (my $hash = $modules{XiaomiSmartHome_Device}{defptr}{$sid}) if ($modules{XiaomiSmartHome_Device}{defptr}{$sid}{IODev}->{NAME})
{ {
Log3 $name, 4, "$name: DEV_Parse> IS DEFINED " . $model . " : " .$sid; my $hash = $modules{XiaomiSmartHome_Device}{defptr}{$sid}->{IODev};
Log3 $name, 5, "$name: DEV_Parse> IS DEFINED " . $model . " : " . $sid . " " . $modules{XiaomiSmartHome_Device}{defptr}{$sid}->{IODev};
$hash = $modules{XiaomiSmartHome_Device}{defptr}{$sid};
XiaomiSmartHome_Device_Read($hash, $msg, $name); XiaomiSmartHome_Device_Read($hash, $msg, $name);
} }
else else
{ {
Log3 $name, 4, "$name: DEV_Parse> UNDEFINED " . $model . " : " .$sid; Log3 $name, 1, "$name: DEV_Parse> UNDEFINED " . $model . " : " .$sid;
return "UNDEFINED XMI_$sid XiaomiSmartHome_Device $sid $model $name"; return "UNDEFINED XMI_$sid XiaomiSmartHome_Device $sid $model $name";
} }
} }
@@ -421,9 +423,11 @@ sub XiaomiSmartHome_Device_update($){
CommandDeleteReading( undef, "$name batterystate" ) if(defined(ReadingsVal($name,"batterystate",undef))); CommandDeleteReading( undef, "$name batterystate" ) if(defined(ReadingsVal($name,"batterystate",undef)));
CommandDeleteReading( undef, "$name round" ) if(defined(ReadingsVal($name,"round",undef))); CommandDeleteReading( undef, "$name round" ) if(defined(ReadingsVal($name,"round",undef)));
CommandDeleteReading( undef, "$name battery_level" ) if(defined(ReadingsVal($name,"battery_level",undef))); CommandDeleteReading( undef, "$name battery_level" ) if(defined(ReadingsVal($name,"battery_level",undef)));
CommandDeleteReading( undef, "$name battery" ) if(defined(ReadingsVal($name,"battery",undef)));
CommandDeleteReading( undef, "$name batteryLevel" ) if(defined(ReadingsVal($name,"batteryLevel",undef)));
} }
##################################### #####################################
sub XiaomiSmartHome_Device_Define($$) { sub XiaomiSmartHome_Device_Define($$) {
my ($hash, $def) = @_; my ($hash, $def) = @_;
@@ -437,7 +441,7 @@ sub XiaomiSmartHome_Device_Define($$) {
$modules{XiaomiSmartHome_Device}{defptr}{$sid} = $hash; $modules{XiaomiSmartHome_Device}{defptr}{$sid} = $hash;
AssignIoPort($hash,$iodev); AssignIoPort($hash,$iodev);
my $room = $attr{$iodev}{room}; my $room = $attr{$iodev}{room};
if(defined($hash->{IODev}->{NAME})) { if(defined($hash->{IODev}->{NAME})) {
my $IOname = $hash->{IODev}->{NAME}; my $IOname = $hash->{IODev}->{NAME};
Log3 $name, 4, $IOname . ": DEV_Define> " .$name. ": " . $type . " I/O device is " . $hash->{IODev}->{NAME}; Log3 $name, 4, $IOname . ": DEV_Define> " .$name. ": " . $type . " I/O device is " . $hash->{IODev}->{NAME};
@@ -445,15 +449,17 @@ sub XiaomiSmartHome_Device_Define($$) {
Log3 $name, 1, "$name DEV_Define> $type - no I/O device"; Log3 $name, 1, "$name DEV_Define> $type - no I/O device";
} }
$iodev = $hash->{IODev}->{NAME}; $iodev = $hash->{IODev}->{NAME};
my $d = $modules{XiaomiSmartHome_Device}{defptr}{$name}; my $d = $modules{XiaomiSmartHome_Device}{defptr}{$sid};
return "XiaomiSmartHome device $hash->{SID} on XiaomiSmartHome $iodev already defined as $d->{NAME}." if( defined($d) && $d->{IODev} == $hash->{IODev} && $d->{NAME} ne $name ); return "XiaomiSmartHome device $hash->{SID} on XiaomiSmartHome $iodev already defined as $d->{SID}." if( defined($d) && $d->{IODev} == $hash->{IODev} && $d->{SID} ne $sid );
Log3 $name, 4, $iodev . ": DEV_Define> " . $name . ": defined as ". $hash->{MODEL}; Log3 $name, 4, $iodev . ": DEV_Define> " . $name . ": defined as ". $hash->{MODEL};
$attr{$name}{room} = $room if( !defined( $attr{$name}{room} ) ); $attr{$name}{room} = $room if( !defined( $attr{$name}{room} ) );
if( $type =~ /motion/) { if( $type =~ /motion/) {
readingsSingleUpdate($hash, "state", "motion", 1 ) if( !defined( $attr{$name}{devStateIcon} ));
$attr{$name}{devStateIcon} = 'motion:motion_detector@red off:motion_detector@green no_motion:motion_detector@green' if( !defined( $attr{$name}{devStateIcon} ) ); $attr{$name}{devStateIcon} = 'motion:motion_detector@red off:motion_detector@green no_motion:motion_detector@green' if( !defined( $attr{$name}{devStateIcon} ) );
} }
elsif ( $type =~ /magnet/) { elsif ( $type =~ /magnet/) {
$attr{$name}{devStateIcon} = 'open:fts_door_open@red close:fts_door@green' if( !defined( $attr{$name}{devStateIcon} ) ); $attr{$name}{devStateIcon} = 'open:fts_door_open@red close:fts_door@green' if( !defined( $attr{$name}{devStateIcon} ) );
@@ -463,8 +469,8 @@ sub XiaomiSmartHome_Device_Define($$) {
} }
elsif ( $type eq 'weather.v1') { elsif ( $type eq 'weather.v1') {
$attr{$name}{stateFormat} = 'temperature °C, humidity %, pressure kPa' if( !defined( $attr{$name}{stateFormat} ) ); $attr{$name}{stateFormat} = 'temperature °C, humidity %, pressure kPa' if( !defined( $attr{$name}{stateFormat} ) );
} }
if( $init_done ) { if( $init_done ) {
InternalTimer(gettimeofday() + 2, "XiaomiSmartHome_Device_updateSReading", $hash, 0 ); InternalTimer(gettimeofday() + 2, "XiaomiSmartHome_Device_updateSReading", $hash, 0 );
Log3 $name, 4, $iodev . ": DEV_Define> " . $name . " Init Done set InternalTimer for Update"; Log3 $name, 4, $iodev . ": DEV_Define> " . $name . " Init Done set InternalTimer for Update";
@@ -485,12 +491,14 @@ sub XiaomiSmartHome_Device_updateSReading($) {
##################################### #####################################
sub XiaomiSmartHome_Device_Undef($) sub XiaomiSmartHome_Device_Undef($)
{ {
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $iodev = $hash->{IODev}->{NAME}; my $iodev = $hash->{IODev}->{NAME};
my $sid = $hash->{SID};
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
delete($modules{XiaomiSmartHome_Device}{defptr}{$hash->{SID}}); Log3 $name, 1, "$iodev: DEV_Undef> ". $hash->{SID} . " > " . $modules{XiaomiSmartHome_Device}{defptr}{$hash->{SID}} . " > " . $sid ." > " . $modules{XiaomiSmartHome_Device}{defptr}{$sid};
Log3 $name, 4, "$iodev: DEV_Undef> $name - device deleted"; my $error = delete ($modules{XiaomiSmartHome_Device}{defptr}{$sid});
Log3 $name, 1, "$iodev: DEV_Undef> $name - device deleted " . $error;
return undef; return undef;
} }
@@ -504,8 +512,9 @@ sub XiaomiSmartHome_round {
$p ||= 0; $p ||= 0;
$n *= 10 ** $p; $n *= 10 ** $p;
$n = int($n + .5 * $sign); $n = int($n + .5 * $sign);
Log3 $name, 5, "$name: DEV_Round>" . " Result_value: " . $n / 10**$p; my $res = sprintf( "%." . $p . "f", $n / 10**$p);
return $n / 10**$p; Log3 $name, 5, "$name: DEV_Round>" . " Result_value: " . $res;
return $res;
} }
@@ -522,7 +531,7 @@ sub XiaomiSmartHome_round {
<a name="XiaomiSmartHome_Device"></a> <a name="XiaomiSmartHome_Device"></a>
<h3>XiaomiSmartHome</h3> <h3>XiaomiSmartHome</h3>
<ul> <ul>
<i>XiaomiSmartHome</i> implements the XiaomiSmartHome Gateway and Sensors. <i>XiaomiSmartHome</i> implements the XiaomiSmartHome Gateway and Sensors.
<a name="XiaomiSmartHome"></a> <a name="XiaomiSmartHome"></a>
<br/> <br/>
<b>Prerequisite</b> <b>Prerequisite</b>
@@ -624,7 +633,7 @@ sub XiaomiSmartHome_round {
<a name="XiaomiSmartHome_Device"></a> <a name="XiaomiSmartHome_Device"></a>
<h3>XiaomiSmartHome</h3> <h3>XiaomiSmartHome</h3>
<ul> <ul>
<i>XiaomiSmartHome</i> Steuern des XiaomiSmartHome Gateway und deren verbundener Sensoren. <i>XiaomiSmartHome</i> Steuern des XiaomiSmartHome Gateway und deren verbundener Sensoren.
<a name="XiaomiSmartHome"></a> <a name="XiaomiSmartHome"></a>
<br/> <br/>
<b>Vorraussetzungen</b> <b>Vorraussetzungen</b>
@@ -644,7 +653,7 @@ sub XiaomiSmartHome_round {
<b>Entwicklermodus am Gatway setzen!</b> <b>Entwicklermodus am Gatway setzen!</b>
<ul> <ul>
<p>Ohne Entwicklermodus ist keine Komunikation mit dem Gateway m&oumlglich. <p>Ohne Entwicklermodus ist keine Komunikation mit dem Gateway m&oumlglich.
<br/>Zum setzen des Entwicklermoduses braucht man ein android oder ios Ger&aumlt mit installierter MI APP. <br/>Zum setzen des Entwicklermoduses braucht man ein android oder ios Ger&aumlt mit installierter MI APP.
<br/>Um das versteckte Men&uuml zu &oumlffnen muss man mehrmals auf die Versionsnummer der MI APP klicken. <br/>Um das versteckte Men&uuml zu &oumlffnen muss man mehrmals auf die Versionsnummer der MI APP klicken.
<br/>Hier finden Sie eine Anleitung mit Bildern. <br/>Hier finden Sie eine Anleitung mit Bildern.
<br/>Android -> https://louiszl.gitbooks.io/lumi-gateway-local-api/content/device_discover.html <br/>Android -> https://louiszl.gitbooks.io/lumi-gateway-local-api/content/device_discover.html
@@ -720,4 +729,4 @@ sub XiaomiSmartHome_round {
=end html_DE =end html_DE
=cut =cut

View File

@@ -1,2 +1,2 @@
UPD 2017-12-18_13:56:43 37688 FHEM/71_XiaomiSmartHome.pm UPD 2018-06-22_13:29:31 38872 FHEM/71_XiaomiSmartHome.pm
UPD 2017-12-18_10:00:55 28395 FHEM/71_XiaomiSmartHome_Device.pm UPD 2018-06-22_12:45:46 29142 FHEM/71_XiaomiSmartHome_Device.pm