Merge pull request #3 from T0RST3N/devel

support all sensors protokol 1.0.7. FIX for Multigw Support
This commit is contained in:
2017-06-26 16:59:39 +02:00
committed by GitHub
4 changed files with 240 additions and 94 deletions

View File

@@ -49,7 +49,7 @@ use SetExtensions;
sub XiaomiSmartHome_Notify($$); 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.01"; my $version = "1.06";
my %XiaomiSmartHome_gets = ( my %XiaomiSmartHome_gets = (
"getDevices" => ["get_id_list", '^.+get_id_list_ack' ], "getDevices" => ["get_id_list", '^.+get_id_list_ack' ],
@@ -94,14 +94,22 @@ sub XiaomiSmartHome_Initialize($) {
"8:XiaomiSmartHome_Device" => "^.+86sw2", "8:XiaomiSmartHome_Device" => "^.+86sw2",
"9:XiaomiSmartHome_Device" => "^.+ctrl_neutral1", "9:XiaomiSmartHome_Device" => "^.+ctrl_neutral1",
"10:XiaomiSmartHome_Device" => "^.+ctrl_neutral2", "10:XiaomiSmartHome_Device" => "^.+ctrl_neutral2",
"11:XiaomiSmartHome_Device" => "^.+rgbw_light"}; "11:XiaomiSmartHome_Device" => "^.+rgbw_light",
"12:XiaomiSmartHome_Device" => "^.+curtain",
"13:XiaomiSmartHome_Device" => "^.+ctrl_ln1",
"14:XiaomiSmartHome_Device" => "^.+ctrl_ln2",
"15:XiaomiSmartHome_Device" => "^.+86plug",
"16:XiaomiSmartHome_Device" => "^.+natgas",
"17:XiaomiSmartHome_Device" => "^.+smoke"};
FHEM_colorpickerInit(); FHEM_colorpickerInit();
} }
##################################### #####################################
sub XiaomiSmartHome_Read($) { sub XiaomiSmartHome_Read($) {
my ($hash) = @_; my ($hash) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $self = {}; # my new hash
my $new_hash = {};
Log3 $name, 5, "$name: Read> Read start"; Log3 $name, 5, "$name: Read> Read start";
my $buf = ""; my $buf = "";
my $ret = sysread($hash->{CD}, $buf, 1024); my $ret = sysread($hash->{CD}, $buf, 1024);
@@ -112,7 +120,6 @@ 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 $json = $hash->{helper}{JSON}->incr_parse($buf);
my $decoded = eval{decode_json($buf)}; my $decoded = eval{decode_json($buf)};
if ($@) { if ($@) {
@@ -126,90 +133,117 @@ sub XiaomiSmartHome_Read($) {
if ($json) if ($json)
{ {
Log3 $name, 5, "$name: Read> " . $buf; Log3 $name, 5, "$name: Read> " . $buf;
if ($decoded->{'cmd'} eq 'report' && $decoded->{'model'} eq 'gateway' || $decoded->{'cmd'} eq 'heartbeat' && $decoded->{'model'} eq 'gateway' || $decoded->{'cmd'} eq 'write_ack'){ my $rsid = $decoded->{'sid'};
if ($decoded->{'sid'} ne $hash->{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') {
Log3 $name, 5, "$name: Read> $decoded->{'sid'} not matching with my SID $hash->{SID} skipping"; Log3 $name, 5, "$name: Read> Dispatch " . $buf;
return; Dispatch($hash, $buf, undef);
}
readingsBeginUpdate( $hash );
if ($decoded->{'model'} && $decoded->{'model'} eq 'gateway' ){
if ($decoded->{'cmd'} eq 'report'){
my $data = eval{decode_json($decoded->{data})};
if ($@) {
Log3 $name, 1, "$name: Read> Error while request: $@";
return;
}
if (defined $data->{rgb}){
Log3 $name, 3, "$name: Read>" . " SID: " . $decoded->{'sid'} . " Type: Gateway" . " RGB: " . $data->{rgb} ;
readingsBulkUpdate($hash, "RGB", $data->{rgb} , 1 );
}
if (defined $data->{illumination}){
Log3 $name, 3, "$name: Read>" . " SID: " . $decoded->{'sid'} . " Type: Gateway" . " Illumination: " . $data->{illumination} ;
readingsBulkUpdate($hash, "illumination", $data->{illumination} , 1 );
}
}
elsif ($decoded->{'cmd'} eq 'heartbeat'){
my $data = eval{decode_json($decoded->{data})};
if ($@) {
Log3 $name, 1, "$name: Read> Error while request: $@";
return;
}
if ($data->{ip} eq $hash->{GATEWAY_IP}){
readingsBulkUpdate($hash, 'heartbeat', $decoded->{'sid'}, 1 );
readingsBulkUpdate($hash, 'token', $decoded->{'token'}, 1 );
Log3 $name, 4, "$name: Read> Heartbeat from $data->{ip} received with $decoded->{'sid'}";
#$hash->{SID} = $decoded->{'sid'};
}
else {
Log3 $name, 4, "$name: Read> IP-Heartbeat Data didnt match! $data->{ip} " . $hash->{GATEWAY_IP} ;
}
}
}
if ($decoded->{'cmd'} eq 'write_ack'){
if ($decoded->{'sid'} ne $hash->{SID} ){
Log3 $name, 5, "$name: Read> $decoded->{'sid'} not matching with my SID $hash->{SID} skipping";
return;
}
Log3 $name, 4, "$name: Read> Write answer " . $hash->{GATEWAY} ;
my $data = eval{decode_json($decoded->{data})};
if ($@) {
Log3 $name, 1, "$name: Read> Error while request: $@";
return;
}
if ($data->{error}){
readingsBulkUpdate($hash, 'heartbeat', $data->{error}, 1 );
}
else {
readingsBulkUpdate($hash, 'heartbeat', "Write_OK", 1 );
readingsBulkUpdate($hash, "proto_version", $data->{proto_version} , 1 );
}
}
readingsEndUpdate( $hash, 1 );
return;
} }
if ($decoded->{'cmd'} eq 'get_id_list_ack'){ 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);
}
else
{
Log3 $name, 5, "$name: Read> HASH correctly";
XiaomiSmartHome_Reading ($hash, $buf);
}
}
}
#####################################
sub XiaomiSmartHome_Reading ($@) {
my ($hash, $buf) = @_;
my $name = $hash->{NAME};
Log3 $name, 5, "$name: Reading> Reading start";
my $json = $hash->{helper}{JSON}->incr_parse($buf);
my $decoded = eval{decode_json($buf)};
if ($@) {
Log3 $name, 1, "$name: Reading> Error while request: $@";
return;
}
if ($json){
if ($decoded->{'cmd'} eq 'report' && $decoded->{'model'} eq 'gateway' || $decoded->{'cmd'} eq 'heartbeat' && $decoded->{'model'} eq 'gateway' || $decoded->{'cmd'} eq 'write_ack'){
if ($decoded->{'sid'} ne $hash->{SID} ){
Log3 $name, 5, "$name: Reading> $decoded->{'sid'} not matching with my SID $hash->{SID} skipping $hash->{SID} TT";
return;
}
readingsBeginUpdate( $hash );
if ($decoded->{'model'} && $decoded->{'model'} eq 'gateway' ){
if ($decoded->{'cmd'} eq 'report'){
my $data = eval{decode_json($decoded->{data})};
if ($@) {
Log3 $name, 1, "$name: Reading> Error while request: $@";
return;
}
if (defined $data->{rgb}){
Log3 $name, 3, "$name: Reading>" . " SID: " . $decoded->{'sid'} . " Type: Gateway" . " RGB: " . $data->{rgb} ;
readingsBulkUpdate($hash, "RGB", $data->{rgb} , 1 );
}
if (defined $data->{illumination}){
Log3 $name, 3, "$name: Reading>" . " SID: " . $decoded->{'sid'} . " Type: Gateway" . " Illumination: " . $data->{illumination} ;
readingsBulkUpdate($hash, "illumination", $data->{illumination} , 1 );
}
}
elsif ($decoded->{'cmd'} eq 'heartbeat'){
my $data = eval{decode_json($decoded->{data})};
if ($@) {
Log3 $name, 1, "$name: Reading> Error while request: $@";
return;
}
if ($data->{ip} eq $hash->{GATEWAY_IP}){
readingsBulkUpdate($hash, 'heartbeat', $decoded->{'sid'}, 1 );
readingsBulkUpdate($hash, 'token', $decoded->{'token'}, 1 );
Log3 $name, 4, "$name: Reading> Heartbeat from $data->{ip} received with $decoded->{'sid'}";
#$hash->{SID} = $decoded->{'sid'};
}
else {
Log3 $name, 4, "$name: Reading> IP-Heartbeat Data didnt match! $data->{ip} " . $hash->{GATEWAY_IP} ;
}
}
}
if ($decoded->{'cmd'} eq 'write_ack'){
if ($decoded->{'sid'} ne $hash->{SID} ){
Log3 $name, 5, "$name: Reading> $decoded->{'sid'} not matching with my SID $hash->{SID} skipping";
return;
}
Log3 $name, 4, "$name: Reading> Write answer " . $hash->{GATEWAY} ;
my $data = eval{decode_json($decoded->{data})};
if ($@) {
Log3 $name, 1, "$name: Reading> Error while request: $@";
return;
}
if ($data->{error}){
readingsBulkUpdate($hash, 'heartbeat', $data->{error}, 1 );
}
else {
readingsBulkUpdate($hash, 'heartbeat', "Write_OK", 1 );
readingsBulkUpdate($hash, "proto_version", $data->{proto_version} , 1 );
}
}
readingsEndUpdate( $hash, 1 );
return;
}
elsif ($decoded->{'cmd'} eq 'get_id_list_ack'){
if ($decoded->{'sid'} ne $hash->{SID} ){ if ($decoded->{'sid'} ne $hash->{SID} ){
Log3 $name, 5, "$name: Read> $decoded->{'sid'} not matching with my SID $hash->{SID} skipping"; Log3 $name, 5, "$name: Reading> $decoded->{'sid'} not matching with my SID $hash->{SID} skipping $hash";
return; return;
} }
my @sensors = eval{ @{decode_json($decoded->{data})}}; my @sensors = eval{ @{decode_json($decoded->{data})}};
if ($@) { if ($@) {
Log3 $name, 1, "$name: Read> Error while request: $@"; Log3 $name, 1, "$name: Reading> Error while request: $@";
return; return;
} }
foreach my $sensor (@sensors) foreach my $sensor (@sensors)
{ {
Log3 $name, 4, "$name: Read> PushRead:" . $sensor; Log3 $name, 4, "$name: Reading> PushRead:" . $sensor;
XiaomiSmartHome_Write($hash, 'read', $sensor ); XiaomiSmartHome_Write($hash, 'read', $sensor );
} }
return; return;
} }
}
Log3 $name, 5, "$name: Read> Dispatch " . $buf; Log3 $name, 5, "$name: Reading> Dispatch " . $buf;
Dispatch($hash, $buf, undef); Dispatch($hash, $buf, undef);
}
} }
##################################### #####################################
@@ -253,6 +287,7 @@ sub XiaomiSmartHome_getGatewaySID($){
Log3 $name, 4, "$name: getGatewaySID> Find SID for Gateway: $decoded->{sid}"; Log3 $name, 4, "$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;
return $decoded->{sid}; return $decoded->{sid};
} }
else { else {
@@ -302,7 +337,7 @@ sub XiaomiSmartHome_Define($$) {
$hash->{helper}{JSON} = JSON->new->utf8(); $hash->{helper}{JSON} = JSON->new->utf8();
$hash->{FHEMIP} = XiaomiSmartHome_getLocalIP(); $hash->{FHEMIP} = XiaomiSmartHome_getLocalIP();
$hash->{STATE} = "initialized"; $hash->{STATE} = "initialized";
$hash->{helper}{host} = $definition; $hash->{helper}{host} = $definition;
if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){ if( $hash->{GATEWAY} !~ m/^\d+\.\d+\.\d+\.\d+$/ ){
eval { eval {
$GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ; $GATEWAY_IP = inet_ntoa(inet_aton($hash->{GATEWAY})) ;
@@ -317,6 +352,7 @@ sub XiaomiSmartHome_Define($$) {
} }
} }
$hash->{GATEWAY_IP} = $GATEWAY_IP; $hash->{GATEWAY_IP} = $GATEWAY_IP;
$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";
@@ -391,10 +427,18 @@ sub XiaomiSmartHome_Write($@)
{ {
$msg = '{"cmd":"write","model":"plug","sid":"' . $iohash->{SID} . '","data":"{\"status\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; $msg = '{"cmd":"write","model":"plug","sid":"' . $iohash->{SID} . '","data":"{\"status\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
} }
if ($cmd eq '86power')
{
$msg = '{"cmd":"write","model":"86plug","sid":"' . $iohash->{SID} . '","data":"{\"status\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
}
if ($cmd eq 'ctrl') if ($cmd eq 'ctrl')
{ {
$msg = '{"cmd":"write","model":"ctrl_neutral1","sid":"' . $iohash->{SID} . '","data":"{\"channel_0\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; $msg = '{"cmd":"write","model":"ctrl_neutral1","sid":"' . $iohash->{SID} . '","data":"{\"channel_0\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
} }
if ($cmd eq 'ctrl_ln1')
{
$msg = '{"cmd":"write","model":"ctrl_ln1","sid":"' . $iohash->{SID} . '","data":"{\"channel_0\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
}
if ($cmd eq 'channel_0') if ($cmd eq 'channel_0')
{ {
$msg = '{"cmd":"write","model":"ctrl_neutral2","sid":"' . $iohash->{SID} . '","data":"{\"channel_0\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; $msg = '{"cmd":"write","model":"ctrl_neutral2","sid":"' . $iohash->{SID} . '","data":"{\"channel_0\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
@@ -403,6 +447,14 @@ sub XiaomiSmartHome_Write($@)
{ {
$msg = '{"cmd":"write","model":"ctrl_neutral2","sid":"' . $iohash->{SID} . '","data":"{\"channel_1\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; $msg = '{"cmd":"write","model":"ctrl_neutral2","sid":"' . $iohash->{SID} . '","data":"{\"channel_1\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
} }
if ($cmd eq 'ctrl_ln2_0')
{
$msg = '{"cmd":"write","model":"ctrl_ln2","sid":"' . $iohash->{SID} . '","data":"{\"channel_0\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
}
if ($cmd eq 'ctrl_ln2_1')
{
$msg = '{"cmd":"write","model":"ctrl_ln2","sid":"' . $iohash->{SID} . '","data":"{\"channel_1\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
}
if ($cmd eq 'ringtone') if ($cmd eq 'ringtone')
{ {
my $vol = $hash->{READINGS}{volume}{VAL}; my $vol = $hash->{READINGS}{volume}{VAL};
@@ -413,6 +465,14 @@ sub XiaomiSmartHome_Write($@)
my $rt = $hash->{READINGS}{ringtone}{VAL}; my $rt = $hash->{READINGS}{ringtone}{VAL};
$msg = '{"cmd":"write","model":"gateway","sid":"' . $hash->{SID} . '","short_id":0,"key":"8","data":"{\"mid\":' . $rt . ',\"vol\":' .$val . ',\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }'; $msg = '{"cmd":"write","model":"gateway","sid":"' . $hash->{SID} . '","short_id":0,"key":"8","data":"{\"mid\":' . $rt . ',\"vol\":' .$val . ',\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
} }
if ($cmd eq 'status')
{
$msg = '{"cmd":"write","model":"curtain","sid":"' . $iohash->{SID} . '","data":"{\"status\":\"' . $val . '\",\"key\":\"'. XiaomiSmartHome_EncryptKey($hash) .'\"}" }';
}
if ($cmd eq 'level')
{
$msg = '{"cmd":"write","model":"curtain","sid":"' . $iohash->{SID} . '","data":"{\"curtain_level\":\"' . $val . '\",\"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});
@@ -800,13 +860,30 @@ sub XiaomiSmartHome_updateAllReadings($)
<li>motion: Human body motion sensor</li> <li>motion: Human body motion sensor</li>
<li>sensor_ht: Temperatur and humidity sensor</li> <li>sensor_ht: Temperatur 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>smoke: smoke alarm detector</li>
<ul>
<li>0: disarm</li>
<li>1: arlarm</li>
<li>8: battery arlarm</li>
<li>64: arlarm sensitivity</li>
<li>32768: ICC communication failure</li>
</ul>
<li>gas: gas alarm detector</li>
<ul>
<li>0: disarm</li>
<li>1: arlarm</li>
<li>2: analog arlarm</li>
<li>64: arlarm sensitivity</li>
<li>32768: ICC communication failure</li>
</ul>
</ul> </ul>
<br/> <br/>
<b>Heartbeat</b> <b>Heartbeat</b>
@@ -881,13 +958,30 @@ sub XiaomiSmartHome_updateAllReadings($)
<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: Schaltbare Funksteckdose</li> <li>plug & 86plug: Schaltbare Funksteckdose</li>
<li>cube: W&uumlrfel Sensor</li> <li>cube: W&uumlrfel 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>smoke: Rauchmelder</li>
<ul>
<li>0: disarm</li>
<li>1: arlarm</li>
<li>8: battery arlarm</li>
<li>64: arlarm sensitivity</li>
<li>32768: ICC communication failure</li>
</ul>
<li>gas: Gasmelder</li>
<ul>
<li>0: disarm</li>
<li>1: arlarm</li>
<li>2: analog arlarm</li>
<li>64: arlarm sensitivity</li>
<li>32768: ICC communication failure</li>
</ul>
</ul> </ul>
<br/> <br/>
<b>Heartbeat</b> <b>Heartbeat</b>

View File

@@ -25,7 +25,7 @@ package main;
use strict; use strict;
use warnings; use warnings;
my $version = "1.00"; my $version = "1.05";
sub XiaomiSmartHome_Device_updateSReading($); sub XiaomiSmartHome_Device_updateSReading($);
@@ -35,7 +35,7 @@ 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"; $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";
$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";
@@ -66,19 +66,25 @@ sub XiaomiSmartHome_Device_Set($@)
$setlist .= "motionOffTimer:1,5,10 " if ($hash->{MODEL} eq 'motion'); $setlist .= "motionOffTimer:1,5,10 " if ($hash->{MODEL} eq 'motion');
#$setlist = "open:noArg close:noArg " if ($hash->{MODEL} eq 'magnet'); #$setlist = "open:noArg close:noArg " if ($hash->{MODEL} eq 'magnet');
$setlist .= "power:on,off " if ($hash->{MODEL} eq 'plug'); $setlist .= "power:on,off " if ($hash->{MODEL} eq 'plug');
$setlist .= "power:on,off " if ($hash->{MODEL} eq '86plug');
$setlist .= "ctrl:on,off " if ($hash->{MODEL} eq 'ctrl_neutral1'); $setlist .= "ctrl:on,off " if ($hash->{MODEL} eq 'ctrl_neutral1');
$setlist .= "ctrl:on,off " if ($hash->{MODEL} eq 'ctrl_ln1');
$setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_neutral2'); $setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_neutral2');
$setlist .= "channel_0:on,off channel_1:on,off " if ($hash->{MODEL} eq 'ctrl_ln2');
$setlist .= "status:open,close,stop,auto level:slider,1,1,100 " if ($hash->{MODEL} eq 'curtain');
if($cmd eq "power") if($cmd eq "power")
{ {
if($args[0] eq "on") if($args[0] eq "on")
{ {
IOWrite($hash,"power","on",$hash); IOWrite($hash,"power","on",$hash) if ($hash->{MODEL} eq 'plug');
IOWrite($hash,"86power","on",$hash) if ($hash->{MODEL} eq '86plug');
return; return;
} }
elsif($args[0] eq "off") elsif($args[0] eq "off")
{ {
IOWrite($hash,"power","off",$hash); IOWrite($hash,"power","off",$hash) if ($hash->{MODEL} eq 'plug');
IOWrite($hash,"86power","off",$hash) if ($hash->{MODEL} eq '86plug');
return; return;
} }
} }
@@ -86,12 +92,14 @@ sub XiaomiSmartHome_Device_Set($@)
{ {
if($args[0] eq "on") if($args[0] eq "on")
{ {
IOWrite($hash,"ctrl","on",$hash); IOWrite($hash,"ctrl","on",$hash) if ($hash->{MODEL} eq 'ctrl_neutral1');
IOWrite($hash,"ctrl_ln1","on",$hash) if ($hash->{MODEL} eq 'ctrl_ln1');
return; return;
} }
elsif($args[0] eq "off") elsif($args[0] eq "off")
{ {
IOWrite($hash,"ctrl","off",$hash); IOWrite($hash,"ctrl","off",$hash) if ($hash->{MODEL} eq 'ctrl_neutral1');
IOWrite($hash,"ctrl_ln1","off",$hash) if ($hash->{MODEL} eq 'ctrl_ln1');
return; return;
} }
} }
@@ -99,12 +107,14 @@ sub XiaomiSmartHome_Device_Set($@)
{ {
if($args[0] eq "on") if($args[0] eq "on")
{ {
IOWrite($hash,"channel_0","on",$hash); IOWrite($hash,"channel_0","on",$hash) if ($hash->{MODEL} eq 'ctrl_neutral2');
IOWrite($hash,"ctrl_ln2_0","on",$hash) if ($hash->{MODEL} eq 'ctrl_ln2');
return; return;
} }
elsif($args[0] eq "off") elsif($args[0] eq "off")
{ {
IOWrite($hash,"channel_0","off",$hash); IOWrite($hash,"channel_0","off",$hash) if ($hash->{MODEL} eq 'ctrl_neutral2');
IOWrite($hash,"ctrl_ln2_0","off",$hash) if ($hash->{MODEL} eq 'ctrl_ln2');
return; return;
} }
} }
@@ -112,15 +122,45 @@ sub XiaomiSmartHome_Device_Set($@)
{ {
if($args[0] eq "on") if($args[0] eq "on")
{ {
IOWrite($hash,"channel_1","on",$hash); IOWrite($hash,"channel_1","on",$hash) if ($hash->{MODEL} eq 'ctrl_neutral2');
IOWrite($hash,"ctrl_ln2_1","on",$hash) if ($hash->{MODEL} eq 'ctrl_ln2');
return; return;
} }
elsif($args[0] eq "off") elsif($args[0] eq "off")
{ {
IOWrite($hash,"channel_1","off",$hash); IOWrite($hash,"channel_1","off",$hash) if ($hash->{MODEL} eq 'ctrl_neutral2');
IOWrite($hash,"ctrl_ln2_1","off",$hash) if ($hash->{MODEL} eq 'ctrl_ln2');
return; return;
} }
} }
if($cmd eq "status")
{
if($args[0] eq "open")
{
IOWrite($hash,"status","open",$hash) ;
return;
}
elsif($args[0] eq "close")
{
IOWrite($hash,"status","close",$hash) ;
return;
}
elsif($args[0] eq "stop")
{
IOWrite($hash,"status","stop",$hash) ;
return;
}
elsif($args[0] eq "auto")
{
IOWrite($hash,"status","auto",$hash) ;
return;
}
}
if($cmd eq "level")
{
IOWrite($hash,"level", $args[0] ,$hash) ;
return;
}
# if($cmd eq "open") # if($cmd eq "open")
# { # {
# readingsSingleUpdate($hash, "state", "open", 1 ); # readingsSingleUpdate($hash, "state", "open", 1 );
@@ -209,7 +249,7 @@ sub XiaomiSmartHome_Device_Read($$$){
readingsBulkUpdate($hash, "channel_1", "$data->{channel_1}", 1 ); readingsBulkUpdate($hash, "channel_1", "$data->{channel_1}", 1 );
} }
#86sw1 + 86sw2 + ctrl_neutral1 + ctrl_neutral2 end #86sw1 + 86sw2 + ctrl_neutral1 + ctrl_neutral2 end
#plug start #plug & 86plug start
if (defined $data->{load_voltage}){ if (defined $data->{load_voltage}){
Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " LOAD_Voltage: " . $data->{load_voltage}; Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " LOAD_Voltage: " . $data->{load_voltage};
readingsBulkUpdate($hash, "LOAD_Voltage", "$data->{load_voltage}", 1 ); readingsBulkUpdate($hash, "LOAD_Voltage", "$data->{load_voltage}", 1 );
@@ -226,7 +266,7 @@ sub XiaomiSmartHome_Device_Read($$$){
Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " InUse: " . $data->{inuse}; Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " InUse: " . $data->{inuse};
readingsBulkUpdate($hash, "inuse", "$data->{inuse}", 1 ); readingsBulkUpdate($hash, "inuse", "$data->{inuse}", 1 );
} }
#plug end #plug & 86plug end
#rgbw_light start #rgbw_light start
if (defined $data->{level}){ if (defined $data->{level}){
Log3 $name, 3, "$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} . " Level: " . $data->{level};
@@ -260,6 +300,18 @@ sub XiaomiSmartHome_Device_Read($$$){
readingsBulkUpdate($hash, "state", "rotate", 1 ); readingsBulkUpdate($hash, "state", "rotate", 1 );
} }
#cube end #cube end
#smoke & natgast start
if (defined $data->{alarm}){
Log3 $name, 3, "$name: DEV_Read>" . " Name: " . $hash->{NAME} . " SID: " . $sid . " Type: " . $hash->{MODEL} . " Rotate: " . $data->{arlarm};
readingsBulkUpdate($hash, "arlarm", "$data->{arlarm}", 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} . " Rotate: " . $data->{curtain_level};
readingsBulkUpdate($hash, "arlarm", "$data->{curtain_level}", 1 );
}
#curtain end
if ($decoded->{'cmd'} eq 'heartbeat'){ if ($decoded->{'cmd'} eq 'heartbeat'){
readingsBulkUpdate($hash, 'heartbeat', $decoded->{'sid'} , 1 ); readingsBulkUpdate($hash, 'heartbeat', $decoded->{'sid'} , 1 );
} }
@@ -280,10 +332,10 @@ sub XiaomiSmartHome_Device_Parse($$) {
} }
my $sid = $decoded->{'sid'}; my $sid = $decoded->{'sid'};
my $model = $decoded->{'model'}; my $model = $decoded->{'model'};
if (my $io_hash = $modules{XiaomiSmartHome_Device}{defptr}{$sid}) if (my $hash = $modules{XiaomiSmartHome_Device}{defptr}{$sid})
{ {
Log3 $name, 4, "$name: DEV_Parse> IS DEFINED " . $model . " : " .$sid; Log3 $name, 4, "$name: DEV_Parse> IS DEFINED " . $model . " : " .$sid;
XiaomiSmartHome_Device_Read($io_hash, $msg, $name); XiaomiSmartHome_Device_Read($hash, $msg, $name);
} }
else else
{ {

View File

@@ -1,6 +1,6 @@
# 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. 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.
Changing and switching the led of the gateway is now also possible. Changing and switching the led of 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

View File

@@ -1,2 +1,2 @@
UPD 2017-05-28_09:43:07 32000 FHEM/71_XiaomiSmartHome.pm UPD 2017-06-15_17:31:21 36080 FHEM/71_XiaomiSmartHome.pm
UPD 2017-05-18_11:38:12 21164 FHEM/71_XiaomiSmartHome_Device.pm UPD 2017-06-13_10:28:27 23503 FHEM/71_XiaomiSmartHome_Device.pm