Compare commits
	
		
			45 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8f5f50385b | |||
| 430adca511 | |||
| d3c97857c0 | |||
| f3dc58137a | |||
| 9bde01610d | |||
| 7cdbe5f16c | |||
| e7e4634a53 | |||
| 475b60c50b | |||
| 2b637d9066 | |||
| 140f258c82 | |||
| 5bf1141eaa | |||
| fbd347aae3 | |||
| d3d96436a2 | |||
| 631c54d0d9 | |||
| ae08a7455e | |||
| ad1fa232ca | |||
| e4b1f0cb0c | |||
| 2065ea1e8f | |||
| a7625c0802 | |||
| 5c5c845696 | |||
| a11d334298 | |||
| 672521a4aa | |||
| 95c240efce | |||
| c3f37feacd | |||
| feefe1a418 | |||
| a71f701e7c | |||
| ff57476935 | |||
| 0a9738f543 | |||
| 5e4194c5c1 | |||
| 9c3fc38dc7 | |||
| 24d7fc4e87 | |||
| 0a1c2b4732 | |||
| d19108559b | |||
| 9caee3a95f | |||
| eb3dddcdc2 | |||
| cca119e3fc | |||
| 3f9b1bc745 | |||
| a0f59fd96e | |||
| ca97220d09 | |||
| 3b5be4a8c5 | |||
| 3e2dd99769 | |||
| 52ff120e11 | |||
| cdde04b39d | |||
| 9571dcf066 | |||
| c7f242fd82 | 
| @@ -41,15 +41,15 @@ return "\nERROR: Please install Crypt::CBC" if($@); | |||||||
| eval "use Net::Ping"; | 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; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 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.08"; |  | ||||||
|  | my $version = "1.43"; | ||||||
|  |  | ||||||
| my %XiaomiSmartHome_gets = ( | my %XiaomiSmartHome_gets = ( | ||||||
| 	"getDevices"	=> ["get_id_list", '^.+get_id_list_ack' ], | 	"getDevices"	=> ["get_id_list", '^.+get_id_list_ack' ], | ||||||
|  |  | ||||||
| @@ -64,6 +64,7 @@ my %sets = ( | |||||||
|   "volume:slider,1,1,100" => 1, |   "volume:slider,1,1,100" => 1, | ||||||
|   "ringtone:0,1,2,3,4,5,6,7,8,13,21,22,23,24,25,26,27,28,29,10000,10001" => 1, |   "ringtone:0,1,2,3,4,5,6,7,8,13,21,22,23,24,25,26,27,28,29,10000,10001" => 1, | ||||||
|   "ringvol" => 2, |   "ringvol" => 2, | ||||||
|  |   "learn" => 0, | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -72,7 +73,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'; | ||||||
| 	$hash->{NotifyFn}   = 'XiaomiSmartHome_Notify'; | 	$hash->{NotifyFn}   = 'XiaomiSmartHome_Notify'; | ||||||
| @@ -80,15 +81,16 @@ sub XiaomiSmartHome_Initialize($) { | |||||||
|     $hash->{GetFn}      = 'XiaomiSmartHome_Get'; |     $hash->{GetFn}      = 'XiaomiSmartHome_Get'; | ||||||
|     $hash->{AttrFn}     = 'XiaomiSmartHome_Attr'; |     $hash->{AttrFn}     = 'XiaomiSmartHome_Attr'; | ||||||
|     $hash->{ReadFn}     = 'XiaomiSmartHome_Read'; |     $hash->{ReadFn}     = 'XiaomiSmartHome_Read'; | ||||||
|     $hash->{WriteFn}    = "XiaomiSmartHome_Write"; | 	$hash->{ReadyFn}    = 'XiaomiSmartHome_Ready'; | ||||||
| 	$hash->{AttrList}	= "disable:1,0 " . |     $hash->{WriteFn}    = 'XiaomiSmartHome_Write'; | ||||||
|  | 	$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", | ||||||
| @@ -102,7 +104,12 @@ sub XiaomiSmartHome_Initialize($) { | |||||||
| 						"16:XiaomiSmartHome_Device"     => "^.+natgas", | 						"16:XiaomiSmartHome_Device"     => "^.+natgas", | ||||||
| 						"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", | ||||||
|  | 						"21:XiaomiSmartHome_Device"     => "^.+vibration", | ||||||
|  | 						"22:XiaomiSmartHome_Device"     => "^.*b186acn01", | ||||||
|  | 						"23:XiaomiSmartHome_Device"     => "^.*b286acn01", | ||||||
|  | 						"24:XiaomiSmartHome_Device"     => "^.*b1acn01"}; | ||||||
| 	FHEM_colorpickerInit(); | 	FHEM_colorpickerInit(); | ||||||
| } | } | ||||||
| ##################################### | ##################################### | ||||||
| @@ -110,10 +117,13 @@ 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 | ||||||
| 	my $new_hash = {}; |  | ||||||
|  |  | ||||||
| 	Log3 $name, 5, "$name: Read> Read start"; | 	Log3 $name, 5, "$name: Read> Read start"; | ||||||
|     my $buf = ""; |     if ( ! $hash->{SID} ){ | ||||||
|  | 		Log3 $name, 3, "$name: Read> No SID, Stop Read"; | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	my $buf = ""; | ||||||
|     my $ret = sysread($hash->{CD}, $buf, 1024); |     my $ret = sysread($hash->{CD}, $buf, 1024); | ||||||
|     if (!defined($ret) || $ret <= 0) |     if (!defined($ret) || $ret <= 0) | ||||||
|     { |     { | ||||||
| @@ -122,35 +132,81 @@ sub XiaomiSmartHome_Read($) { | |||||||
|         InternalTimer(gettimeofday() + 2, "XiaomiSmartHome_connect", $hash, 0); |         InternalTimer(gettimeofday() + 2, "XiaomiSmartHome_connect", $hash, 0); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     my $json = $hash->{helper}{JSON}->incr_parse($buf); |  | ||||||
| 	my $decoded = eval{decode_json($buf)}; | 	my $decoded = eval{decode_json($buf)}; | ||||||
| 	if ($@) { | 	if ($@) { | ||||||
| 		Log3 $name, 1, "$name: Read> Error while request: $@"; | 		Log3 $name, 1, "$name: Read> Error while request: $@ " . $buf; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	if ( ! $decoded ) { | 	if ( ! $decoded ) { | ||||||
| 		Log3 $name, 5, "$name: Read> Error no JSON Data " . $buf; | 		Log3 $name, 5, "$name: Read> Error no JSON Data " . $buf; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  | 	my $json = $hash->{helper}{JSON}->incr_parse($buf); | ||||||
|     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') { | ||||||
| 			Log3 $name, 5, "$name: Read> Dispatch " . $buf; | 			# devices does not exist yet | ||||||
| 			Dispatch($hash, $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; | ||||||
|  | 						} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			# 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} ){ | 		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> Wrong Modul HASH skipping $self->{NAME}"; | ||||||
| 			XiaomiSmartHome_Reading ($self, $buf); | 			#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"; | 			Log3 $name, 5, "$name: Read> HASH correctly"; | ||||||
| 			XiaomiSmartHome_Reading ($hash, $buf); | 			XiaomiSmartHome_Reading ($hash, $buf); | ||||||
| 			} | 			return; | ||||||
|     } | 		} | ||||||
|  | 	 } | ||||||
| } | } | ||||||
| ##################################### | ##################################### | ||||||
| sub XiaomiSmartHome_Reading ($@) { | sub XiaomiSmartHome_Reading ($@) { | ||||||
| @@ -199,7 +255,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} ; | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| @@ -235,11 +291,14 @@ sub XiaomiSmartHome_Reading ($@) { | |||||||
| 					Log3 $name, 1, "$name: Reading> Error while request: $@"; | 					Log3 $name, 1, "$name: Reading> Error while request: $@"; | ||||||
| 					return; | 					return; | ||||||
| 				} | 				} | ||||||
|  | 			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 ); | ||||||
|  | 				$all_sensors = $all_sensors . $sensor . ","; | ||||||
| 				} | 				} | ||||||
|  | 			$hash->{helper}{sensors} = $all_sensors; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -286,14 +345,14 @@ 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 ; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			}; | 			}; | ||||||
| @@ -326,7 +385,7 @@ 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]; | ||||||
| @@ -344,7 +403,7 @@ sub XiaomiSmartHome_Define($$) { | |||||||
| 		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, 1, "$name: Define> Set GATEWAYs IP: " .  $GATEWAY_IP; | 			Log3 $name, 5, "$name: Define> Set GATEWAYs IP: " .  $GATEWAY_IP; | ||||||
| 			}; | 			}; | ||||||
| 		if ($@) { | 		if ($@) { | ||||||
| 			Log3 $name, 1, "$name: Define> Error $@\n"; | 			Log3 $name, 1, "$name: Define> Error $@\n"; | ||||||
| @@ -354,7 +413,7 @@ 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"; | ||||||
| @@ -383,7 +442,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; | ||||||
| 		} | 		} | ||||||
| 	else{ | 	else{ | ||||||
| @@ -475,6 +534,11 @@ sub XiaomiSmartHome_Write($@) | |||||||
| 				{ | 				{ | ||||||
| 				$msg  = '{"cmd":"write","model":"curtain","sid":"' . $iohash->{SID} . '","data":"{\"curtain_level\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; | 				$msg  = '{"cmd":"write","model":"curtain","sid":"' . $iohash->{SID} . '","data":"{\"curtain_level\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; | ||||||
| 				} | 				} | ||||||
|  | 			if ($cmd eq 'learn') | ||||||
|  | 				{ | ||||||
|  | 				my $t = '"yes"'; | ||||||
|  | 				$msg  = '{"cmd":"write","model":"gateway","sid":"' . $hash->{SID} . '","data":"{\"join_permission\":' . $t . ',\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	return Log3 $name, 4, "$name: Write> - socket not connected" unless($hash->{CD}); | 	return Log3 $name, 4, "$name: Write> - socket not connected" unless($hash->{CD}); | ||||||
| @@ -482,7 +546,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; | ||||||
| } | } | ||||||
| ##################################### | ##################################### | ||||||
| @@ -506,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->{helper}{ConnectionState} 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($@) | sub XiaomiSmartHome_Get($@) | ||||||
| { | { | ||||||
| 	my ($hash , $name, $opt, $args ) = @_; | 	my ($hash , $name, $opt, $args ) = @_; | ||||||
| @@ -513,12 +593,14 @@ sub XiaomiSmartHome_Get($@) | |||||||
| 	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 | ||||||
| 	{ | 	{ | ||||||
| @@ -531,7 +613,18 @@ sub XiaomiSmartHome_Notify($$) | |||||||
| { | { | ||||||
|  	my ($hash, $dev_hash) = @_; |  	my ($hash, $dev_hash) = @_; | ||||||
| 	my $ownName = $hash->{NAME}; # own name / 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 | 	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}); | ||||||
| @@ -620,6 +713,10 @@ sub XiaomiSmartHome_Set($@) | |||||||
| 			} | 			} | ||||||
| 		readingsEndUpdate( $hash, 1 ); | 		readingsEndUpdate( $hash, 1 ); | ||||||
| 	} | 	} | ||||||
|  | 	elsif($cmd eq "learn") | ||||||
|  | 	{ | ||||||
|  | 		XiaomiSmartHome_Write($hash,'learn', 1); | ||||||
|  | 	} | ||||||
| 	elsif($cmd eq "pct") | 	elsif($cmd eq "pct") | ||||||
| 	{ | 	{ | ||||||
| 		my $ownName = $hash->{NAME}; | 		my $ownName = $hash->{NAME}; | ||||||
| @@ -681,8 +778,6 @@ 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"; | ||||||
| @@ -695,7 +790,7 @@ sub XiaomiSmartHome_connect($) | |||||||
| 		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"; | ||||||
| @@ -706,12 +801,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, 3, "$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"; | ||||||
| @@ -748,7 +843,7 @@ sub XiaomiSmartHome_disconnect($) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     return if (!$hash->{CD}); |     return if (!$hash->{CD}); | ||||||
|     Log3 $name, 3, "$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}); | ||||||
| @@ -782,7 +877,7 @@ 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(); | ||||||
| @@ -872,20 +967,21 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
| 		<li>ctrl_neutral2: Double bond ignition switch</li> | 		<li>ctrl_neutral2: Double bond ignition switch</li> | ||||||
| 		<li>rgbw_light: Smart lights (report only)</li> | 		<li>rgbw_light: Smart lights (report only)</li> | ||||||
| 		<li>curtain: Curtain (Control only if device has reporte curtain_level)</li> | 		<li>curtain: Curtain (Control only if device has reporte curtain_level)</li> | ||||||
|  | 		<li>water: water detector</li> | ||||||
| 		<li>smoke: smoke alarm detector</li> | 		<li>smoke: smoke alarm detector</li> | ||||||
| 		<ul> | 		<ul> | ||||||
| 			<li>0: disarm</li> | 			<li>0: disarm</li> | ||||||
| 			<li>1: arlarm</li> | 			<li>1: alarm</li> | ||||||
| 			<li>8: battery arlarm</li> | 			<li>8: battery alarm</li> | ||||||
| 			<li>64: arlarm sensitivity</li> | 			<li>64: alarm sensitivity</li> | ||||||
| 			<li>32768: ICC communication failure</li> | 			<li>32768: ICC communication failure</li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<li>gas: gas alarm detector</li> | 		<li>gas: gas alarm detector</li> | ||||||
| 		<ul> | 		<ul> | ||||||
| 			<li>0: disarm</li> | 			<li>0: disarm</li> | ||||||
| 			<li>1: arlarm</li> | 			<li>1: alarm</li> | ||||||
| 			<li>2: analog arlarm</li> | 			<li>2: analog alarm</li> | ||||||
| 			<li>64: arlarm sensitivity</li> | 			<li>64: alarm sensitivity</li> | ||||||
| 			<li>32768: ICC communication failure</li> | 			<li>32768: ICC communication failure</li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 	</ul> | 	</ul> | ||||||
| @@ -902,9 +998,11 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
| 		<li>password: without password no write to the gateway is possible. Use the MI APP to find the password</li> | 		<li>password: without password no write to the gateway is possible. Use the MI APP to find the password</li> | ||||||
| 		<li>RGB(Colorpicker): set the color</li> | 		<li>RGB(Colorpicker): set the color</li> | ||||||
| 		<li>PCT(Slider): set the brightness in percent</li> | 		<li>PCT(Slider): set the brightness in percent</li> | ||||||
|  | 		<li>intervals: set the gateway to on for an time eg. set intervals 07:00-08:00</li> | ||||||
| 		<li>ringtone: set the ringtone 0-8,13,21-29,10001-.. | 10000 = off</li> | 		<li>ringtone: set the ringtone 0-8,13,21-29,10001-.. | 10000 = off</li> | ||||||
| 		<li>volume: set the volume 1-100, (100 is very loud)</li> | 		<li>volume: set the volume 1-100, (100 is very loud)</li> | ||||||
| 		<li>ringvol: set ringtone and volume in on step e.g. set [GWNAME] ringvol 21 10</li> | 		<li>ringvol: set ringtone and volume in on step e.g. set [GWNAME] ringvol 21 10</li> | ||||||
|  | 		<li>learn: set the gateway in learningmode to learn new sensors now push the button from the new sensor</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Set: Devices</b> | 	<b>Set: Devices</b> | ||||||
| @@ -931,9 +1029,9 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
|     <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>Voraussetzungen</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>Diese Pakete müssen installiert sein: apt-get install libio-socket-multicast-perl libjson-perl libcrypt-cbc-perl</li> | 		<li>Diese Pakete müssen installiert sein: apt-get install libio-socket-multicast-perl libjson-perl libcrypt-cbc-perl</li> | ||||||
| 		<li>Und mit CPAN: cpan Crypt::Cipher::AES</li> | 		<li>Und mit CPAN: cpan Crypt::Cipher::AES</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| @@ -945,11 +1043,11 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
|         <br><br> |         <br><br> | ||||||
|     </ul> |     </ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Entwicklermodus am Gatway setzen!</b> | 	<b>Entwicklermodus am Gateway setzen!</b> | ||||||
|     <ul> |     <ul> | ||||||
| 		<p>Ohne Entwicklermodus ist keine Komunikation mit dem Gateway möglich. | 		<p>Ohne Entwicklermodus ist keine Kommunikation mit dem Gateway möglich. | ||||||
| 		<br/>Zum setzen des Entwicklermoduses braucht man ein android oder ios Gerät mit installierter MI APP.  | 		<br/>Zum setzen des Entwicklermodusses braucht man ein android oder ios Gerät mit installierter MI APP. | ||||||
| 		<br/>Um das versteckte Menü zu öffnen muss man mehrmals auf die Versionsnummer der MI APP klicken. | 		<br/>Um das versteckte Menü zu öffnen 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 | ||||||
| 		<br/>IOS  -> https://github.com/fooxy/homeassistant-aqara/wiki/Enable-dev-mode | 		<br/>IOS  -> https://github.com/fooxy/homeassistant-aqara/wiki/Enable-dev-mode | ||||||
| @@ -958,32 +1056,33 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Unterstütze Sensoren</b> | 	<b>Unterstütze Sensoren</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>magnet: Magnetischer Fenster/Tür Sensor</li> | 		<li>magnet: Magnetischer Fenster/Tür Sensor</li> | ||||||
| 		<li>motion: Bewegungsmelder</li> | 		<li>motion: Bewegungsmelder</li> | ||||||
| 		<li>sensor_ht: Temperatur und Luftdruck</li> | 		<li>sensor_ht: Temperatur und Luftdruck</li> | ||||||
| 		<li>switch: Funkschalter</li> | 		<li>switch: Funkschalter</li> | ||||||
| 		<li>plug & 86plug: Schaltbare Funksteckdose</li> | 		<li>plug & 86plug: Schaltbare Funksteckdose</li> | ||||||
| 		<li>cube: Würfel Sensor</li> | 		<li>cube: Würfel Sensor</li> | ||||||
| 		<li>86sw1: Einfacher Wandfunkschalter</li> | 		<li>86sw1: Einfacher Wandfunkschalter</li> | ||||||
| 		<li>86sw2: Wandfunkschalter doppelt</li> | 		<li>86sw2: Wandfunkschalter doppelt</li> | ||||||
| 		<li>ctrl_neutral1: Einfacher Wandschalter schaltbar</li> | 		<li>ctrl_neutral1: Einfacher Wandschalter schaltbar</li> | ||||||
| 		<li>ctrl_neutral2: Doppelter Wandschalter schaltbar</li> | 		<li>ctrl_neutral2: Doppelter Wandschalter schaltbar</li> | ||||||
| 		<li>rgbw_light: RBGW Lampe (nur Anzeige)</li> | 		<li>rgbw_light: RBGW Lampe (nur Anzeige)</li> | ||||||
| 		<li>curtain: Vorhangmotor (ohne das das device den curtain_level gemeldet hat ist ein steuern nicht möglich)</li> | 		<li>curtain: Vorhangmotor (ohne dass das Device den curtain_level gemeldet hat ist ein Steuern nicht möglich)</li> | ||||||
|  | 		<li>water: Wasser Sensor</li> | ||||||
| 		<li>smoke: Rauchmelder</li> | 		<li>smoke: Rauchmelder</li> | ||||||
| 		<ul> | 		<ul> | ||||||
| 			<li>0: disarm</li> | 			<li>0: disarm</li> | ||||||
| 			<li>1: arlarm</li> | 			<li>1: alarm</li> | ||||||
| 			<li>8: battery arlarm</li> | 			<li>8: battery alarm</li> | ||||||
| 			<li>64: arlarm sensitivity</li> | 			<li>64: alarm sensitivity</li> | ||||||
| 			<li>32768: ICC communication failure</li> | 			<li>32768: ICC communication failure</li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<li>gas: Gasmelder</li> | 		<li>gas: Gasmelder</li> | ||||||
| 		<ul> | 		<ul> | ||||||
| 			<li>0: disarm</li> | 			<li>0: disarm</li> | ||||||
| 			<li>1: arlarm</li> | 			<li>1: alarm</li> | ||||||
| 			<li>2: analog arlarm</li> | 			<li>2: analog alarm</li> | ||||||
| 			<li>64: arlarm sensitivity</li> | 			<li>64: alarm sensitivity</li> | ||||||
| 			<li>32768: ICC communication failure</li> | 			<li>32768: ICC communication failure</li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 	</ul> | 	</ul> | ||||||
| @@ -992,27 +1091,29 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>Das XiaomiSmartHome Gateway sendet alle 10 seconds einen heartbeat</li> | 		<li>Das XiaomiSmartHome Gateway sendet alle 10 seconds einen heartbeat</li> | ||||||
| 		<li>Jedes XiaomiSmartHome Devices sendet alle 60 Minuten einen heartbeat</li> | 		<li>Jedes XiaomiSmartHome Devices sendet alle 60 Minuten einen heartbeat</li> | ||||||
| 		<li>Das Reading heartbeat wird mit der SID des jeweiligen Gerätes beim empfang eines Heartbeat aktualisiert</li> | 		<li>Das Reading heartbeat wird mit der SID des jeweiligen Gerätes beim Empfang eines Heartbeat aktualisiert</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Set: Gateway</b> | 	<b>Set: Gateway</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>password: Ohne Passwort ist ein Schalten des GATEWAY nicht möglich. Das Passwort findet man in der MI APP</li> | 		<li>password: Ohne Passwort ist ein Schalten des GATEWAY nicht möglich. Das Passwort findet man in der MI APP</li> | ||||||
| 		<li>RGB(Colorpicker): Einstellen der LED Farbe des Gateways</li> | 		<li>RGB(Colorpicker): Einstellen der LED Farbe des Gateways</li> | ||||||
| 		<li>PCT(Slider): Einstellen der Helligkeit des Gateways</li> | 		<li>PCT(Slider): Einstellen der Helligkeit des Gateways</li> | ||||||
| 		<li>ringtone: Wiedergeben eines Arlarmtones 0-8,13,21-29,10001-.. Benutzerdefinierte| 10000 = aus</li> | 		<li>intervals: Einschalten des Gateways für einen Zeitraum zb. set intervals 07:00-08:00</li> | ||||||
| 		<li>volume: Einstellen der Lautstärke des Arlarmtones 1-100, (100 ist sehr laut!)</li> | 		<li>ringtone: Wiedergeben eines Alarmtones 0-8,13,21-29,10001-.. Benutzerdefinierte| 10000 = aus</li> | ||||||
| 		<li>ringvol: Wiedergeben eines Arlamtones und gleichzeitiges verändern der Lautstärke set [GWNAME] ringvol 21 10</li> | 		<li>volume: Einstellen der Lautstärke des Alarmtones 1-100, (100 ist sehr laut!)</li> | ||||||
|  | 		<li>ringvol: Wiedergeben eines Arlamtones und gleichzeitiges verändern der Lautstärke set [GWNAME] ringvol 21 10</li> | ||||||
|  | 		<li>learn: Anlernen neuer Sensoren, nach dem Set an dem neuen Sensor den Button drücken</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Set: Devices</b> | 	<b>Set: Devices</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>motionOffTimer:  (nur Bewegungsmelder) | 		<li>motionOffTimer:  (nur Bewegungsmelder) | ||||||
| 		<br/>Durch setzen des Parameters ist es möglich das das Reading des Bewegungsmelder nach 1, 5 oder 10 Sekunden | 		<br/>Durch setzen des Parameters ist es möglich, dass das Reading des Bewegungsmelder nach 1, 5 oder 10 Sekunden | ||||||
| 		<br/>automatisch wieder auf off gestellt wird. | 		<br/>automatisch wieder auf off gestellt wird. | ||||||
| 		<br/>Hintergrund: Der Bewegungsmelder sendet kein selber kein off. | 		<br/>Hintergrund: Der Bewegungsmelder sendet selber kein off. | ||||||
| 		<br/>Der Bewegungsmelder sendet no_motion nach 120, 180, 300, 600, 1200 Sekunden wenn keine Bewegung festgestellt wurde.</li> | 		<br/>Der Bewegungsmelder sendet no_motion nach 120, 180, 300, 600, 1200 Sekunden, wenn keine Bewegung festgestellt wurde.</li> | ||||||
| 		<li>Power: (nur Funksteckdose) on off Funktsteckdose ein oder ausschalten</li> | 		<li>Power: (nur Funksteckdose) on off Funksteckdose ein oder ausschalten</li> | ||||||
| 		<li>ctrl: (nur Funkschalter) on off Funkschalter </li> | 		<li>ctrl: (nur Funkschalter) on off Funkschalter </li> | ||||||
| 		<li>channel_0: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | 		<li>channel_0: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | ||||||
| 		<li>channel_1: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | 		<li>channel_1: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | ||||||
| @@ -1024,5 +1125,3 @@ sub XiaomiSmartHome_updateAllReadings($) | |||||||
|  |  | ||||||
| =cut | =cut | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,7 +25,10 @@ package main; | |||||||
| use strict; | use strict; | ||||||
| use warnings; | use warnings; | ||||||
|  |  | ||||||
| my $version = "1.08"; |  | ||||||
|  |  | ||||||
|  | my $version = "1.40"; | ||||||
|  |  | ||||||
| sub XiaomiSmartHome_Device_updateSReading($); | sub XiaomiSmartHome_Device_updateSReading($); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -35,14 +38,19 @@ 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"; |   $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|vibration|remote.b186acn01|remote.b286acn01|remote.b1acn01"; | ||||||
|   $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"; | ||||||
|   $hash->{ParseFn}   = "XiaomiSmartHome_Device_Parse"; |   $hash->{ParseFn}   = "XiaomiSmartHome_Device_Parse"; | ||||||
|  |   $hash->{FingerprintFn} = "XiaomiSmartHome_Device_Fingerprint"; | ||||||
|  |  | ||||||
|   $hash->{AttrList}  = "IODev follow-on-for-timer:1,0 follow-on-timer ". |   $hash->{AttrList}  = "follow-on-for-timer:1,0 follow-on-timer ". | ||||||
|                        "do_not_notify:1,0 ignore:1,0 dummy:1,0 showtime:1,0 valueFn:textField-long ". |                        "do_not_notify:1,0 ignore:1,0 dummy:1,0 showtime:1,0 valueFn:textField-long ". | ||||||
|  | 					   "rnd_tmp:0,1,2,3 ". | ||||||
|  | 					   "rnd_hum:0,1,2,3 ". | ||||||
|  | 					   "rnd_bat:0,1,2,3 ". | ||||||
|  | 					   "rnd_pres:0,1,2,3 ". | ||||||
|                        $readingFnAttributes ; |                        $readingFnAttributes ; | ||||||
| } | } | ||||||
| ##################################### | ##################################### | ||||||
| @@ -190,6 +198,12 @@ sub XiaomiSmartHome_Device_on_timeout($){ | |||||||
| ##################################### | ##################################### | ||||||
| sub XiaomiSmartHome_Device_Read($$$){ | sub XiaomiSmartHome_Device_Read($$$){ | ||||||
| 	my ($hash, $msg, $name) = @_; | 	my ($hash, $msg, $name) = @_; | ||||||
|  |  | ||||||
|  | 	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_pres = AttrVal( $hash->{NAME}, "rnd_pres", "2" ); | ||||||
|  |  | ||||||
| 	my $decoded = eval{decode_json($msg)}; | 	my $decoded = eval{decode_json($msg)}; | ||||||
| 	if ($@) { | 	if ($@) { | ||||||
| 		Log3 $name, 1, "$name: DEV_Read> Error while request: $@"; | 		Log3 $name, 1, "$name: DEV_Read> Error while request: $@"; | ||||||
| @@ -197,6 +211,7 @@ sub XiaomiSmartHome_Device_Read($$$){ | |||||||
| 	} | 	} | ||||||
| 	my $sid = $decoded->{'sid'}; | 	my $sid = $decoded->{'sid'}; | ||||||
| 	my $model = $decoded->{'model'}; | 	my $model = $decoded->{'model'}; | ||||||
|  | 	my $cmd = $decoded->{'cmd'}; | ||||||
| 	Log3 $name, 5, "$name: DEV_Read> SID: " . $hash->{SID} . " " . $hash->{TYPE}; | 	Log3 $name, 5, "$name: DEV_Read> SID: " . $hash->{SID} . " " . $hash->{TYPE}; | ||||||
| 	my $data = eval{decode_json($decoded->{data})}; | 	my $data = eval{decode_json($decoded->{data})}; | ||||||
| 	if ($@) { | 	if ($@) { | ||||||
| @@ -204,128 +219,164 @@ sub XiaomiSmartHome_Device_Read($$$){ | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	readingsBeginUpdate( $hash ); | 	readingsBeginUpdate( $hash ); | ||||||
| 	if (defined $data->{status}){ | 		if (defined $data->{status}){ | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Status: " . $data->{status}; | 			Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Status: " . $data->{status}; | ||||||
| 		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/){ | ||||||
|  | 				readingsBulkUpdate($hash, "no_close", "0", 1 ); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		if ($data->{status} eq 'close' && $hash->{MODEL} =~ /magnet/){ |  | ||||||
| 			readingsBulkUpdate($hash, "no_close", "0", 1 ); | 		if (defined $data->{no_motion}){ | ||||||
|  | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " NO_motion: " . $data->{no_motion}; | ||||||
|  | 			readingsBulkUpdate($hash, "no_motion", "$data->{no_motion}", 1 ); | ||||||
| 			} | 			} | ||||||
| 		} | 		if (defined $data->{no_close}){ | ||||||
| 	if (defined $data->{no_motion}){ | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " NO_close: " . $data->{no_close}; | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " NO_motion: " . $data->{no_motion}; | 			readingsBulkUpdate($hash, "no_close", "$data->{no_close}", 1 ); | ||||||
| 		readingsBulkUpdate($hash, "no_motion", "$data->{no_motion}", 1 ); | 			} | ||||||
| 		} | 		if (defined $data->{voltage}){ | ||||||
| 	if (defined $data->{no_close}){ | 			my $bat = ($data->{voltage}/1000); | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " NO_close: " . $data->{no_close}; | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Voltage: " . $data->{voltage}; | ||||||
| 		readingsBulkUpdate($hash, "no_close", "$data->{no_close}", 1 ); | 			if ($bat < 2.2) { | ||||||
| 		} | 				readingsBulkUpdate($hash, "batteryState", "low", 1 ); | ||||||
| 	if (defined $data->{voltage}){ | 				} | ||||||
| 		my $bat = ($data->{voltage}/1000); | 				else { | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Voltage: " . $data->{voltage}; | 					readingsBulkUpdate($hash, "batteryState", "ok", 1 ) | ||||||
| 		readingsBulkUpdate($hash, "battery", $bat, 1 ); | 				} | ||||||
| 		} | 			$bat = XiaomiSmartHome_round($bat, $XMIround_bat, $name ); | ||||||
| 	if (defined $data->{temperature}){ | 			readingsBulkUpdate($hash, "batteryVoltage", $bat, 1 ); | ||||||
| 		my $temp = $data->{temperature}; | 			} | ||||||
| 		$temp =~ s/(^[-+]?\d+?(?=(?>(?:\d{2})+)(?!\d))|\G\d{2}(?=\d))/$1./g; | 		if (defined $data->{temperature}){ | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Temperature: " . $temp; | 			if ($data->{temperature} ne "10000"){ | ||||||
| 		readingsBulkUpdate($hash, "temperature", "$temp", 1 ); | 				my $temp = sprintf( "%#.4d", $data->{temperature}); | ||||||
| 		} | 				$temp =~ s/(^[-+]?\d+?(?=(?>(?:\d{2})+)(?!\d))|\G\d{3}(?=\d))/$1./g; | ||||||
| 	if (defined $data->{humidity}){ | 				$temp = XiaomiSmartHome_round($temp, $XMIround_tmp, $name ); | ||||||
| 		my $hum = $data->{humidity}; | 				Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Temperature: " . $temp . " Round: " . $XMIround_tmp; | ||||||
| 		$hum =~ s/(^[-+]?\d+?(?=(?>(?:\d{2})+)(?!\d))|\G\d{2}(?=\d))/$1./g; | 				readingsBulkUpdate($hash, "temperature", "$temp", 1 ); | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Humidity: " . $hum; | 				} | ||||||
| 		readingsBulkUpdate($hash, "humidity", "$hum", 1 ); | 			} | ||||||
| 		} | 		if (defined $data->{humidity}){ | ||||||
|     if (defined $data->{pressure}){ | 			if ($data->{humidity} ne "0"){ | ||||||
| 		my $pres = $data->{pressure}; | 				my $hum = $data->{humidity}; | ||||||
| 		$pres =~ s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1./g; | 				$hum =~ s/(^[-+]?\d+?(?=(?>(?:\d{2})+)(?!\d))|\G\d{2}(?=\d))/$1./g; | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Pressure: " . $pres; | 				$hum = XiaomiSmartHome_round($hum, $XMIround_hum, $name ); | ||||||
| 		readingsBulkUpdate($hash, "pressure", "$pres", 1 ); | 				Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Humidity: " . $hum . " Round: " . $XMIround_hum; | ||||||
| 		} | 				readingsBulkUpdate($hash, "humidity", "$hum", 1 ); | ||||||
| 	if (defined $data->{lux}){ | 				} | ||||||
| 		my $lux = $data->{lux}; | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Illuminance: " . $lux; | 		if (defined $data->{pressure}){ | ||||||
| 		readingsBulkUpdate($hash, "lux", "$lux", 1 ); | 			if ($data->{pressure} ne "0"){ | ||||||
| 		} | 				my $pres = $data->{pressure}; | ||||||
| 	#86sw1 + 86sw2 + ctrl_neutral1 + ctrl_neutral2 start | 				$pres =~ s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1./g; | ||||||
| 	if (defined $data->{channel_0}){ | 				$pres = XiaomiSmartHome_round($pres, $XMIround_pres, $name ); | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Channel_0: " . $data->{channel_0}; | 				Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Pressure: " . $pres . " Round: " . $XMIround_pres; | ||||||
| 		readingsBulkUpdate($hash, "channel_0", "$data->{channel_0}", 1 ); | 				readingsBulkUpdate($hash, "pressure", "$pres", 1 ); | ||||||
| 		} | 				} | ||||||
| 	if (defined $data->{channel_1}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Channel_1: " . $data->{channel_1}; | 		if (defined $data->{lux}){ | ||||||
| 		readingsBulkUpdate($hash, "channel_1", "$data->{channel_1}", 1 ); | 			my $lux = $data->{lux}; | ||||||
| 		} | 			Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Illuminance: " . $lux; | ||||||
| 	#86sw1 + 86sw2 + ctrl_neutral1 + ctrl_neutral2 end | 			readingsBulkUpdate($hash, "lux", "$lux", 1 ); | ||||||
| 	#plug & 86plug start | 			} | ||||||
| 	if (defined $data->{load_voltage}){ | 		#86sw1 + 86sw2 + ctrl_neutral1 + ctrl_neutral2 start | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " LOAD_Voltage: " . $data->{load_voltage}; | 		if (defined $data->{channel_0}){ | ||||||
| 		readingsBulkUpdate($hash, "LOAD_Voltage", "$data->{load_voltage}", 1 ); | 			Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Channel_0: " . $data->{channel_0}; | ||||||
| 		} | 			readingsBulkUpdate($hash, "channel_0", "$data->{channel_0}", 1 ); | ||||||
| 	if (defined $data->{load_power}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " LOAD_Power: " . $data->{load_power}; | 		if (defined $data->{channel_1}){ | ||||||
| 		readingsBulkUpdate($hash, "LOAD_Power", "$data->{load_power}", 1 ); | 			Log3 $name, 3, "$name: DEV_Read>" . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Channel_1: " . $data->{channel_1}; | ||||||
| 		} | 			readingsBulkUpdate($hash, "channel_1", "$data->{channel_1}", 1 ); | ||||||
| 	if (defined $data->{power_consumed}){ | 			} | ||||||
| 		Log3 $name, 3, "$name:" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " POWER_Consumed: " . $data->{power_consumed}; | 		if (defined $data->{dual_channel}){ | ||||||
| 		readingsBulkUpdate($hash, "POWER_Consumed", "$data->{power_consumed}", 1 ); | 			Log3 $name, 3, "$name: DEV_Read>" . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Dual_Channel: " . $data->{dual_channel}; | ||||||
| 		} | 			readingsBulkUpdate($hash, "dual_channel", "$data->{dual_channel}", 1 ); | ||||||
| 	if (defined $data->{inuse}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " InUse: " . $data->{inuse}; | 		#86sw1 + 86sw2 + ctrl_neutral1 + ctrl_neutral2 end | ||||||
| 		readingsBulkUpdate($hash, "inuse", "$data->{inuse}", 1 ); | 		#plug & 86plug start | ||||||
| 		} | 		if (defined $data->{load_voltage}){ | ||||||
| 	#plug & 86plug end | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " LOAD_Voltage: " . $data->{load_voltage}; | ||||||
| 	#rgbw_light start | 			readingsBulkUpdate($hash, "LOAD_Voltage", "$data->{load_voltage}", 1 ); | ||||||
| 	if (defined $data->{level}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Level: " . $data->{level}; | 		if (defined $data->{load_power}){ | ||||||
| 		readingsBulkUpdate($hash, "level", "$data->{level}", 1 ); | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " LOAD_Power: " . $data->{load_power}; | ||||||
| 		} | 			readingsBulkUpdate($hash, "LOAD_Power", "$data->{load_power}", 1 ); | ||||||
| 	if (defined $data->{hue}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Hue: " . $data->{hue}; | 		if (defined $data->{power_consumed}){ | ||||||
| 		readingsBulkUpdate($hash, "hue", "$data->{hue}", 1 ); | 			Log3 $name, 4, "$name:" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " POWER_Consumed: " . $data->{power_consumed}; | ||||||
| 		} | 			readingsBulkUpdate($hash, "POWER_Consumed", "$data->{power_consumed}", 1 ); | ||||||
| 	if (defined $data->{saturation}){ | 			} | ||||||
| 		Log3 $name, 3, "$name:" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Saturation: " . $data->{saturation}; | 		if (defined $data->{inuse}){ | ||||||
| 		readingsBulkUpdate($hash, "saturation", "$data->{saturation}", 1 ); | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " InUse: " . $data->{inuse}; | ||||||
| 		} | 			readingsBulkUpdate($hash, "inuse", "$data->{inuse}", 1 ); | ||||||
| 	if (defined $data->{color_temperature}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Color_temperature: " . $data->{color_temperature}; | 		#plug & 86plug end | ||||||
| 		readingsBulkUpdate($hash, "color_temperature", "$data->{color_temperature}", 1 ); | 		#rgbw_light start | ||||||
| 		} | 		if (defined $data->{level}){ | ||||||
| 	if (defined $data->{x}){ | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Level: " . $data->{level}; | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " X: " . $data->{x}; | 			readingsBulkUpdate($hash, "level", "$data->{level}", 1 ); | ||||||
| 		readingsBulkUpdate($hash, "x", "$data->{x}", 1 ); | 			} | ||||||
| 		} | 		if (defined $data->{hue}){ | ||||||
| 	if (defined $data->{y}){ | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Hue: " . $data->{hue}; | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Y: " . $data->{y}; | 			readingsBulkUpdate($hash, "hue", "$data->{hue}", 1 ); | ||||||
| 		readingsBulkUpdate($hash, "y", "$data->{y}", 1 ); | 			} | ||||||
| 		} | 		if (defined $data->{saturation}){ | ||||||
| 	#rgbw_light end | 			Log3 $name, 4, "$name:" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Saturation: " . $data->{saturation}; | ||||||
| 	#cube start | 			readingsBulkUpdate($hash, "saturation", "$data->{saturation}", 1 ); | ||||||
| 	if (defined $data->{rotate}){ | 			} | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Rotate: " . $data->{rotate}; | 		if (defined $data->{color_temperature}){ | ||||||
| 		readingsBulkUpdate($hash, "rotate", "$data->{rotate}", 1 ); | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Color_temperature: " . $data->{color_temperature}; | ||||||
| 		readingsBulkUpdate($hash, "state", "rotate", 1 ); | 			readingsBulkUpdate($hash, "color_temperature", "$data->{color_temperature}", 1 ); | ||||||
| 		} | 			} | ||||||
| 	#cube end	 | 		if (defined $data->{x}){ | ||||||
| 	#smoke & natgast start | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " X: " . $data->{x}; | ||||||
| 	if (defined $data->{alarm}){ | 			readingsBulkUpdate($hash, "x", "$data->{x}", 1 ); | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Rotate: " . $data->{arlarm}; | 			} | ||||||
| 		readingsBulkUpdate($hash, "arlarm", "$data->{arlarm}", 1 ); | 		if (defined $data->{y}){ | ||||||
| 		} | 			Log3 $name, 4, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Y: " . $data->{y}; | ||||||
| 	#smoke & natgast end | 			readingsBulkUpdate($hash, "y", "$data->{y}", 1 ); | ||||||
| 	#curtain start | 			} | ||||||
| 	if (defined $data->{curtain_level}){ | 		#rgbw_light end | ||||||
| 		Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Rotate: " . $data->{curtain_level}; | 		#cube start | ||||||
| 		readingsBulkUpdate($hash, "arlarm", "$data->{curtain_level}", 1 ); | 		if (defined $data->{rotate}){ | ||||||
| 		} | 			Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Rotate: " . $data->{rotate}; | ||||||
| 	#curtain end | 			readingsBulkUpdate($hash, "rotate", "$data->{rotate}", 1 ); | ||||||
| 	if ($decoded->{'cmd'} eq 'heartbeat'){ | 			readingsBulkUpdate($hash, "state", "rotate", 1 ); | ||||||
|  | 			} | ||||||
|  | 		#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}; | ||||||
|  | 			readingsBulkUpdate($hash, "alarm", "$data->{alarm}", 1 ); | ||||||
|  | 			} | ||||||
|  | 		if (defined $data->{density}){ | ||||||
|  | 			Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Density: " . $data->{density}; | ||||||
|  | 			readingsBulkUpdate($hash, "density", "$data->{density}", 1 ); | ||||||
|  | 			} | ||||||
|  | 		#smoke & natgast end | ||||||
|  | 		#curtain start | ||||||
|  | 		if (defined $data->{curtain_level}){ | ||||||
|  | 			Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Curtain: " . $data->{curtain_level}; | ||||||
|  | 			readingsBulkUpdate($hash, "alarm", "$data->{curtain_level}", 1 ); | ||||||
|  | 			} | ||||||
|  | 		#curtain end | ||||||
|  |     #vibration Start | ||||||
|  |     if (defined $data->{'coordination'}){ | ||||||
|  |       Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Coordination: " . $data->{coordination}; | ||||||
|  |       readingsBulkUpdate($hash, "coordination", "$data->{coordination}", 1 ); | ||||||
|  |       } | ||||||
|  |     if (defined $data->{'final_tilt_angle'}){ | ||||||
|  |       Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL}  . " Final tilt angle: " . $data->{final_tilt_angle}; | ||||||
|  |       readingsBulkUpdate($hash, "final_tilt_angle", "$data->{final_tilt_angle}", 1 ); | ||||||
|  |       } | ||||||
|  |     #vibration end | ||||||
|  | 		if ($decoded->{'cmd'} eq 'heartbeat'){ | ||||||
| 		readingsBulkUpdate($hash, 'heartbeat', $decoded->{'sid'} , 1 ); | 		readingsBulkUpdate($hash, 'heartbeat', $decoded->{'sid'} , 1 ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	readingsEndUpdate( $hash, 1 ); | 	readingsEndUpdate( $hash, 1 ); | ||||||
| 	XiaomiSmartHome_Device_update($hash); | 	XiaomiSmartHome_Device_update($hash); | ||||||
| 	return $hash->{NAME}; | 	return $hash->{NAME}; | ||||||
| @@ -343,15 +394,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"; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -369,14 +422,19 @@ sub XiaomiSmartHome_Device_update($){ | |||||||
|     my $LASTCMD = ReadingsVal($name,"lastCmd",undef); |     my $LASTCMD = ReadingsVal($name,"lastCmd",undef); | ||||||
|  |  | ||||||
|     my $value_fn = eval $value_fn; |     my $value_fn = eval $value_fn; | ||||||
|     Log3 $name, 3, $name .": DEV_Update valueFn: ". $@ if($@); |     Log3 $name, 4, $name .": DEV_Update valueFn: ". $@ if($@); | ||||||
|     return undef if( !defined($value_fn) ); |     return undef if( !defined($value_fn) ); | ||||||
|   } |   } | ||||||
|   if( $model =~ /motion/) { |   if( $model =~ /motion/) { | ||||||
| 	XiaomiSmartHome_Device_mot($hash, $hash->{READINGS}{motionOffTimer}{VAL}) if( $hash->{READINGS}{motionOffTimer}); | 	XiaomiSmartHome_Device_mot($hash, $hash->{READINGS}{motionOffTimer}{VAL}) if( $hash->{READINGS}{motionOffTimer}); | ||||||
| 	} | 	} | ||||||
|   # Update delete old reading Voltage |   # Update delete old reading voltage & batterystate | ||||||
|   CommandDeleteReading( undef, "$name voltage" ) if(defined(ReadingsVal($name,"voltage",undef))); |   CommandDeleteReading( undef, "$name voltage" ) if(defined(ReadingsVal($name,"voltage",undef))); | ||||||
|  |   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))); | ||||||
| } | } | ||||||
| ##################################### | ##################################### | ||||||
|  |  | ||||||
| @@ -392,6 +450,7 @@ sub XiaomiSmartHome_Device_Define($$) { | |||||||
| 	$hash->{STATE} = 'initialized'; | 	$hash->{STATE} = 'initialized'; | ||||||
| 	$modules{XiaomiSmartHome_Device}{defptr}{$sid} = $hash; | 	$modules{XiaomiSmartHome_Device}{defptr}{$sid} = $hash; | ||||||
| 	AssignIoPort($hash,$iodev); | 	AssignIoPort($hash,$iodev); | ||||||
|  | 	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}; | ||||||
| @@ -401,14 +460,16 @@ sub XiaomiSmartHome_Device_Define($$) { | |||||||
|     } |     } | ||||||
|     $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} = "MiSmartHome" 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} ) ); | ||||||
| @@ -426,12 +487,20 @@ sub XiaomiSmartHome_Device_Define($$) { | |||||||
| 	} | 	} | ||||||
| 	return undef; | 	return undef; | ||||||
| } | } | ||||||
|  | ##################################### | ||||||
|  | sub XiaomiSmartHome_Device_Fingerprint($$){ | ||||||
|  | 	my ($io_name, $msg) = @_; | ||||||
|  | 	Log3 $io_name, 4, "$io_name: Fingerprint> for $msg"; | ||||||
|  | 	return ($io_name, $msg ); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| ##################################### | ##################################### | ||||||
| sub XiaomiSmartHome_Device_updateSReading($) { | sub XiaomiSmartHome_Device_updateSReading($) { | ||||||
|  |  | ||||||
|     my $hash        = shift; |     my $hash        = shift; | ||||||
| 	my $name = $hash->{NAME}; | 	my $name = $hash->{NAME}; | ||||||
| 	Log3 $name, 3, "$name: DEV_updateSReading> for $hash->{SID}"; | 	Log3 $name, 4, "$name: DEV_updateSReading> for $hash->{SID}"; | ||||||
| 	RemoveInternalTimer($hash,'XiaomiSmartHome_Device_updateSReading'); | 	RemoveInternalTimer($hash,'XiaomiSmartHome_Device_updateSReading'); | ||||||
|     IOWrite($hash,'read',"$hash->{SID}"); |     IOWrite($hash,'read',"$hash->{SID}"); | ||||||
| } | } | ||||||
| @@ -443,17 +512,36 @@ 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, 3, "$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; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | ##################################### | ||||||
|  |  | ||||||
|  | sub XiaomiSmartHome_round { | ||||||
|  |   my ($n, $p, $name) = @_; | ||||||
|  |   Log3 $name, 5, "$name: DEV_Round>" . " Value: " . $n . " points: " . $p; | ||||||
|  |   my $sign = ($n > 0) ? 1 : -1; | ||||||
|  |  | ||||||
|  |   $p ||= 0; | ||||||
|  |   $n *= 10 ** $p; | ||||||
|  |   $n = int($n + .5 * $sign); | ||||||
|  |   my $res =  sprintf( "%." . $p . "f", $n / 10**$p); | ||||||
|  |   Log3 $name, 5, "$name: DEV_Round>" . " Result_value: " . $res; | ||||||
|  |   return $res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| 1; | 1; | ||||||
|  |  | ||||||
| =pod | =pod | ||||||
| =item device | =item device | ||||||
| =item summary Module to control XiaomiSmartHome Gateway | =item summary Module to control XiaomiSmartHome Gateway | ||||||
|  | =item summary_DE Modul zum steuern des  XiaomiSmartHome Gateway | ||||||
|  |  | ||||||
|  |  | ||||||
| =begin html | =begin html | ||||||
| @@ -492,15 +580,35 @@ sub XiaomiSmartHome_Device_Undef($) | |||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>magnet: Window/Door magnetic sensor</li> | 		<li>magnet: Window/Door magnetic sensor</li> | ||||||
| 		<li>motion: Human body motion sensor</li> | 		<li>motion: Human body motion sensor</li> | ||||||
| 		<li>sensor_ht: Temperatur and humidity sensor</li> | 		<li>sensor_motion.aq2: Aqara Human body motion sensor with lux readings</li> | ||||||
|  | 		<li>sensor_ht: Temperature and humidity sensor</li> | ||||||
|  | 		<li>weather.v1: Aqara Temperature, pressure and humidity sensor</li> | ||||||
| 		<li>switch: Wireless sensor switch</li> | 		<li>switch: Wireless sensor switch</li> | ||||||
| 		<li>plug: Smart socket</li> | 		<li>plug & 86plug: Smart socket</li> | ||||||
| 		<li>cube: Cube sensor</li> | 		<li>cube: Cube sensor</li> | ||||||
| 		<li>86sw1: Wireless switch single</li> | 		<li>86sw1: Wireless switch single</li> | ||||||
| 		<li>86sw2: Wireless switch double</li> | 		<li>86sw2: Wireless switch double</li> | ||||||
| 		<li>ctrl_neutral1: Single bond ignition switch</li> | 		<li>ctrl_neutral1: Single bond ignition switch</li> | ||||||
| 		<li>ctrl_neutral2: Double bond ignition switch</li> | 		<li>ctrl_neutral2: Double bond ignition switch</li> | ||||||
| 		<li>rgbw_light: Smart lights (report only)</li> | 		<li>rgbw_light: Smart lights (report only)</li> | ||||||
|  | 		<li>curtain: Curtain (Control only if device has reporte curtain_level)</li> | ||||||
|  | 		<li>water: water detector</li> | ||||||
|  | 		<li>smoke: smoke alarm detector</li> | ||||||
|  | 		<ul> | ||||||
|  | 			<li>0: disarm</li> | ||||||
|  | 			<li>1: alarm</li> | ||||||
|  | 			<li>8: battery alarm</li> | ||||||
|  | 			<li>64: alarm sensitivity</li> | ||||||
|  | 			<li>32768: ICC communication failure</li> | ||||||
|  | 		</ul> | ||||||
|  | 		<li>gas: gas alarm detector</li> | ||||||
|  | 		<ul> | ||||||
|  | 			<li>0: disarm</li> | ||||||
|  | 			<li>1: alarm</li> | ||||||
|  | 			<li>2: analog alarm</li> | ||||||
|  | 			<li>64: alarm sensitivity</li> | ||||||
|  | 			<li>32768: ICC communication failure</li> | ||||||
|  | 		</ul> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Heartbeat</b> | 	<b>Heartbeat</b> | ||||||
| @@ -515,16 +623,18 @@ sub XiaomiSmartHome_Device_Undef($) | |||||||
| 		<li>password: without password no write to the gateway is possible. Use the MI APP to find the password</li> | 		<li>password: without password no write to the gateway is possible. Use the MI APP to find the password</li> | ||||||
| 		<li>RGB(Colorpicker): set the color</li> | 		<li>RGB(Colorpicker): set the color</li> | ||||||
| 		<li>PCT(Slider): set the brightness in percent</li> | 		<li>PCT(Slider): set the brightness in percent</li> | ||||||
|  | 		<li>intervals: set the gateway to on for an time eg. set intervals 07:00-08:00</li> | ||||||
| 		<li>ringtone: set the ringtone 0-8,13,21-29,10001-.. | 10000 = off</li> | 		<li>ringtone: set the ringtone 0-8,13,21-29,10001-.. | 10000 = off</li> | ||||||
| 		<li>volume: set the volume 1-100, (100 is very loud)</li> | 		<li>volume: set the volume 1-100, (100 is very loud)</li> | ||||||
| 		<li>ringvol: set ringtone and volume in on step e.g. set [GWNAME] ringvol 21 10</li> | 		<li>ringvol: set ringtone and volume in on step e.g. set [GWNAME] ringvol 21 10</li> | ||||||
|  | 		<li>learn: set the gateway in learningmode to learn new sensors now push the button from the new sensor</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Set: Devices</b> | 	<b>Set: Devices</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>motionOffTimer:  (only motionsensor) | 		<li>motionOffTimer:  (only motionsensor) | ||||||
| 		<br/>You can set a motion Off Timer Attribut on the motion sensor device. You can set 1, 5 or 10 seconds after | 		<br/>You can set a motion Off Timer Attribut on the motion sensor device. You can set 1, 5 or 10 seconds after | ||||||
| 		<br/>the motion sensors will automatically set to off. | 		<br/>the motion sensors will automatically set to off. MotionOffTimer is set to 5 by default. | ||||||
| 		<br/>Background: The motionsensors does not send off immediately. | 		<br/>Background: The motionsensors does not send off immediately. | ||||||
| 		<br/>The Motionsensor send a no_motion after 120, 180, 300, 600, 1200 seconds no motion is detected.</li> | 		<br/>The Motionsensor send a no_motion after 120, 180, 300, 600, 1200 seconds no motion is detected.</li> | ||||||
| 		<li>Power: (only smart soket) on off switch a plug on or off</li> | 		<li>Power: (only smart soket) on off switch a plug on or off</li> | ||||||
| @@ -538,15 +648,15 @@ sub XiaomiSmartHome_Device_Undef($) | |||||||
|  |  | ||||||
| =begin html_DE | =begin html_DE | ||||||
|  |  | ||||||
| <a name="XiaomiSmartHome"></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>Voraussetzungen</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>Diese Pakete müssen installiert sein: apt-get install libio-socket-multicast-perl libjson-perl libcrypt-cbc-perl</li> | 		<li>Diese Pakete müssen installiert sein: apt-get install libio-socket-multicast-perl libjson-perl libcrypt-cbc-perl</li> | ||||||
| 		<li>Und mit CPAN: cpan Crypt::Cipher::AES</li> | 		<li>Und mit CPAN: cpan Crypt::Cipher::AES</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| @@ -558,11 +668,11 @@ sub XiaomiSmartHome_Device_Undef($) | |||||||
|         <br><br> |         <br><br> | ||||||
|     </ul> |     </ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Entwicklermodus am Gatway setzen!</b> | 	<b>Entwicklermodus am Gateway setzen!</b> | ||||||
|     <ul> |     <ul> | ||||||
| 		<p>Ohne Entwicklermodus ist keine Komunikation mit dem Gateway möglich. | 		<p>Ohne Entwicklermodus ist keine Kommunikation mit dem Gateway möglich. | ||||||
| 		<br/>Zum setzen des Entwicklermoduses braucht man ein android oder ios Gerät mit installierter MI APP.  | 		<br/>Zum setzen des Entwicklermodusses braucht man ein android oder ios Gerät mit installierter MI APP. | ||||||
| 		<br/>Um das versteckte Menü zu öffnen muss man mehrmals auf die Versionsnummer der MI APP klicken. | 		<br/>Um das versteckte Menü zu öffnen 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 | ||||||
| 		<br/>IOS  -> https://github.com/fooxy/homeassistant-aqara/wiki/Enable-dev-mode | 		<br/>IOS  -> https://github.com/fooxy/homeassistant-aqara/wiki/Enable-dev-mode | ||||||
| @@ -571,46 +681,64 @@ sub XiaomiSmartHome_Device_Undef($) | |||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Unterstütze Sensoren</b> | 	<b>Unterstütze Sensoren</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>magnet: Magnetischer Fenster/Tür Sensor</li> | 		<li>magnet: Magnetischer Fenster/Tür Sensor</li> | ||||||
| 		<li>motion: Bewegungsmelder</li> | 		<li>motion: Bewegungsmelder</li> | ||||||
| 		<li>sensor_motion.aq2: Aqara Bewegungsmelder mit lux-Messung</li> |  | ||||||
| 		<li>sensor_ht: Temperatur und Luftdruck</li> | 		<li>sensor_ht: Temperatur und Luftdruck</li> | ||||||
| 		<li>weather.v1: Aqara Temperatur, Luftdruck und Feuchtigkeit</li> |  | ||||||
| 		<li>switch: Funkschalter</li> | 		<li>switch: Funkschalter</li> | ||||||
| 		<li>plug: Schaltbare Funksteckdose</li> | 		<li>plug & 86plug: Schaltbare Funksteckdose</li> | ||||||
| 		<li>cube: Würfel Sensor</li> | 		<li>cube: Würfel Sensor</li> | ||||||
| 		<li>86sw1: Einfacher Wandfunkschalter</li> | 		<li>86sw1: Einfacher Wandfunkschalter</li> | ||||||
| 		<li>86sw2: Wandfunkschalter doppelt</li> | 		<li>86sw2: Wandfunkschalter doppelt</li> | ||||||
| 		<li>ctrl_neutral1: Einfacher Wandschalter schaltbar</li> | 		<li>ctrl_neutral1: Einfacher Wandschalter schaltbar</li> | ||||||
| 		<li>ctrl_neutral2: Doppelter Wandschalter schaltbar</li> | 		<li>ctrl_neutral2: Doppelter Wandschalter schaltbar</li> | ||||||
| 		<li>rgbw_light: RBGW Lampe (nur Anzeige)</li> | 		<li>rgbw_light: RBGW Lampe (nur Anzeige)</li> | ||||||
|  | 		<li>curtain: Vorhangmotor (ohne dass das Device den curtain_level gemeldet hat ist ein Steuern nicht öglich)</li> | ||||||
|  | 		<li>water: Wasser Sensor</li> | ||||||
|  | 		<li>smoke: Rauchmelder</li> | ||||||
|  | 		<ul> | ||||||
|  | 			<li>0: disarm</li> | ||||||
|  | 			<li>1: alarm</li> | ||||||
|  | 			<li>8: battery alarm</li> | ||||||
|  | 			<li>64: alarm sensitivity</li> | ||||||
|  | 			<li>32768: ICC communication failure</li> | ||||||
|  | 		</ul> | ||||||
|  | 		<li>gas: Gasmelder</li> | ||||||
|  | 		<ul> | ||||||
|  | 			<li>0: disarm</li> | ||||||
|  | 			<li>1: alarm</li> | ||||||
|  | 			<li>2: analog alarm</li> | ||||||
|  | 			<li>64: alarm sensitivity</li> | ||||||
|  | 			<li>32768: ICC communication failure</li> | ||||||
|  | 		</ul> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Heartbeat</b> | 	<b>Heartbeat</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>Das XiaomiSmartHome Gateway sendet alle 10 seconds einen heartbeat</li> | 		<li>Das XiaomiSmartHome Gateway sendet alle 10 seconds einen heartbeat</li> | ||||||
| 		<li>Jedes XiaomiSmartHome Devices sendet alle 60 Minuten einen heartbeat</li> | 		<li>Jedes XiaomiSmartHome Devices sendet alle 60 Minuten einen heartbeat</li> | ||||||
| 		<li>Das Reading heartbeat wird mit der SID des jeweiligen Gerätes beim empfang eines Heartbeat aktualisiert</li> | 		<li>Das Reading heartbeat wird mit der SID des jeweiligen Gerätes beim Empfang eines Heartbeat aktualisiert</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Set: Gateway</b> | 	<b>Set: Gateway</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>password: Ohne Passwort ist ein Schalten des GATEWAY nicht möglich. Das Passwort findet man in der MI APP</li> | 		<li>password: Ohne Passwort ist ein Schalten des GATEWAY nicht möglich. Das Passwort findet man in der MI APP</li> | ||||||
| 		<li>RGB(Colorpicker): Einstellen der LED Farbe des Gateways</li> | 		<li>RGB(Colorpicker): Einstellen der LED Farbe des Gateways</li> | ||||||
| 		<li>PCT(Slider): Einstellen der Helligkeit des Gateways</li> | 		<li>PCT(Slider): Einstellen der Helligkeit des Gateways</li> | ||||||
| 		<li>ringtone: Wiedergeben eines Arlarmtones 0-8,13,21-29,10001-.. Benutzerdefinierte| 10000 = aus</li> | 		<li>intervals: Einschalten des Gateways für einen Zeitraum zb. set intervals 07:00-08:00</li> | ||||||
| 		<li>volume: Einstellen der Lautstärke des Arlarmtones 1-100, (100 ist sehr laut!)</li> | 		<li>ringtone: Wiedergeben eines Alarmtones 0-8,13,21-29,10001-.. Benutzerdefinierte| 10000 = aus</li> | ||||||
| 		<li>ringvol: Wiedergeben eines Arlamtones und gleichzeitiges verändern der Lautstärke set [GWNAME] ringvol 21 10</li> | 		<li>volume: Einstellen der Lautstärke des Alarmtones 1-100, (100 ist sehr laut!)</li> | ||||||
|  | 		<li>ringvol: Wiedergeben eines Arlamtones und gleichzeitiges verändern der Lautstärke set [GWNAME] ringvol 21 10</li> | ||||||
|  | 		<li>learn: Anlernen neuer Sensoren, nach dem Set an dem neuen Sensor den Button drücken</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	<br/> | 	<br/> | ||||||
| 	<b>Set: Devices</b> | 	<b>Set: Devices</b> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li>motionOffTimer:  (nur Bewegungsmelder) | 		<li>motionOffTimer:  (nur Bewegungsmelder) | ||||||
| 		<br/>Durch setzen des Parameters ist es möglich das das Reading des Bewegungsmelder nach 1, 5 oder 10 Sekunden | 		<br/>Durch setzen des Parameters ist es möglich, dass das Reading des Bewegungsmelder nach 1, 5 oder 10 Sekunden | ||||||
| 		<br/>automatisch wieder auf off gestellt wird. Standardmäßig ist dieser Wert auf 5 gestellt, sodass der Sensor alle 5 Sekunden auf eine erneute Bewegung reagiert. | 		<br/>automatisch wieder auf off gestellt wird. | ||||||
| 		<br/>Hintergrund: Der Bewegungsmelder sendet kein selber kein off. | 		<br/>Hintergrund: Der Bewegungsmelder sendet selber kein off. | ||||||
| 		<br/>Der Bewegungsmelder sendet no_motion nach 120, 180, 300, 600, 1200 Sekunden wenn keine Bewegung festgestellt wurde.</li> | 		<br/>Der Bewegungsmelder sendet no_motion nach 120, 180, 300, 600, 1200 Sekunden, wenn keine Bewegung festgestellt wurde.</li> | ||||||
| 		<li>Power: (nur Funksteckdose) on off Funktsteckdose ein oder ausschalten</li> | 		<li>Power: (nur Funksteckdose) on off Funksteckdose ein oder ausschalten</li> | ||||||
| 		<li>ctrl: (nur Funkschalter) on off Funkschalter </li> | 		<li>ctrl: (nur Funkschalter) on off Funkschalter </li> | ||||||
| 		<li>channel_0: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | 		<li>channel_0: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | ||||||
| 		<li>channel_1: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | 		<li>channel_1: (nur Doppelter Wandschalter schaltbar) ein oder ausschalten </li> | ||||||
| @@ -620,3 +748,4 @@ sub XiaomiSmartHome_Device_Undef($) | |||||||
| =end html_DE | =end html_DE | ||||||
|  |  | ||||||
| =cut | =cut | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,6 +1,43 @@ | |||||||
| # fhem-XiaomiSmartHome Gateway | # fhem-XiaomiSmartHome Gateway | ||||||
| With this module, the XiaomiGateway is bound to Fhem. The module listens for multicast messages from the gateway. Currently only  for the sensortype Magnet, Motion, Temperature-Humidity, Switch, Cube, Curtain, Smoke and Gas.  | With this module, the Xiaomi Smarthome Gateway is bound to FHEM. The module listens for multicast messages from the gateway.  | ||||||
| Changing and switching the led of the gateway and changing ringtone and volume of the gateway is also possible | Changing and switching the LED from the gateway and changing ringtone and volume of the gateway is also possible | ||||||
|  |  | ||||||
| * Please read the Wiki !! you need to install some Perl modules. | * Please read the Wiki !! you need to install some Perl modules. | ||||||
| * https://github.com/T0RST3N/fhem-XiaomiSmartHome/wiki | * https://github.com/T0RST3N/fhem-XiaomiSmartHome/wiki | ||||||
|  |  | ||||||
|  | # Supported Sensors | ||||||
|  | * magnet: Window/Door magnetic sensor | ||||||
|  | * motion: Human body motion sensor | ||||||
|  | * sensor_motion.aq2: Aqara Human body motion sensor with lux readings | ||||||
|  | * sensor_ht: Temperature and humidity sensor | ||||||
|  | * weather.v1: Aqara Temperature, pressure and humidity sensor | ||||||
|  | * switch: Wireless sensor switch | ||||||
|  | * plug & 86plug: Smart socket | ||||||
|  | * cube: Cube sensor | ||||||
|  | * 86sw1: Wireless switch single | ||||||
|  | * 86sw2: Wireless switch double | ||||||
|  | * ctrl_neutral1: Single bond ignition switch | ||||||
|  | * ctrl_neutral2: Double bond ignition switch | ||||||
|  | * rgbw_light: Smart lights (report only) | ||||||
|  | * curtain: Curtain (Control only if device has reporte curtain_level) | ||||||
|  | * wleak: Watersensor | ||||||
|  | * smoke: smoke alarm detector | ||||||
|  | * * 0: disarm | ||||||
|  | * * 1: arlarm | ||||||
|  | * * 8: battery arlarm | ||||||
|  | * * 64: arlarm sensitivity | ||||||
|  | * * 32768: ICC communication failure | ||||||
|  | * gas: gas alarm detector | ||||||
|  | * * 0: disarm | ||||||
|  | * * 1: arlarm | ||||||
|  | * * 2: analog arlarm | ||||||
|  | * * 64: arlarm sensitivity | ||||||
|  | * * 32768: ICC communication failure | ||||||
|  | * vibration: Detect vibration | ||||||
|  |  | ||||||
|  | # A BIG ThankYOU to my Supporters | ||||||
|  | * StefanB from Coburg | ||||||
|  | * Hendrik S | ||||||
|  | * Karsten B | ||||||
|  | * Juergen K | ||||||
|  | * FHEM-Wohnung | ||||||
|   | |||||||
| @@ -1,2 +1,2 @@ | |||||||
| UPD 2017-07-17_17:26:57 36127 FHEM/71_XiaomiSmartHome.pm | UPD 2019-04-26_11:40:51 40758 FHEM/71_XiaomiSmartHome.pm | ||||||
| UPD 2017-07-17_17:01:34 24008 FHEM/71_XiaomiSmartHome_Device.pm | UPD 2019-03-20_11:32:54 30100 FHEM/71_XiaomiSmartHome_Device.pm | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								images/7.PNG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								images/7.PNG
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 21 KiB | 
		Reference in New Issue
	
	Block a user