diff --git a/fhem/CHANGED b/fhem/CHANGED index 1c7a55667..71b00850f 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 72_XiaomiDevice: New fan types 1C / P9 - bugfix: 59_Twilight: show dependencies to global lon/lat settings - bugfix: 32_withings: remove invalid meastype in userReadingsActivity call - bugfix: 73_AutoShuttersControl: add feature isNotDay and all condition for diff --git a/fhem/FHEM/72_XiaomiDevice.pm b/fhem/FHEM/72_XiaomiDevice.pm index cbfe0442d..d299e886f 100755 --- a/fhem/FHEM/72_XiaomiDevice.pm +++ b/fhem/FHEM/72_XiaomiDevice.pm @@ -141,7 +141,7 @@ sub XiaomiDevice_Initialize($) { $hash->{WriteFn} = "XiaomiDevice_Write"; $hash->{DbLog_splitFn}= "XiaomiDevice_DbLog_splitFn"; $hash->{AttrFn} = "XiaomiDevice_Attr"; - $hash->{AttrList} = "subType:AirPurifier,AirPurifier3H,Humidifier,EvpHumidifier,HumidifierMJJSQ,VacuumCleaner,SmartFan,SmartFan1X,SmartLamp,EyeCare,WaterPurifier,Camera,RiceCooker,PowerPlug intervalData intervalSettings preset disable:0,1 zone_names point_names map_names segment_names ". + $hash->{AttrList} = "subType:AirPurifier,AirPurifier3H,Humidifier,EvpHumidifier,HumidifierMJJSQ,VacuumCleaner,SmartFan,SmartFan1X,SmartFan1C,TowerFanP9,SmartLamp,EyeCare,WaterPurifier,Camera,RiceCooker,PowerPlug intervalData intervalSettings preset disable:0,1 zone_names point_names map_names segment_names ". $readingFnAttributes; } @@ -306,6 +306,8 @@ sub XiaomiDevice_Define($$$) { $attr{$name}{stateFormat} = "power" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "HumidifierMJJSQ" && !defined($attr{$name}{stateFormat})); $attr{$name}{stateFormat} = "mode level%" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan" && !defined($attr{$name}{stateFormat})); $attr{$name}{stateFormat} = "mode level%" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1X" && !defined($attr{$name}{stateFormat})); + $attr{$name}{stateFormat} = "mode level%" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C" && !defined($attr{$name}{stateFormat})); + $attr{$name}{stateFormat} = "mode level%" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9" && !defined($attr{$name}{stateFormat})); $attr{$name}{stateFormat} = "state" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartLamp" && !defined($attr{$name}{stateFormat})); $attr{$name}{stateFormat} = "power" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "EyeCare" && !defined($attr{$name}{stateFormat})); $attr{$name}{stateFormat} = "power" if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "WaterPurifier" && !defined($attr{$name}{stateFormat})); @@ -550,7 +552,7 @@ sub XiaomiDevice_Set($$@) { $list .= " on:noArg off:noArg mode:auto,idle,silent,favorite favorite:slider,0,1,16 preset:noArg save:noArg restore:noArg buzzer:on,off led:bright,dim,off turbo:on,off child_lock:on,off sleep_time sleep_auto:close,single"; } elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "AirPurifier3H"){ - $list .= " on:noArg off:noArg mode:auto,fan,silent,favorite favorite:slider,0,1,14 fan_level:1,2,3 buzzer:on,off led:bright,dim,off child_lock:on,off"; + $list .= " on:noArg off:noArg mode:auto,fan,silent,favorite favorite:slider,0,1,14 level:slider,0,1,3 buzzer:on,off led:bright,dim,off child_lock:on,off"; } elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "Humidifier"){ $list .= " on:noArg off:noArg mode:idle,silent,medium,high buzzer:on,off led:bright,dim,off child_lock:on,off limit_hum:slider,30,1,80"; @@ -567,6 +569,12 @@ sub XiaomiDevice_Set($$@) { elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1X"){ $list .= " on:noArg off:noArg timed_off mode:straight,natural level:slider,0,1,100 angle:30,60,90,120,140 angle_enable:on,off move:left,right buzzer:on,off led:on,off child_lock:on,off"; } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C"){ + $list .= " on:noArg off:noArg timed_off mode:straight,sleep level:slider,0,1,3 angle_enable:on,off buzzer:on,off led:on,off child_lock:on,off"; + } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9"){ + $list .= " on:noArg off:noArg timed_off mode:straight,natural,sleep level:slider,0,1,100 angle:30,60,90,120,150 angle_enable:on,off move:left,right buzzer:on,off led:on,off child_lock:on,off"; + } elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartLamp"){ $list .= " on:noArg off:noArg toggle:noArg brightness:slider,0,1,100 timed_off save:noArg"; $list .= " ct:slider,2700,190,6500" if(defined(ReadingsVal($name,"ct",undef))); @@ -782,6 +790,17 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"m_roll","params":["'.$arg[0].'"]}' ); return undef; } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + return "Usage: move [left/right]" if(!defined($arg[0])); + my $packetid = $hash->{helper}{packetid}; + $hash->{helper}{packetid} = $packetid+1; + $hash->{helper}{packet}{$packetid} = "move"; + my $cmd_set = $arg[0] eq 'left' ? '2' : $arg[0] eq 'right' ? '2' :'0'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "mode", "siid": 2, "piid": 10, "value": '.$cmd_set.'}]}' ); + InternalTimer( gettimeofday() + 10, "XiaomiDevice_GetSettings", $hash); + return undef; + } return "Usage: move [direction -100..100] [velocity 0..100] [time ms]" if(!defined($arg[0]) || !defined($arg[1])); if($hash->{helper}{rc_seq} == 0) { my $packetid = $hash->{helper}{packetid}; @@ -1321,6 +1340,18 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_power","params":['.($cmd eq "on" ? 'true' : 'false').']}' ); return undef; } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $cmd_set = $cmd eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "power", "siid": 2, "piid": 1, "value": '.$cmd_set.'}]}' ); + return undef; + } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $cmd_set = $cmd eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "power", "siid": 2, "piid": 1, "value": '.$cmd_set.'}]}' ); + return undef; + } XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_power","params":["'.$cmd.'"]}' ); InternalTimer( gettimeofday() + 10, "XiaomiDevice_GetSpeed", $hash); } @@ -1510,6 +1541,21 @@ sub XiaomiDevice_Set($$@) { return undef; } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $cmd_set = $arg[0] eq 'straight' ? '0' : '1'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "mode", "siid": 2, "piid": 7, "value": '.$cmd_set.'}]}' ); + InternalTimer( gettimeofday() + 10, "XiaomiDevice_GetSettings", $hash); + return undef; + } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $cmd_set = $arg[0] eq 'straight' ? '0' : $arg[0] eq 'natural' ? '1' :'2'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "mode", "siid": 2, "piid": 4, "value": '.$cmd_set.'}]}' ); + InternalTimer( gettimeofday() + 10, "XiaomiDevice_GetSettings", $hash); + return undef; + } + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_mode","params":["'.$arg[0].'"]}' ); if($arg[0] eq "favorite" && defined($arg[1])) { my $level = int($arg[1]); @@ -1559,6 +1605,11 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_angle","params":['.$arg[0].']}' ); return undef; } + if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "angle_enable", "siid": 2, "piid": 6, "value": '.$arg[0].'}]}' ); + return undef; + } XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_angle","params":['.$arg[0].']}' ); } elsif ($cmd eq 'angle_enable') @@ -1571,6 +1622,18 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_roll","params":['.($arg[0] eq "on" ? "true" : "false").']}' ); return undef; } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $cmd_boolean = $arg[0] eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "angle_enable", "siid": 2, "piid": 3, "value": '.$cmd_boolean.'}]}' ); + return undef; + } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $cmd_boolean = $arg[0] eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "angle_enable", "siid": 2, "piid": 5, "value": '.$cmd_boolean.'}]}' ); + return undef; + } XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_angle_enable","params":["'.$arg[0].'"]}' ); } elsif ($cmd eq 'level') @@ -1580,19 +1643,50 @@ sub XiaomiDevice_Set($$@) { $hash->{helper}{packet}{$packetid} = "set_level"; if(int($arg[0])<1) { - if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1X") + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "AirPurifier3H") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "power", "siid": 2, "piid": 2, "value": false}]}' ); + } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1X") { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_power","params":[false]}' ); } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "power", "siid": 2, "piid": 1, "value": false}]}' ); + } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "power", "siid": 2, "piid": 1, "value": false}]}' ); + } else { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_power","params":["off"]}' ); } } else { - if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1X") + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "AirPurifier3H") + { + my $cmd_value = $arg[0]; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "level", "siid": 2, "piid": 4, "value": '.$cmd_value.'}]}' ); + InternalTimer( gettimeofday() + 2, "XiaomiDevice_GetUpdate", $hash); + return undef; + } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1X") { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_speed","params":['.$arg[0].']}' ); - } else { + } + elsif (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $cmd_value = $arg[0] eq 'low' ? '1' : $arg[0] eq 'medium' ? '2' : $arg[0] eq 'high' ? '3' : $arg[0]; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "fan_level", "siid": 2, "piid": 2, "value": '.$cmd_value.'}]}' ); + return undef; + } + elsif (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "level", "siid": 2, "piid": 11, "value": '.$arg[0].'}]}' ); + return undef; + } + else { my $mode = (ReadingsVal($name, "mode", "natural") eq "natural")?"natural":"speed"; XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_'.$mode.'_level","params":['.$arg[0].']}' ); } @@ -1620,6 +1714,18 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_t_off","params":['.$arg[0].']}' ); return undef; } + if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "timed_off", "siid": 2, "piid": 10, "value": '.$arg[0].'}]}' ); + InternalTimer( gettimeofday() + 10, "XiaomiDevice_GetSettings", $hash); + return undef; + } + if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "timed_off", "siid": 2, "piid": 8, "value": '.$arg[0].'}]}' ); + InternalTimer( gettimeofday() + 10, "XiaomiDevice_GetSettings", $hash); + return undef; + } XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_poweroff_time","params":['.$arg[0].']}' ); } elsif ($cmd eq 'buzzer') @@ -1644,6 +1750,18 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_sound","params":['.($arg[0] eq "off" ? 'false' : 'true' ).']}' ); return undef; } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $cmd_boolean = $arg[0] eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "buzzer", "siid": 2, "piid": 11, "value": '.$cmd_boolean.'}]}' ); + return undef; + } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $cmd_boolean = $arg[0] eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "buzzer", "siid": 2, "piid": 7, "value": '.$cmd_boolean.'}]}' ); + return undef; + } if(defined($hash->{model}) && $hash->{model} eq "zhimi.fan.za4") { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_buzzer","params":['.($arg[0] eq "off" ? '0' : '2' ).']}' ); @@ -1679,22 +1797,23 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_light","params":['.($arg[0] eq "off" ? 'false' : 'true' ).']}' ); return undef; } - XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_led_b","params":['.($arg[0] eq "bright" ? '0' : $arg[0] eq "dim" ? '1' : '2' ).']}' ); - } - elsif ($cmd eq 'fan_level') - { - my $packetid = $hash->{helper}{packetid}; - $hash->{helper}{packetid} = $packetid+1; - - if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "AirPurifier3H") + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") { - my $cmd_value = $arg[0]; - XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "fan_level", "siid": 2, "piid": 4, "value": '.$cmd_value.'}]}' ); - InternalTimer( gettimeofday() + 2, "XiaomiDevice_GetUpdate", $hash); + my $cmd_value = $arg[0] eq 'on' ? 'true' : $arg[0] eq 'bright' ? 'true' : $arg[0] eq 'dim' ? 'false' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "led_brightness", "siid": 2, "piid": 12, "value": '.$cmd_value.'}]}' ); + #InternalTimer( gettimeofday() + 2, "XiaomiDevice_GetSettings", $hash); return undef; } - + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $cmd_value = $arg[0] eq 'on' ? 'true' : $arg[0] eq 'bright' ? 'true' : $arg[0] eq 'dim' ? 'false' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "led_brightness", "siid": 2, "piid": 9, "value": '.$cmd_value.'}]}' ); + #InternalTimer( gettimeofday() + 2, "XiaomiDevice_GetSettings", $hash); + return undef; + } + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_led_b","params":['.($arg[0] eq "bright" ? '0' : $arg[0] eq "dim" ? '1' : '2' ).']}' ); } + elsif ($cmd eq 'turbo') { my $packetid = $hash->{helper}{packetid}; @@ -1720,6 +1839,18 @@ sub XiaomiDevice_Set($$@) { XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"s_lock","params":['.($arg[0] eq "off" ? 'false' : 'true' ).']}' ); return undef; } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $cmd_boolean = $arg[0] eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "child_lock", "siid": 3, "piid": 1, "value": '.$cmd_boolean.'}]}' ); + return undef; + } + if (defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $cmd_boolean = $arg[0] eq 'on' ? 'true' : 'false'; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_properties","params":[{"did": "child_lock", "siid": 3, "piid": 1, "value": '.$cmd_boolean.'}]}' ); + return undef; + } XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"set_child_lock","params":["'.$arg[0].'"]}' ); } elsif ($cmd eq 'kid_mode') @@ -1971,7 +2102,7 @@ sub XiaomiDevice_GetUpdate($) elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "AirPurifier3H") { $hash->{helper}{packet}{$packetid} = "air_data_3H"; - XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 2}, {"did": "fan_level", "siid": 2, "piid": 4}, {"did": "mode", "siid": 2, "piid": 5}, {"did": "humidity", "siid": 3, "piid": 7}, {"did": "temperature", "siid": 3, "piid": 8}, {"did": "aqi", "siid": 3, "piid": 6}, {"did": "filter_life_remaining", "siid": 4, "piid": 3}, {"did": "purify_volume", "siid": 13, "piid": 1}, {"did": "filter_hours_used", "siid": 4, "piid": 5}, {"did": "favorite_level", "siid": 10, "piid": 10}, {"did": "favorite_rpm", "siid": 10, "piid": 7},{"did": "motor_speed", "siid": 10, "piid": 8}, {"did": "use_time", "siid": 12, "piid": 1},{"did": "average_aqi", "siid": 13, "piid": 2}]}'); + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 2}, {"did": "level", "siid": 2, "piid": 4}, {"did": "mode", "siid": 2, "piid": 5}, {"did": "humidity", "siid": 3, "piid": 7}, {"did": "temperature", "siid": 3, "piid": 8}, {"did": "aqi", "siid": 3, "piid": 6}, {"did": "filter_life_remaining", "siid": 4, "piid": 3}, {"did": "purify_volume", "siid": 13, "piid": 1}, {"did": "filter_hours_used", "siid": 4, "piid": 5}, {"did": "favorite_level", "siid": 10, "piid": 10}, {"did": "favorite_rpm", "siid": 10, "piid": 7},{"did": "motor_speed", "siid": 10, "piid": 8}, {"did": "use_time", "siid": 12, "piid": 1},{"did": "average_aqi", "siid": 13, "piid": 2}]}'); } elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "Humidifier") { @@ -1998,6 +2129,16 @@ sub XiaomiDevice_GetUpdate($) $hash->{helper}{packet}{$packetid} = "fan_data_1x"; XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_prop","params":["power","mode","speed","roll_enable","roll_angle","time_off","light","beep_sound","child_lock"]}' ); } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + $hash->{helper}{packet}{$packetid} = "fan_data_1C"; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 1}, {"did": "level", "siid": 2, "piid": 2}, {"did": "mode", "siid": 2, "piid": 7}, {"did": "led", "siid": 2, "piid": 12}, {"did": "buzzer", "siid": 2, "piid": 11}, {"did": "angle_enable", "siid": 2, "piid": 3}, {"did": "child_lock", "siid": 3, "piid": 1}, {"did": "timed_off", "siid": 2, "piid": 10}]}'); + } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + $hash->{helper}{packet}{$packetid} = "fan_data_P9"; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 1}, {"did": "level", "siid": 2, "piid": 11}, {"did": "mode", "siid": 2, "piid": 4}, {"did": "led", "siid": 2, "piid": 12}, {"did": "buzzer", "siid": 2, "piid": 7}, {"did": "angle_enable", "siid": 2, "piid": 5}, {"did": "child_lock", "siid": 3, "piid": 1}, {"did": "timed_off", "siid": 2, "piid": 8}, {"did": "angle", "siid": 2, "piid": 6}]}'); + } elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartLamp") { $hash->{helper}{packet}{$packetid} = "lamp_data"; @@ -2101,6 +2242,22 @@ sub XiaomiDevice_GetSettings($) return XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_prop","params":["power","mode","speed","roll_enable","roll_angle","time_off","light","beep_sound","child_lock"]}' ); } + if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + my $packetid = $hash->{helper}{packetid}; + $hash->{helper}{packetid} = $packetid+1; + $hash->{helper}{packet}{$packetid} = "fan_data_1C"; + return XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 1}, {"did": "level", "siid": 2, "piid": 2}, {"did": "mode", "siid": 2, "piid": 7}, {"did": "led", "siid": 2, "piid": 12}, {"did": "buzzer", "siid": 2, "piid": 11}, {"did": "angle_enable", "siid": 2, "piid": 3}, {"did": "child_lock", "siid": 3, "piid": 1}, {"did": "timed_off", "siid": 2, "piid": 10}]}'); + } + + if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + my $packetid = $hash->{helper}{packetid}; + $hash->{helper}{packetid} = $packetid+1; + $hash->{helper}{packet}{$packetid} = "fan_data_P9"; + return XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 1}, {"did": "level", "siid": 2, "piid": 11}, {"did": "mode", "siid": 2, "piid": 4}, {"did": "led", "siid": 2, "piid": 12}, {"did": "buzzer", "siid": 2, "piid": 7}, {"did": "angle_enable", "siid": 2, "piid": 5}, {"did": "child_lock", "siid": 3, "piid": 1}, {"did": "timed_off", "siid": 2, "piid": 8}, {"did": "angle", "siid": 2, "piid": 6}]}'); + } + if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartLamp") { my $packetid = $hash->{helper}{packetid}; @@ -2208,6 +2365,7 @@ sub XiaomiDevice_GetDeviceDetails($) XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"miIO.wifi_assoc_state","params":[""]}' ); return undef if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} ne "VacuumCleaner"); + return undef if(!defined($hash->{model})); $packetid = $hash->{helper}{packetid}; $hash->{helper}{packetid} = $packetid+1; @@ -2273,6 +2431,16 @@ sub XiaomiDevice_GetSpeed($) $hash->{helper}{packet}{$packetid} = "fan_status_1x"; XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_prop","params":["power","mode","speed"]}' ); } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartFan1C") + { + $hash->{helper}{packet}{$packetid} = "fan_data_1C"; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 1}, {"did": "level", "siid": 2, "piid": 2}, {"did": "mode", "siid": 2, "piid": 7}, {"did": "led", "siid": 2, "piid": 12}, {"did": "buzzer", "siid": 2, "piid": 11}, {"did": "angle_enable", "siid": 2, "piid": 3}, {"did": "child_lock", "siid": 3, "piid": 1}, {"did": "timed_off", "siid": 2, "piid": 10}]}'); + } + elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "TowerFanP9") + { + $hash->{helper}{packet}{$packetid} = "fan_data_P9"; + XiaomiDevice_WriteJSON($hash, '{"id":'.$packetid.',"method":"get_properties","params":[{"did": "power", "siid": 2, "piid": 1}, {"did": "level", "siid": 2, "piid": 11}, {"did": "mode", "siid": 2, "piid": 4}, {"did": "led", "siid": 2, "piid": 12}, {"did": "buzzer", "siid": 2, "piid": 7}, {"did": "angle_enable", "siid": 2, "piid": 5}, {"did": "child_lock", "siid": 3, "piid": 1}, {"did": "timed_off", "siid": 2, "piid": 8}, {"did": "angle", "siid": 2, "piid": 6}]}'); + } elsif( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartLamp") { $hash->{helper}{packet}{$packetid} = "lamp_status"; @@ -2315,6 +2483,14 @@ sub XiaomiDevice_WriteJSON($$) return undef; } + #if( defined($attr{$name}) && defined($attr{$name}{subType}) && $attr{$name}{subType} eq "SmartLamp") + #{ + # $json =~ /"id":(.*),"method"/; + # my $msgid = $1; + # my $msgtype = $hash->{helper}{packet}{$msgid}; + # Log3 $name, 2, "$name: Message type for ID $msgid is $msgtype >"; + #} + XiaomiDevice_initSend($hash) if(!defined($hash->{helper}{last_read}) || $hash->{helper}{last_read} < (int(time())-180) ); @@ -2389,7 +2565,7 @@ sub XiaomiDevice_ParseJSON($$) if(!defined($msgtype)) { Log3 $name, 2, "$name: Message type for ID $msgid not found"; - Log3 $name, 3, "$name: ".Dumper($json); + Log3 $name, 4, "$name: ".Dumper($json); return undef; } @@ -2414,7 +2590,8 @@ sub XiaomiDevice_ParseJSON($$) if(!$msgtype) { - Log3 $name, 2, "$name: message type for id ".$json->{id}." not found!\n".Dumper($json); + Log3 $name, 2, "$name: Message type for ID ".$json->{id}." not found"; + Log3 $name, 4, "$name: ".Dumper($json); return undef; } @@ -2489,7 +2666,7 @@ sub XiaomiDevice_ParseJSON($$) return undef if(ref($json->{result}) ne "ARRAY"); readingsBeginUpdate($hash); readingsBulkUpdate( $hash, "power", (($json->{result}[0]{value} eq "false" || $json->{result}[0]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[0]{value})); - readingsBulkUpdate( $hash, "fan_level", $json->{result}[1]{value}, 1 ) if(defined($json->{result}[1]{value})); + readingsBulkUpdate( $hash, "level", $json->{result}[1]{value}, 1 ) if(defined($json->{result}[1]{value})); readingsBulkUpdate( $hash, "mode", ($json->{result}[2]{value} eq "0" ? 'auto' : $json->{result}[2]{value} eq "1" ? 'silent' : $json->{result}[2]{value} eq "2" ? 'favorite' : 'fan'), 1 ) if(defined($json->{result}[2]{value})); readingsBulkUpdate( $hash, "humidity", $json->{result}[3]{value}, 1 ) if(defined($json->{result}[3]{value})); readingsBulkUpdate( $hash, "temperature", $json->{result}[4]{value}, 1 ) if(defined($json->{result}[4]{value})); @@ -2793,6 +2970,41 @@ sub XiaomiDevice_ParseJSON($$) readingsEndUpdate($hash,1); return undef; } + if ($msgtype eq "fan_data_1C") + { + return undef if(!defined($json->{result})); + return undef if(ref($json->{result}) ne "ARRAY"); + readingsBeginUpdate($hash); + readingsBulkUpdate( $hash, "power", (($json->{result}[0]{value} eq "false" || $json->{result}[0]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[0]{value})); + readingsBulkUpdate( $hash, "level", ($json->{result}[1]{value} eq "0" ? '0' : $json->{result}[1]{value} eq "1" ? '1' : $json->{result}[1]{value} eq "2" ? '2' : '3'), 1 ) if(defined($json->{result}[1]{value})); + readingsBulkUpdate( $hash, "mode", ($json->{result}[2]{value} eq "0" ? 'straight' : $json->{result}[2]{value} eq "1" ? 'sleep' : 'auto'), 1 ) if(defined($json->{result}[2]{value})); + readingsBulkUpdate( $hash, "led", (($json->{result}[3]{value} eq "false" || $json->{result}[3]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[3]{value})); + readingsBulkUpdate( $hash, "buzzer", (($json->{result}[4]{value} eq "false" || $json->{result}[4]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[4]{value})); + readingsBulkUpdate( $hash, "angle_enable", (($json->{result}[5]{value} eq "false" || $json->{result}[5]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[5]{value})); + readingsBulkUpdate( $hash, "child_lock", (($json->{result}[6]{value} eq "false" || $json->{result}[6]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[6]{value})); + readingsBulkUpdate( $hash, "timed_off", $json->{result}[7]{value} ) if(defined($json->{result}[7]{value})); + readingsEndUpdate($hash,1); + return undef; + } + if ($msgtype eq "fan_data_P9") + { + return undef if(!defined($json->{result})); + return undef if(ref($json->{result}) ne "ARRAY"); + readingsBeginUpdate($hash); + readingsBulkUpdate( $hash, "power", (($json->{result}[0]{value} eq "false" || $json->{result}[0]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[0]{value})); + readingsBulkUpdate( $hash, "level", $json->{result}[1]{value} ) if(defined($json->{result}[1]{value})); + readingsBulkUpdate( $hash, "mode", ($json->{result}[2]{value} eq "0" ? 'straight' : $json->{result}[2]{value} eq "1" ? 'natural' : 'sleep'), 1 ) if(defined($json->{result}[2]{value})); + readingsBulkUpdate( $hash, "led", (($json->{result}[3]{value} eq "false" || $json->{result}[3]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[3]{value})); + readingsBulkUpdate( $hash, "buzzer", (($json->{result}[4]{value} eq "false" || $json->{result}[4]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[4]{value})); + readingsBulkUpdate( $hash, "angle_enable", (($json->{result}[5]{value} eq "false" || $json->{result}[5]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[5]{value})); + readingsBulkUpdate( $hash, "child_lock", (($json->{result}[6]{value} eq "false" || $json->{result}[6]{value} eq "0") ? 'off' : 'on'), 1 ) if(defined($json->{result}[6]{value})); + readingsBulkUpdate( $hash, "timed_off", $json->{result}[7]{value} ) if(defined($json->{result}[7]{value})); + readingsBulkUpdate( $hash, "angle", $json->{result}[8]{value} ) if(defined($json->{result}[8]{value})); + readingsEndUpdate($hash,1); + return undef; + } + + if($msgtype eq "fan_status") { return undef if(!defined($json->{result})); @@ -3247,6 +3459,7 @@ sub XiaomiDevice_ParseJSON($$) { return undef if(!defined($json->{result})); return undef if(ref($json->{result}) ne "ARRAY"); + return undef if(ref($json->{result}[0]) ne "HASH"); readingsSingleUpdate( $hash, "log_upload_status", $json->{result}[0]{log_upload_status}, 1 ) if(defined($json->{result}[0]{log_upload_status})); return undef; } @@ -3737,7 +3950,7 @@ sub XiaomiDevice_DbLog_splitFn($) {
move
direction velocity [time] (VacuumCleaner)
+ move
direction velocity [time] or left/right (VacuumCleaner/Fan)
on / off
(AirPurifier/Humidifier)
+ on / off
(AirPurifier/Humidifier/Fan)
mode
(AirPurifier/EvpHumidifier)
+ mode
(AirPurifier/Humidifier/Fan)
favorite
(AirPurifier)
buzzer
(AirPurifier/EvpHumidifier)
+ buzzer
(AirPurifier/Humidifier/Fan)
led
(AirPurifier/EvpHumidifier)
+ led
(AirPurifier/Humidifier/Fan)
child_lock
(AirPurifier/EvpHumidifier)
+ child_lock
(AirPurifier/Humidifier/Fan)
limit_hum
(Humidifier/EvpHumidifier)
+ limit_hum
(Humidifier)
dry
(EvpHumidifier)
+ dry
(Humidifier)
temperature
(AirPurifier/EvpHumidifier)
+ temperature
(AirPurifier/Humidifier/Fan)
humidity
(AirPurifier/EvpHumidifier)
+ humidity
(AirPurifier/Humidifier/Fan)
speed
(AirPurifier/EvpHumidifier)
+ speed
(AirPurifier/Humidifier/Fan)
limit_hum
(EvpHumidifier)
+ limit_hum
(Humidifier)
dry
(EvpHumidifier)
+ dry
(Humidifier)
depth
(EvpHumidifier)
+ depth
(Humidifier)
subType
disable