diff --git a/FHEM/71_XiaomiSmartHome.pm b/FHEM/71_XiaomiSmartHome.pm index d6e96b1..b8d2b13 100644 --- a/FHEM/71_XiaomiSmartHome.pm +++ b/FHEM/71_XiaomiSmartHome.pm @@ -42,7 +42,6 @@ eval "use Net::Ping"; return "\nERROR: Please install Net::Ping" if($@); - use Color; use SetExtensions; @@ -52,7 +51,7 @@ sub XiaomiSmartHome_Notify($$); sub XiaomiSmartHome_updateSingleReading($$); 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 = ( "getDevices" => ["get_id_list", '^.+get_id_list_ack' ], @@ -76,7 +75,7 @@ my %sets = ( sub XiaomiSmartHome_Initialize($) { my ($hash) = @_; - + $hash->{Clients} = "XiaomiSmartHome_Device"; $hash->{DefFn} = 'XiaomiSmartHome_Define'; $hash->{UndefFn} = 'XiaomiSmartHome_Undef'; @@ -88,12 +87,12 @@ sub XiaomiSmartHome_Initialize($) { $hash->{WriteFn} = "XiaomiSmartHome_Write"; $hash->{AttrList} = "disable:1,0 " . $readingFnAttributes; - + $hash->{MatchList} = { "1:XiaomiSmartHome_Device" => ".*magnet.*", "2:XiaomiSmartHome_Device" => ".*motion.*", "3:XiaomiSmartHome_Device" => "^.+sensor_ht", "4:XiaomiSmartHome_Device" => ".*switch.*", - "5:XiaomiSmartHome_Device" => "^.+cube", + "5:XiaomiSmartHome_Device" => ".*cube.*", "6:XiaomiSmartHome_Device" => "^.+plug", "7:XiaomiSmartHome_Device" => "^.+86sw1", "8:XiaomiSmartHome_Device" => "^.+86sw2", @@ -108,7 +107,7 @@ sub XiaomiSmartHome_Initialize($) { "17:XiaomiSmartHome_Device" => "^.+smoke", "18:XiaomiSmartHome_Device" => "^.+weather.v1", "19:XiaomiSmartHome_Device" => "^.+sensor_motion.aq2", - "20:XiaomiSmartHome_Device" => "^.+sensor_wleak.aq1"}; + "20:XiaomiSmartHome_Device" => "^.+sensor_wleak.aq1"}; FHEM_colorpickerInit(); } ##################################### @@ -116,7 +115,7 @@ sub XiaomiSmartHome_Read($) { my ($hash) = @_; my $name = $hash->{NAME}; my $self = {}; # my new hash - + Log3 $name, 5, "$name: Read> Read start"; if ( ! $hash->{SID} ){ Log3 $name, 3, "$name: Read> No SID, Stop Read"; @@ -143,20 +142,37 @@ sub XiaomiSmartHome_Read($) { } if ($json) { - Log3 $name, 5, "$name: Read> " . $buf; + Log3 $name, 5, "$name: Read> [PLAIN] " . $buf; 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 ( $modules{XiaomiSmartHome_Device}{defptr}{$rsid}->{SID} = $rsid ){ - Log3 $name, 5, "$name: Read> Dispatch " . $buf; - my $devhash = $modules{XiaomiSmartHome_Device}{defptr}{$rsid}->{IODev}; - Dispatch($devhash, $buf, undef); + if (!$modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME}){ + Log3 $name, 5, "$name: Read> XiaomiSmartHome_Device unknown trying autocreate" ; + my $def=$modules{XiaomiSmartHome}{defptr}; + 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 { - Log3 $name, 5, "$name: Read> Dispatch " . $buf; - Dispatch($hash, $buf, undef); - + if ($modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} eq $hash->{NAME}) { + Log3 $name, 5, "$name: Read> XiaomiSmartHome_Device known! " . "SID: " . $rsid . " " . $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} . " " . $hash->{NAME}; + } + 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} ){ $self = $modules{XiaomiSmartHome}{defptr}{$rsid}; Log3 $name, 5, "$name: Read> Change HASH Ref to $self->{NAME}"; @@ -216,7 +232,7 @@ sub XiaomiSmartHome_Reading ($@) { #$hash->{SID} = $decoded->{'sid'}; } 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; } if ($data->{error}){ - readingsBulkUpdate($hash, 'heartbeat', $data->{error}, 1 ); + readingsBulkUpdate($hash, 'heartbeat', $data->{error}, 1 ); } else { - readingsBulkUpdate($hash, 'heartbeat', "Write_OK", 1 ); + readingsBulkUpdate($hash, 'heartbeat', "Write_OK", 1 ); readingsBulkUpdate($hash, "proto_version", $data->{proto_version} , 1 ); } } @@ -253,7 +269,7 @@ sub XiaomiSmartHome_Reading ($@) { return; } my $all_sensors = ""; - foreach my $sensor (@sensors) + foreach my $sensor (@sensors) { Log3 $name, 4, "$name: Reading> PushRead:" . $sensor; XiaomiSmartHome_Write($hash, 'read', $sensor ); @@ -306,16 +322,16 @@ sub XiaomiSmartHome_getGatewaySID($){ } if ($json) { 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(); $hash->{SID} = $decoded->{sid}; $modules{XiaomiSmartHome}{defptr}{$decoded->{sid}} = $hash; return $decoded->{sid}; } 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 ($@) { Log3 $name, 1, "$name: getGatewaySID> Error no response from whois!! STOP!!"; @@ -346,8 +362,8 @@ sub XiaomiSmartHome_Define($$) { if ( ! $p->ping($param[2])){ $hash->{STATE} = "Disconnected"; XiaomiSmartHome_disconnect($hash); - Log3 $name, 5, "$name: Define> Ping ERROR Gateway disconnecting"; - $p->close(); + Log3 $name, 1, "$name: Define> Ping ERROR Gateway disconnecting"; + $p->close(); } my $GATEWAY_IP = $param[2]; my $definition = $param[2]; @@ -359,7 +375,7 @@ sub XiaomiSmartHome_Define($$) { $hash->{helper}{JSON} = JSON->new->utf8(); $hash->{FHEMIP} = XiaomiSmartHome_getLocalIP(); $hash->{STATE} = "initialized"; - $hash->{helper}{host} = $definition; + $hash->{helper}{host} = $definition; if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ eval { $GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ; @@ -374,24 +390,24 @@ sub XiaomiSmartHome_Define($$) { } } $hash->{GATEWAY_IP} = $GATEWAY_IP; - $modules{XiaomiSmartHome}{defptr}{$GATEWAY_IP} = $hash; + #$modules{XiaomiSmartHome}{defptr}{$GATEWAY_IP} = $hash; #$hash->{SID} = XiaomiSmartHome_getGatewaySID($hash); - + Log3 $name, 5, "$name: Define> $definition"; # Define 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} ) ); - - InternalTimer(gettimeofday() + 5, "XiaomiSmartHome_connect", $hash, 0); - + + InternalTimer(gettimeofday() + 5, "XiaomiSmartHome_connect", $hash, 0); + return undef; } ##################################### sub XiaomiSmartHome_Undef($$) { - my ($hash, $arg) = @_; - + my ($hash, $arg) = @_; + XiaomiSmartHome_disconnect($hash); # nothing to do return undef; @@ -402,7 +418,7 @@ sub XiaomiSmartHome_Write($@) { my ($hash,$cmd,$val,$iohash) = @_; 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"; return undef; } @@ -413,7 +429,7 @@ sub XiaomiSmartHome_Write($@) Log3 $name, 1, "$name: Write> Ping to $hash->{helper}{host} failed"; $hash->{STATE} = "Disconnected"; XiaomiSmartHome_disconnect($hash); - $p->close(); + $p->close(); return undef; } } @@ -507,7 +523,7 @@ sub XiaomiSmartHome_Write($@) my $sock = $hash->{CD}; my $MAXLEN = 1024; $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; } ##################################### @@ -518,9 +534,9 @@ sub XiaomiSmartHome_EncryptKey($) my $name = $hash->{NAME}; if ( $hash->{READINGS}{password}{VAL} =~ /^[a-zA-Z0-9]{16}$/ ) { 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}); - $encryptkey = substr($encryptkey, 0, 32); + $encryptkey = substr($encryptkey, 0, 32); return $encryptkey; } else @@ -534,16 +550,18 @@ sub XiaomiSmartHome_EncryptKey($) sub XiaomiSmartHome_Get($@) { my ($hash , $name, $opt, $args ) = @_; - + if ($opt eq "UpdateAll") { XiaomiSmartHome_updateAllReadings($hash); - Log3 $name, 5, "$name: Get> UpdateALLReadings Started"; + Log3 $name, 3, "$name: Get> UpdateALLReadings Started"; + return "UpdateALLReadings Started"; } elsif($opt eq "UpdateSingle") { XiaomiSmartHome_updateSingleReading($hash,$args); - Log3 $name, 5, "$name: Get> UpdateSingel Started"; + Log3 $name, 3, "$name: Get> UpdateSingel Started"; + return "UpdateSingel " . $args . " Started"; } else { @@ -559,9 +577,9 @@ sub XiaomiSmartHome_Notify($$) Log3 $ownName, 5, "$ownName: Notify> NotifyStart"; 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" ); - readingsSingleUpdate($hash, "pct", 100, 1) if ( ! $hash->{READINGS}{pct}{VAL}); - readingsSingleUpdate($hash, "ringtone", 21, 1) if ( ! $hash->{READINGS}{ringtone}{VAL}); - readingsSingleUpdate($hash, "volume", 10, 1) if ( ! $hash->{READINGS}{volume}{VAL}); + readingsSingleUpdate($hash, "pct", 100, 1) if ( ! $hash->{READINGS}{pct}{VAL}); + readingsSingleUpdate($hash, "ringtone", 21, 1) if ( ! $hash->{READINGS}{ringtone}{VAL}); + readingsSingleUpdate($hash, "volume", 10, 1) if ( ! $hash->{READINGS}{volume}{VAL}); my $devName = $dev_hash->{NAME}; # Device that created the events my $events = deviceEvents($dev_hash, 1); 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 $dec_num; @@ -582,14 +600,14 @@ sub XiaomiSmartHome_Set($@) #-- check argument 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 "\"set $name\" needs at least one argument" unless(defined($cmd)); if (!defined $hash->{READINGS}{pct}) { $MIpct = $hash->{READINGS}{pct}{VAL}; } else { $MIpct = 64; - } + } if($cmd eq "password") { #if($args[0] =~ /^[a-zA-Z0-9_.-]*$/) @@ -601,7 +619,7 @@ sub XiaomiSmartHome_Set($@) else { 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}$/) { @@ -612,7 +630,7 @@ sub XiaomiSmartHome_Set($@) elsif($cmd eq "rgb") { my $ownName = $hash->{NAME}; - + Log3 $ownName, 4, "$ownName: Set> $cmd, $args[0]"; $dec_num = sprintf("%d", hex($MIpct . $args[0])); Log3 $ownName, 4, "$ownName: Set> $cmd, $dec_num"; @@ -638,7 +656,7 @@ sub XiaomiSmartHome_Set($@) readingsBulkUpdate( $hash, 'rgb', $hash->{helper}{prevrgbvalue}, 1 ); XiaomiSmartHome_Write($hash,'rgb', $dec_num); } - else + else { readingsBulkUpdate( $hash, 'rgb', "00ff00", 1 ); XiaomiSmartHome_Write($hash,'rgb', 1677786880); @@ -692,7 +710,7 @@ sub XiaomiSmartHome_Set($@) sub XiaomiSmartHome_Attr(@) { my ($cmd,$NAME,$name, $val) = @_; if ($cmd eq "delete"){ - delete $attr{$NAME}{$name}; + delete $attr{$NAME}{$name}; CommandDeleteAttr(undef, "$NAME $name"); Log3 $name, 1, "$name: Attr> delete $name"; } @@ -710,21 +728,19 @@ sub XiaomiSmartHome_connect($) my $name = $hash->{NAME}; my $GATEWAY_IP; Log3 $name, 5, "$name: connect> ConnectStart"; - - Log3 $name, 4, "$name: connecting"; my $p = Net::Ping->new(); if ( ! $p->ping($hash->{GATEWAY})){ Log3 $name, 1, "$name: connect> Ping to $hash->{helper}{host} failed"; $hash->{STATE} = "Disconnected"; XiaomiSmartHome_disconnect($hash); - $p->close(); + $p->close(); return undef; } if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ eval { $GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ; $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 ($@) { Log3 $name, 1, "$name: Connect> Error $@\n"; @@ -735,12 +751,12 @@ sub XiaomiSmartHome_connect($) } XiaomiSmartHome_getGatewaySID($hash); 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: $!"; if ($sock) { - Log3 $name, 4, "$name: connect> Connected"; - $sock->mcast_add('224.0.0.50', $hash->{fhemIP} ) || die "Couldn't set group: $!\n"; #$hash->{fhemIP} + 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_ttl(32); $sock->mcast_loopback(1); $hash->{helper}{ConnectionState} = "Connected"; @@ -778,12 +794,12 @@ sub XiaomiSmartHome_disconnect($) return if (!$hash->{CD}); Log3 $name, 1, "$name: disconnect> disconnecting"; - + close($hash->{CD}) if($hash->{CD}); delete($hash->{FD}); delete($hash->{CD}); delete($selectlist{$name}); - + return undef; } @@ -796,10 +812,10 @@ sub XiaomiSmartHome_updateSingleReading($$) my $GATEWAY = $hash->{GATEWAY}; my $sock = $hash->{CD}; my $MAXLEN = 1024; - + Log3 $name, 4, "$name: updateSingleReading> PushSingelRead:" . $sensor; XiaomiSmartHome_Write($hash, 'read', $sensor); - + } ##################################### @@ -811,10 +827,10 @@ sub XiaomiSmartHome_updateAllReadings($) my $GATEWAY; my $p = Net::Ping->new(); 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"; XiaomiSmartHome_disconnect($hash); - $p->close(); + $p->close(); return undef; } if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ @@ -834,13 +850,13 @@ sub XiaomiSmartHome_updateAllReadings($) $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}"; XiaomiSmartHome_connect($hash); return undef; } - + XiaomiSmartHome_Write($hash, 'get_id_list'); } @@ -858,7 +874,7 @@ sub XiaomiSmartHome_updateAllReadings($)
Ohne Entwicklermodus ist keine Komunikation mit dem Gateway möglich.
-
Zum setzen des Entwicklermoduses braucht man ein android oder ios Gerät mit installierter MI APP.
+
Zum setzen des Entwicklermoduses braucht man ein android oder ios Gerät mit installierter MI APP.
Um das versteckte Menü zu öffnen muss man mehrmals auf die Versionsnummer der MI APP klicken.
Hier finden Sie eine Anleitung mit Bildern.
Android -> https://louiszl.gitbooks.io/lumi-gateway-local-api/content/device_discover.html
@@ -1058,6 +1074,3 @@ sub XiaomiSmartHome_updateAllReadings($)
=cut
-
-
-
diff --git a/FHEM/71_XiaomiSmartHome_Device.pm b/FHEM/71_XiaomiSmartHome_Device.pm
index 7dd1cc9..2035e76 100644
--- a/FHEM/71_XiaomiSmartHome_Device.pm
+++ b/FHEM/71_XiaomiSmartHome_Device.pm
@@ -27,7 +27,7 @@ use warnings;
-my $version = "1.21";
+my $version = "1.30";
sub XiaomiSmartHome_Device_updateSReading($);
@@ -37,8 +37,8 @@ sub XiaomiSmartHome_Device_updateSReading($);
sub XiaomiSmartHome_Device_Initialize($)
{
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->{SetFn} = "XiaomiSmartHome_Device_Set";
$hash->{UndefFn} = "XiaomiSmartHome_Device_Undef";
@@ -50,7 +50,7 @@ sub XiaomiSmartHome_Device_Initialize($)
"rnd_hum:0,1,2,3 ".
"rnd_bat: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 ) = @_;
return "\"set $name\" needs at least one argument" unless(defined($cmd));
-
+
my $setlist = "";
$setlist .= "motionOffTimer:1,5,10 " if ($hash->{MODEL} =~ /motion/);
#$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_ln2');
$setlist .= "status:open,close,stop,auto level:slider,1,1,100 " if ($hash->{MODEL} eq 'curtain');
-
+
if($cmd eq "power")
{
if($args[0] eq "on")
@@ -151,22 +151,22 @@ sub XiaomiSmartHome_Device_Set($@)
{
IOWrite($hash,"status","close",$hash) ;
return;
- }
+ }
elsif($args[0] eq "stop")
{
IOWrite($hash,"status","stop",$hash) ;
return;
- }
+ }
elsif($args[0] eq "auto")
{
IOWrite($hash,"status","auto",$hash) ;
return;
- }
+ }
}
if($cmd eq "level")
{
IOWrite($hash,"level", $args[0] ,$hash) ;
- return;
+ return;
}
# if($cmd eq "open")
# {
@@ -178,7 +178,7 @@ sub XiaomiSmartHome_Device_Set($@)
readingsSingleUpdate($hash, "motionOffTimer", "$args[0]", 1 );;
return;
}
-
+
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_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 $decoded = eval{decode_json($msg)};
@@ -223,7 +223,7 @@ sub XiaomiSmartHome_Device_Read($$$){
readingsBulkUpdate($hash, "state", "$data->{status}", 1 );
if ($data->{status} eq 'motion' && $hash->{MODEL} =~ /motion/){
readingsBulkUpdate($hash, "no_motion", "0", 1 );
- }
+ }
if ($data->{status} eq 'close' && $hash->{MODEL} =~ /magnet/){
readingsBulkUpdate($hash, "no_close", "0", 1 );
}
@@ -241,13 +241,13 @@ sub XiaomiSmartHome_Device_Read($$$){
my $bat = ($data->{voltage}/1000);
Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " Voltage: " . $data->{voltage};
if ($bat < 2.2) {
- readingsBulkUpdate($hash, "battery", "low", 1 );
+ readingsBulkUpdate($hash, "batteryState", "low", 1 );
}
else {
- readingsBulkUpdate($hash, "battery", "ok", 1 )
+ readingsBulkUpdate($hash, "batteryState", "ok", 1 )
}
$bat = XiaomiSmartHome_round($bat, $XMIround_bat, $name );
- readingsBulkUpdate($hash, "batteryLevel", $bat, 1 );
+ readingsBulkUpdate($hash, "batteryVoltage", $bat, 1 );
}
if (defined $data->{temperature}){
if ($data->{temperature} ne "10000"){
@@ -345,7 +345,7 @@ sub XiaomiSmartHome_Device_Read($$$){
readingsBulkUpdate($hash, "rotate", "$data->{rotate}", 1 );
readingsBulkUpdate($hash, "state", "rotate", 1 );
}
- #cube end
+ #cube end
#smoke & natgast start
if (defined $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 $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);
}
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";
}
}
@@ -421,9 +423,11 @@ sub XiaomiSmartHome_Device_update($){
CommandDeleteReading( undef, "$name batterystate" ) if(defined(ReadingsVal($name,"batterystate",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" ) if(defined(ReadingsVal($name,"battery",undef)));
+ CommandDeleteReading( undef, "$name batteryLevel" ) if(defined(ReadingsVal($name,"batteryLevel",undef)));
}
#####################################
-
+
sub XiaomiSmartHome_Device_Define($$) {
my ($hash, $def) = @_;
@@ -437,7 +441,7 @@ sub XiaomiSmartHome_Device_Define($$) {
$modules{XiaomiSmartHome_Device}{defptr}{$sid} = $hash;
AssignIoPort($hash,$iodev);
my $room = $attr{$iodev}{room};
-
+
if(defined($hash->{IODev}->{NAME})) {
my $IOname = $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";
}
$iodev = $hash->{IODev}->{NAME};
-
- my $d = $modules{XiaomiSmartHome_Device}{defptr}{$name};
-
- return "XiaomiSmartHome device $hash->{SID} on XiaomiSmartHome $iodev already defined as $d->{NAME}." if( defined($d) && $d->{IODev} == $hash->{IODev} && $d->{NAME} ne $name );
+
+ my $d = $modules{XiaomiSmartHome_Device}{defptr}{$sid};
+
+ 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};
$attr{$name}{room} = $room if( !defined( $attr{$name}{room} ) );
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} ) );
+
}
elsif ( $type =~ /magnet/) {
$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') {
$attr{$name}{stateFormat} = 'temperature °C, humidity %, pressure kPa' if( !defined( $attr{$name}{stateFormat} ) );
- }
-
+ }
+
if( $init_done ) {
InternalTimer(gettimeofday() + 2, "XiaomiSmartHome_Device_updateSReading", $hash, 0 );
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($)
{
- my ($hash, $arg) = @_;
+ my ($hash, $arg) = @_;
my $name = $hash->{NAME};
my $iodev = $hash->{IODev}->{NAME};
+ my $sid = $hash->{SID};
RemoveInternalTimer($hash);
- delete($modules{XiaomiSmartHome_Device}{defptr}{$hash->{SID}});
- Log3 $name, 4, "$iodev: DEV_Undef> $name - device deleted";
+ Log3 $name, 1, "$iodev: DEV_Undef> ". $hash->{SID} . " > " . $modules{XiaomiSmartHome_Device}{defptr}{$hash->{SID}} . " > " . $sid ." > " . $modules{XiaomiSmartHome_Device}{defptr}{$sid};
+ my $error = delete ($modules{XiaomiSmartHome_Device}{defptr}{$sid});
+ Log3 $name, 1, "$iodev: DEV_Undef> $name - device deleted " . $error;
return undef;
}
@@ -504,8 +512,9 @@ sub XiaomiSmartHome_round {
$p ||= 0;
$n *= 10 ** $p;
$n = int($n + .5 * $sign);
- Log3 $name, 5, "$name: DEV_Round>" . " Result_value: " . $n / 10**$p;
- return $n / 10**$p;
+ my $res = sprintf( "%." . $p . "f", $n / 10**$p);
+ Log3 $name, 5, "$name: DEV_Round>" . " Result_value: " . $res;
+ return $res;
}
@@ -522,7 +531,7 @@ sub XiaomiSmartHome_round {
Ohne Entwicklermodus ist keine Komunikation mit dem Gateway möglich.
-
Zum setzen des Entwicklermoduses braucht man ein android oder ios Gerät mit installierter MI APP.
+
Zum setzen des Entwicklermoduses braucht man ein android oder ios Gerät mit installierter MI APP.
Um das versteckte Menü zu öffnen muss man mehrmals auf die Versionsnummer der MI APP klicken.
Hier finden Sie eine Anleitung mit Bildern.
Android -> https://louiszl.gitbooks.io/lumi-gateway-local-api/content/device_discover.html
@@ -720,4 +729,4 @@ sub XiaomiSmartHome_round {
=end html_DE
-=cut
\ No newline at end of file
+=cut
diff --git a/controls_mish.txt b/controls_mish.txt
index 5cfffdf..5cc5954 100644
--- a/controls_mish.txt
+++ b/controls_mish.txt
@@ -1,2 +1,2 @@
-UPD 2017-12-18_13:56:43 37688 FHEM/71_XiaomiSmartHome.pm
-UPD 2017-12-18_10:00:55 28395 FHEM/71_XiaomiSmartHome_Device.pm
+UPD 2018-06-22_13:29:31 38872 FHEM/71_XiaomiSmartHome.pm
+UPD 2018-06-22_12:45:46 29142 FHEM/71_XiaomiSmartHome_Device.pm