Xiaomi Air Purifier 2S

All kinds of 'OS' scripts

Moderator: leecollings

Post Reply
ben53252642
Posts: 543
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Xiaomi Air Purifier 2S

Post by ben53252642 »

The Xiaomi Air Purifier 2S now works with Domoticz for Linux (Ubuntu, Debian Raspberry Pi). Below is the setup, requires moderate Linux knowledge. Separate thread needed due to changes in the API vs the Air Purifier 2, namely:

* Change in LED / Screen control
* Change in favorite level API and speed range

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 */

// Location of miio node lib
const miio = require('/root/node_modules/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.led(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));
})}

// List available fan speed modes
if ( secondarg === "listfanmodes" ) {
        miio.device({
        address: deviceip
}).then(device => {
                fanmodesare = device.modes
                console.log(fanmodesare);
                process.exit();
})}
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 14

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/airpurifier2s

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 "Office Air Purifier" on my devices tab is:

Code: Select all

commnadArray = {}

-- Office Air Purifier
if devicechanged['Office Air Purifier'] == 'Silent' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/scripts/xiaomi/airpurifier2s/airpurifiercontrol.sh 192.168.0.92 on silent &')
end
if devicechanged['Office Air Purifier'] == 'Max' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/scripts/xiaomi/airpurifier2s/airpurifiercontrol.sh 192.168.0.92 on favorite_level 14 &')
end
if devicechanged['Office Air Purifier'] == 'Medium' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/scripts/xiaomi/airpurifier2s/airpurifiercontrol.sh 192.168.0.92 on favorite_level 7 &')
end
if devicechanged['Office Air Purifier'] == 'Low' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/scripts/xiaomi/airpurifier2s/airpurifiercontrol.sh 192.168.0.92 on favorite_level 3 &')
end
if devicechanged['Office Air Purifier'] == 'Auto' then
    os.execute ('sudo screen -S airpurifieron -d -m bash /root/scripts/xiaomi/airpurifier2s/airpurifiercontrol.sh 192.168.0.92 on auto &')
end
if devicechanged['Office Air Purifier'] == 'Off' then
    os.execute ('sudo screen -S airpurifieroff -d -m bash /root/scripts/xiaomi/airpurifier2s/airpurifiercontrol.sh 192.168.0.92 off &')
end

return commandArray
Unless otherwise stated, all my code is released under GPL 3 license: https://www.gnu.org/licenses/gpl-3.0.en.html
bgolab
Posts: 1
Joined: Thursday 24 January 2019 16:36
Target OS: -
Domoticz version:
Contact:

Re: Xiaomi Air Purifier 2S

Post by bgolab »

Hi,
Thank you for this info.

If you could share the info how to get the token from the 2S device. It seems to work differently than the older model.

Bogdan
gajotnt
Posts: 70
Joined: Monday 06 February 2017 12:48
Target OS: Raspberry Pi / ODroid
Domoticz version: V4.9700
Location: Azores
Contact:

Re: Xiaomi Air Purifier 2S

Post by gajotnt »

ben53252642
Posts: 543
Joined: Saturday 02 July 2016 5:17
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Xiaomi Air Purifier 2S

Post by ben53252642 »

I didn't need to extract the token from my devices, the miio software was able to detect it automatically.

Unless a firmware update has changed things, it should still be the same.
Unless otherwise stated, all my code is released under GPL 3 license: https://www.gnu.org/licenses/gpl-3.0.en.html
Sebastian
Posts: 2
Joined: Wednesday 27 November 2019 14:33
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Xiaomi Air Purifier 2S

Post by Sebastian »

Hi

A little enhancement

Below script will also synchronize status between domoticz and Xiaomi air purifier

Requirments:
- script need 5 parameters as described.
Example entry in crontab ( runs every 15 minutes)

*/15 * * * * sh /home/pi/domoticz/scripts/xiaomi_air_purifier.sh 192.168.1.181 192.168.1.100:8088 137 145 141

- Multiswitch in domoticz has only three levels 0 10 20 (0=Off 10=Auto 20=Silent)
Lua
script as in below has been created for each airpurifier

Code: Select all

/home/pi/domoticz/scripts
pi@raspberrypi:~/domoticz/scripts $ cat xiaomi_air_purifier.sh
#!/bin/bash


#Script need fallowing arguments
# 1.Xiaomi Gateway IP address
# 2.Domoticz IP address with port(http)
# 3.Domoticz IDX value for humiditiy and temprature dummy temp&hum sensori
# 4. Domoticz IDX value for aqi dummy custom sensor
# 5.Domoticz IDX value for multiswitch(status of airpurifier)
# Get the data
domoticz_addres=$2
data=$(node /home/pi/domoticz/scripts/airpurifier.js $1 status)
# Parse data

power=$(echo "$data" | grep -oP 'power: \K\w+')
mode=$(echo "$data" | tr -d \' | grep -oP 'mode: \K\w+')
temperature=$(echo "$data" |  grep -oP 'temperature: \K[\.\w]+')
humidity=$(echo "$data" |  grep -oP 'humidity: \K[\.\w]+')
aqi=$(echo "$data" |  grep -oP 'aqi: \K[\.\w]+')

echo temp  $temperature
echo hum $humidity
echo aqi $aqi
echo power $power
echo mode $mode
if [ $power = true -a $mode = auto ] ; then level_value=10 
elif [ $power = true -a $mode = silent ]; then level_value=20
elif [ $power = true -a $mode != silent -a $mode != auto ]; then level_value=20 
else level_value=0
fi
echo Set level $level_value 
# Load it into Domoticz
curl -s "http://$2/json.htm?type=command&param=udevice&idx=$3&nvalue=0&svalue=${temperature};${humidity};0"
curl -s "http://$2/json.htm?type=command&param=udevice&idx=$4&svalue=${aqi}"
curl -s "http://$2/json.htm?type=command&param=switchlight&idx=$5&switchcmd=Set%20Level&level=$level_value"

Lua script

Code: Select all

--
-- Domoticz passes information to scripts through a number of global tables
--
-- device changed contains state and svalues for the device that changed.
--   devicechanged['yourdevicename'] = state 
--   devicechanged['svalues'] = svalues string 
--
-- otherdevices, otherdevices_lastupdate and otherdevices_svalues are arrays for all devices: 
--   otherdevices['yourotherdevicename'] = "On"
--   otherdevices_lastupdate['yourotherdevicename'] = "2015-12-27 14:26:40"
--   otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- uservariables and uservariables_lastupdate are arrays for all user variables: 
--   uservariables['yourvariablename'] = 'Test Value'
--   uservariables_lastupdate['yourvariablename'] = '2015-12-27 11:19:22'
--
-- other useful details are contained in the timeofday table
--   timeofday['Nighttime'] = true or false
--   timeofday['SunriseInMinutes'] = number
--   timeofday['Daytime'] = true or false
--   timeofday['SunsetInMinutes'] = number
--   globalvariables['Security'] = 'Disarmed', 'Armed Home' or 'Armed Away'
--
-- To see examples of commands see: http://www.domoticz.com/wiki/LUA_commands#General
-- To get a list of available values see: http://www.domoticz.com/wiki/LUA_commands#Function_to_dump_all_variables_supplied_to_the_script
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive. 
--
commandArray = {}

if devicechanged['OczyszczaczSonia'] == 'Auto' then
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 power true')
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 fanmode auto')
end
if devicechanged['OczyszczaczSonia'] == 'Off' then
    os.execute ('sudo screen -S airpurifieroff -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 power false')
end
if devicechanged['OczyszczaczSonia'] == 'Low' then
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 fanmode favorite')
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 fanspeed 3')
end
if devicechanged['OczyszczaczSonia'] == 'Max' then
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 fanmode favorite')
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 fanspeed 16')
end
if devicechanged['OczyszczaczSonia'] == 'Silent' then
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 power true')
    os.execute ('sudo screen -S airpurifieron -d -m node /home/pi/domoticz/scripts/airpurifier.js 192.168.1.181 fanmode silent')
end


return commandArray
Kruu
Posts: 49
Joined: Tuesday 17 January 2017 20:27
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: Xiaomi Air Purifier 2S

Post by Kruu »

Hi,

will this work with Mi Air Purifier 3C?

thx
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest