Page 1 of 5

Xiaomi Air Purifier 2

Posted: Wednesday 18 January 2017 18:55
by ben53252642
The Xiaomi Air Purifier 2 now works with Domoticz for Linux (Ubuntu, Debian Raspberry Pi). Below is the setup, requires moderate Linux knowledge.

1) Requirements: apt-get install npm sudo screen

2) Install miIO Device Library: npm install --save miio

3) Install miio command line utility: npm install -g miio

4) Run this command to discover and sync the key from your Air Purifier: miio --discover --sync

airpurifier.js:

Code: Select all

#!/usr/bin/node
/* eslint-disable */

// Set path to node modules miio
const miio = require('miio');

// No need to change any lines in this section
var deviceip = process.argv[2];
var secondarg = process.argv[3];
var thirdarg = process.argv[4];
function exit() {
process.exit(-1);
}

// Power On (on / off specified as true or false)
if ( secondarg === "power" ) {
        setTimeout(exit, 7000);
        console.log('Sending Power', thirdarg, 'command');
        miio.device({
        address: deviceip
}).then(device => {
                return device.setPower(JSON.parse(thirdarg));
})}

// Status
if ( secondarg === "status" ) {
        miio.device({
        address: deviceip
}).then(device => {
                stats = device.getProperties([ 'power', 'mode', 'aqi', 'temperature', 'humidity' ])
                console.log(stats);
                process.exit();
})}

// Specify favorite manual fan speed (1 to 16) eg usage: fanspeed 16
if ( secondarg === "fanspeed" ) {
        setTimeout(exit, 7000);
        console.log('Setting manual fan speed to:', thirdarg);
        miio.device({
        address: deviceip
}).then(device => {
                return device.setFavoriteLevel(parseInt(thirdarg));
})}

// Set fan mode option, specify: idle, auto, silent or favorite which needs to be set for manual speed control
if ( secondarg === "fanmode" ) {
        setTimeout(exit, 7000);
        console.log('Telling device to use', thirdarg, 'fan speed mode');
        miio.device({
        address: deviceip
}).then(device => {
                return device.call('set_mode', [ thirdarg ])
})}

// Control the device led (specify as bright, dim or off)
if ( secondarg === "led" ) {
        setTimeout(exit, 7000);
        console.log('Setting device led to:', thirdarg);
        miio.device({
        address: deviceip
}).then(device => {
                return device.ledBrightness(thirdarg);
})}

// Switch the device buzzer on or off (specify as true or false)
if ( secondarg === "buzzer" ) {
        setTimeout(exit, 7000);
        console.log('Setting device buzzer to:', thirdarg);
        miio.device({
        address: deviceip
}).then(device => {
                return device.setBuzzer(JSON.parse(thirdarg));
})}
Example usage of the node script (new example per line):
node airpurifier.js 192.168.0.240 power true
node airpurifier.js 192.168.0.240 power false
node airpurifier.js 192.168.0.240 status
node airpurifier.js 192.168.0.240 led off
node airpurifier.js 192.168.0.240 buzzer true
node airpurifier.js 192.168.0.240 fanmode auto
node airpurifier.js 192.168.0.240 fanmode favorite
node airpurifier.js 192.168.0.240 fanspeed 16
node airpurifier.js 192.168.0.240 listfanmodes

Below is a template DEVICE lua event script for sending commands to the Air Purifier from Domoticz

Code: Select all

commandArray = {}
if devicechanged['Air Purifier'] == 'On' then
    os.execute ('sudo screen -S airpurifiertemp -d -m node /root/xiaomi/airpurifier.js 192.168.0.240 power true')
end
return commandArray
8) For those who want to load the Temperature, Humidity and Aqi (pm2.5 estimate) into Domoticz sensors, below is a updatedomoticz.sh bash script:

Code: Select all

#!/bin/bash
while true; do

# Get the data
data=$(node airpurifier.js 192.168.0.240 status)
# Sort it
temperature=$(echo "$data" | grep "temperature" | sed -e s/[^0-9.]//g)
humidity=$(echo "$data" | grep "humidity" | sed -e s/[^0-9.%]//g)
aqi=$(echo "$data" | grep "aqi" | sed -e s/[^0-9.]//g)

# Load it into Domoticz
curl -s "http://USERNAME:[email protected]/json.htm?type=command&param=udevice&idx=607&nvalue=0&svalue=${temperature};${humidity};0"
curl -s "http://USERNAME:[email protected]/json.htm?type=command&param=udevice&idx=599&svalue=${aqi}"

sleep 60
done
Domoticz sensor types to be used are:
Temperature and Humidity: Temp+Hum
Aqi (pm2.5 estimate): custom sensor

startup.sh script:

Code: Select all

# Start airpurifiermonitor
/usr/bin/screen -S airpurifiermonitor -d -m /root/xiaomi/updatedomoticz.sh
I use an additional script called airpurifiercontrol.sh which runs a series of commands to power on / off the purifier with exactly the settings and fan speed I like to use, usage: ./airpurifiercontrol.sh 192.168.0.93 on 4

Code: Select all

#!/bin/bash
cd /root/xiaomi/airpurifier2

if [ “$2” == “on” ]; then
node airpurifier.js $1 buzzer false
node airpurifier.js $1 fanmode $3
        if [ "$4" != "" ]; then
                node airpurifier.js $1 fanspeed $4
        fi
node airpurifier.js $1 power true
node airpurifier.js $1 led off
fi

if [ “$2” == “off” ]; then
node airpurifier.js $1 power false
fi
My own Lua device control script for the "Kitty Air Purifier" on my devices tab is:

Code: Select all

commnadArray = {}

-- Kitty Air Purifier
if devicechanged['Kitty Air Purifier'] == 'Silent' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/xiaomi/airpurifier2/airpurifiercontrol.sh 192.168.0.93 on silent')
end
if devicechanged['Kitty Air Purifier'] == 'Max' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/xiaomi/airpurifier2/airpurifiercontrol.sh 192.168.0.93 on favorite 16')
end
if devicechanged['Kitty Air Purifier'] == 'Medium' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/xiaomi/airpurifier2/airpurifiercontrol.sh 192.168.0.93 on favorite 8')
end
if devicechanged['Kitty Air Purifier'] == 'Low' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/xiaomi/airpurifier2/airpurifiercontrol.sh 192.168.0.93 on favorite 4')
end
if devicechanged['Kitty Air Purifier'] == 'Auto' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/xiaomi/airpurifier2/airpurifiercontrol.sh 192.168.0.93 on auto')
end
if devicechanged['Kitty Air Purifier'] == 'Off' then
    os.execute ('sudo screen -S airpurifieroff -d -m bash /root/xiaomi/airpurifier2/airpurifiercontrol.sh 192.168.0.93 off')
end

return commandArray
Screen Shot 2017-05-09 at 11.18.00 am.png
Screen Shot 2017-05-09 at 11.18.00 am.png (138.82 KiB) Viewed 18957 times
Screen Shot 2017-05-10 at 9.10.07 pm.png
Screen Shot 2017-05-10 at 9.10.07 pm.png (91.37 KiB) Viewed 18926 times
Screen Shot 2017-05-10 at 9.12.09 pm.png
Screen Shot 2017-05-10 at 9.12.09 pm.png (344.91 KiB) Viewed 18926 times

Re: Xiaomi Air Purifier 2

Posted: Friday 20 January 2017 22:31
by corbin
if you follow the udp stream in wireshark, and show as ASCII or UTF-8, is it still the hexidecimal response?

Re: Xiaomi Air Purifier 2

Posted: Saturday 21 January 2017 1:32
by ben53252642
Unfortunately yes, I've spent about 10 hours trying to find some meaning in the packets.

Re: Xiaomi Air Purifier 2

Posted: Saturday 21 January 2017 1:38
by trixwood
4th byte (could be) length of message... since it's equivalent with it's length...

This keeps constant...
213100xx0000000002d1eb8b0000

note that the byte after this is alway rising (8/16?? bit counter/minute?...)

You can disassemble the google app... look what they do with the messages... that what they did with the ikettle ;-)

Good luck... if you ever succeed probably buy one :-)

Re: Xiaomi Air Purifier 2

Posted: Friday 24 February 2017 8:17
by akage
Hi, Im interested in this too. Here is a interesting writeup by takku from proto.today:http://proto.today/?p=201

Re: Xiaomi Air Purifier 2

Posted: Sunday 12 March 2017 15:24
by holger
Any news? I'm very much interested as well.

Re: Xiaomi Air Purifier 2

Posted: Monday 08 May 2017 22:25
by ben53252642
Finally we have support for the Xiaomi Air Purifier in Domoticz for Linux. 8-)

Re: Xiaomi Air Purifier 2 Domoticz Setup Instructions

Posted: Monday 08 May 2017 22:41
by kofec
What do you mean by that ? I don't see any commit about this. Can you point us to this commit.

Re: Xiaomi Air Purifier 2 Domoticz Setup Instructions

Posted: Monday 08 May 2017 22:44
by ben53252642
kofec wrote:What do you mean by that ? I don't see any commit about this. Can you point us to this commit.
Read the top post, integration is done via scripts.

Re: Xiaomi Air Purifier 2 Domoticz Setup Instructions

Posted: Monday 08 May 2017 22:47
by kofec
Now I see - great job - thanks a lot

Re: Xiaomi Air Purifier 2 Domoticz Setup Instructions

Posted: Tuesday 09 May 2017 0:48
by ben53252642
It would be even better if someone could make a Domoticz plugin.

Re: Xiaomi Air Purifier 2

Posted: Friday 19 May 2017 5:54
by DT27

Code: Select all

commnadArray = {}
should be

Code: Select all

commandArray = {}

Re: Xiaomi Air Purifier 2

Posted: Friday 19 May 2017 7:45
by ben53252642
DT27 wrote:

Code: Select all

commnadArray = {}
should be

Code: Select all

commandArray = {}
Fixed it, thanks.

Re: Xiaomi Air Purifier 2

Posted: Saturday 20 May 2017 18:31
by juzx
Is it me or does turning it on seem slow and Domoticz hangs for a few seconds? Same with the off switch?

Re: Xiaomi Air Purifier 2

Posted: Saturday 20 May 2017 18:37
by ben53252642
Yes the commands have about a 3 - 7 second delay.

That's why I offload them to a screen session, if executing the command from Linux bash terminal:

sudo screen -S airpurifiertemp -d -m node /root/xiaomi/airpurifier.js 192.168.0.240 power true

If using a Lua script:

Code: Select all

commandArray = {}
if devicechanged['Air Purifier'] == 'On' then
    os.execute ('sudo screen -S airpurifiertemp -d -m node /root/xiaomi/airpurifier.js 192.168.0.240 power true')
end
return commandArray
Using screen will stop the "hang" you mention in Domoticz, which is really just Domoticz having to wait for the node command to complete.

Re: Xiaomi Air Purifier 2

Posted: Sunday 21 May 2017 11:49
by n01knows
Hello.

Thx for solution :)

Maybe any of U hit simmilar issue as I and found resolution?


Code: Select all

miio --discover --sync
/usr/local/lib/node_modules/miio/cli/index.js:10
const { Browser, Devices } = require('../lib/discovery');
      ^

SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:374:25)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:442:10)
    at startup (node.js:136:18)
    at node.js:966:3

Code: Select all

npm rebuild
[email protected] /home/tom/node_modules/ansi-regex
[email protected] /home/tom/node_modules/ansi-styles
[email protected] /home/tom/node_modules/appdirectory
[email protected] /home/tom/node_modules/chalk
[email protected] /home/tom/node_modules/escape-string-regexp
[email protected] /home/tom/node_modules/has-ansi
[email protected] /home/tom/node_modules/strip-ansi
[email protected] /home/tom/node_modules/supports-color
[email protected] /home/tom/node_modules/clone
[email protected] /home/tom/node_modules/debug
[email protected] /home/tom/node_modules/ms
[email protected] /home/tom/node_modules/deep-extend
[b][email protected] /home/tom/node_modules/discovery[/b]
[email protected] /home/tom/node_modules/discovery/node_modules/debug
[email protected] /home/tom/node_modules/ip
[email protected] /home/tom/node_modules/rc
[email protected] /home/tom/node_modules/ini
[email protected] /home/tom/node_modules/rc/node_modules/minimist
[email protected] /home/tom/node_modules/sigmund
[email protected] /home/tom/node_modules/miio
[email protected] /home/tom/node_modules/minimist
[email protected] /home/tom/node_modules/mkdirp
[email protected] /home/tom/node_modules/mkdirp/node_modules/minimist
[email protected] /home/tom/node_modules/optimist
[email protected] /home/tom/node_modules/optimist/node_modules/minimist
[email protected] /home/tom/node_modules/wordwrap



#######

I've followed with nodejs version 6 installation and now I can run commands without issues.

https://askubuntu.com/questions/786272/ ... node-4-2-6

Re: Xiaomi Air Purifier 2

Posted: Sunday 21 May 2017 22:15
by juzx
ben53252642 wrote:Yes the commands have about a 3 - 7 second delay.

That's why I offload them to a screen session, if executing the command from Linux bash terminal:

sudo screen -S airpurifiertemp -d -m node /root/xiaomi/airpurifier.js 192.168.0.240 power true

If using a Lua script:

Code: Select all

commandArray = {}
if devicechanged['Air Purifier'] == 'On' then
    os.execute ('sudo screen -S airpurifiertemp -d -m node /root/xiaomi/airpurifier.js 192.168.0.240 power true')
end
return commandArray
Using screen will stop the "hang" you mention in Domoticz, which is really just Domoticz having to wait for the node command to complete.
Thank you for the answer. I actually removed the screen part because I was unsure what it did, but now I know.

Actually I use your script not for the airpurifier but for the Xiaomi WiFi wallplugs, it also works the same way.

Is there a way to remove the delay, because if I control the WiFi plugs with homekit they go on and off instantely when I push the button?

Re: Xiaomi Air Purifier 2

Posted: Thursday 01 June 2017 23:19
by ben53252642
juzx wrote:Is there a way to remove the delay, because if I control the WiFi plugs with homekit they go on and off instantely when I push the button?
Try adapting the code from humidifier.js here:

viewtopic.php?f=56&t=17498

Re: Xiaomi Air Purifier 2

Posted: Friday 02 June 2017 18:49
by juzx
ben53252642 wrote:
juzx wrote:Is there a way to remove the delay, because if I control the WiFi plugs with homekit they go on and off instantely when I push the button?
Try adapting the code from humidifier.js here:

viewtopic.php?f=56&t=17498
Having the same delay with that code :'(

Re: Xiaomi Air Purifier 2

Posted: Sunday 11 June 2017 13:06
by Julz
Hi all,
I'm having trouble getting the bash script to feed updates via JSON to my Raspberry Pi. I can trigger the bash script manually and it seems to update the temperature sensor and PM2.5 sensor values the first time but then the temperature sensor updates to 0.0C and the PM2.5 sensor doesn't update again. I'm pretty sure I've set up the script to trigger at boot via a call to my 'startup.sh' script in my /etc/rc.local but after bootup is complete, doing a 'screen -list' doesn't show any sessions running unlike when I manually execute my startup.sh. Any suggestions?

TIA!