diff --git a/FHEM/71_XiaomiSmartHome.pm b/FHEM/71_XiaomiSmartHome.pm index b8d2b13..19e54a5 100644 --- a/FHEM/71_XiaomiSmartHome.pm +++ b/FHEM/71_XiaomiSmartHome.pm @@ -45,13 +45,10 @@ return "\nERROR: Please install Net::Ping" if($@); use Color; use SetExtensions; - - -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.30"; +my $version = "1.40"; my %XiaomiSmartHome_gets = ( "getDevices" => ["get_id_list", '^.+get_id_list_ack' ], @@ -76,7 +73,7 @@ my %sets = ( sub XiaomiSmartHome_Initialize($) { my ($hash) = @_; - $hash->{Clients} = "XiaomiSmartHome_Device"; + $hash->{Clients} = 'XiaomiSmartHome_Device'; $hash->{DefFn} = 'XiaomiSmartHome_Define'; $hash->{UndefFn} = 'XiaomiSmartHome_Undef'; $hash->{NotifyFn} = 'XiaomiSmartHome_Notify'; @@ -84,8 +81,9 @@ sub XiaomiSmartHome_Initialize($) { $hash->{GetFn} = 'XiaomiSmartHome_Get'; $hash->{AttrFn} = 'XiaomiSmartHome_Attr'; $hash->{ReadFn} = 'XiaomiSmartHome_Read'; - $hash->{WriteFn} = "XiaomiSmartHome_Write"; - $hash->{AttrList} = "disable:1,0 " . + $hash->{ReadyFn} = 'XiaomiSmartHome_Ready'; + $hash->{WriteFn} = 'XiaomiSmartHome_Write'; + $hash->{AttrList} = 'disable:1,0 ' . $readingFnAttributes; $hash->{MatchList} = { "1:XiaomiSmartHome_Device" => ".*magnet.*", @@ -107,7 +105,11 @@ 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", + "21:XiaomiSmartHome_Device" => "^.+vibration", + "22:XiaomiSmartHome_Device" => "^.*b186acn01", + "23:XiaomiSmartHome_Device" => "^.*b286acn01", + "24:XiaomiSmartHome_Device" => "^.*b1acn01"}; FHEM_colorpickerInit(); } ##################################### @@ -130,7 +132,7 @@ sub XiaomiSmartHome_Read($) { InternalTimer(gettimeofday() + 2, "XiaomiSmartHome_connect", $hash, 0); return; } - my $json = $hash->{helper}{JSON}->incr_parse($buf); + my $json = $hash->{helper}{JSON}->incr_parse($buf); my $decoded = eval{decode_json($buf)}; if ($@) { Log3 $name, 1, "$name: Read> Error while request: $@"; @@ -145,6 +147,7 @@ sub XiaomiSmartHome_Read($) { 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') { + # devices does not exist yet if (!$modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME}){ Log3 $name, 5, "$name: Read> XiaomiSmartHome_Device unknown trying autocreate" ; my $def=$modules{XiaomiSmartHome}{defptr}; @@ -155,35 +158,55 @@ sub XiaomiSmartHome_Read($) { Log3 $value->{NAME}, 5, "$value->{NAME}: $rsid is sensor from $value->{NAME}"; Dispatch($value, $buf, undef); return; - } + } } } - 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; + # devices available with proper and HEARTBEAT gw + elsif ($decoded->{'cmd'} eq 'heartbeat' && $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} eq $hash->{NAME}) { + Log3 $name, 5, "$name: Read> Dispatching! " . "SID: " . $rsid . " " . $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} . " " . $hash->{NAME}; + Dispatch($hash, $buf, undef); return; + } + elsif ($decoded->{'cmd'} eq 'report' && $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} eq $hash->{NAME}) { + Log3 $name, 5, "$name: Read> Dispatching! " . "SID: " . $rsid . " " . $modules{XiaomiSmartHome_Device}{defptr}{$rsid}{IODev}->{NAME} . " " . $hash->{NAME}; + Dispatch($hash, $buf, undef); + return; + } + # Senosoren check change to right GW + elsif ($decoded->{'cmd'} eq 'read_ack') { + $hash = $modules{XiaomiSmartHome_Device}{defptr}{$rsid}->{IODev}; + Log3 $name, 4, "$name: Read> Dispatching using this GW " . $hash->{NAME} ; + Dispatch($hash, $buf, undef); + return; + } + + } + # gateway sensor list + elsif ($decoded->{'cmd'} eq 'get_id_list_ack'){ + $self = $modules{XiaomiSmartHome}{defptr}{$rsid}; + Log3 $name, 5, "$name: Read> Reading Sensorlist with $self->{NAME}" ; + XiaomiSmartHome_Reading ($self, $buf); + return; } + # gateway not definded + elsif (!$modules{XiaomiSmartHome}{defptr}{$rsid}){ + Log3 $name, 1, "$name: Read> GW not defined " . $buf; + return; + } + # gateway defined but not the right modul instance - change 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}"; - XiaomiSmartHome_Reading ($self, $buf); + Log3 $name, 5, "$name: Read> Wrong Modul HASH skipping $self->{NAME}"; + #XiaomiSmartHome_Reading ($self, $buf); no reading anymore! + return; } - else - { + #gateway defined and the right modul instance - nothing to change + elsif ( $modules{XiaomiSmartHome}{defptr}{$rsid}->{SID} eq $hash->{SID} ){ Log3 $name, 5, "$name: Read> HASH correctly"; XiaomiSmartHome_Reading ($hash, $buf); - } - } + return; + } + } } ##################################### sub XiaomiSmartHome_Reading ($@) { @@ -547,6 +570,22 @@ sub XiaomiSmartHome_EncryptKey($) } ##################################### +sub XiaomiSmartHome_Ready($) +{ + my ($hash) = @_; + + # Versuch eines Verbindungsaufbaus, sofern die Verbindung beendet ist. + return DevIo_OpenDev($hash, 1, undef ) if ( $hash->{STATE} eq "disconnected" ); + + # This is relevant for Windows/USB only + if(defined($hash->{USBDev})) { + my $po = $hash->{USBDev}; + my ( $BlockingFlags, $InBytes, $OutBytes, $ErrorFlags ) = $po->status; + return ( $InBytes > 0 ); + } +} +##################################### + sub XiaomiSmartHome_Get($@) { my ($hash , $name, $opt, $args ) = @_; @@ -574,7 +613,18 @@ sub XiaomiSmartHome_Notify($$) { my ($hash, $dev_hash) = @_; my $ownName = $hash->{NAME}; # own name / hash - Log3 $ownName, 5, "$ownName: Notify> NotifyStart"; + #my $evName = $dev_hash->{NAME}; # triggered device + #my $rsid = $dev_hash->{SID}; + Log3 $ownName, 5, "$ownName: Notify> NotifyStart";# . $rsid . " " . $evName; + + # gateway defined but not the right modul instance + #if ( $modules{XiaomiSmartHome}{defptr}{$rsid}->{SID} ne $hash->{SID} ){ + # Log3 $ownName, 5, "$ownName: Notify> Wrong Event-Modul HASH skipping " . $evName; + # #XiaomiSmartHome_Reading ($self, $buf); + # return; + #} + + 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}); @@ -921,17 +971,17 @@ sub XiaomiSmartHome_updateAllReadings($)
  • smoke: smoke alarm detector
  • gas: gas alarm detector
  • @@ -979,9 +1029,9 @@ sub XiaomiSmartHome_updateAllReadings($) XiaomiSmartHome Steuern des XiaomiSmartHome Gateway und deren verbundener Sensoren.
    - Vorraussetzungen + Voraussetzungen
    @@ -993,11 +1043,11 @@ sub XiaomiSmartHome_updateAllReadings($)


    - Entwicklermodus am Gatway setzen! + Entwicklermodus am Gateway setzen!
    - Entwicklermodus am Gatway setzen! + Entwicklermodus am Gateway setzen!